binutils-gdb/gold/layout.cc

3691 lines
111 KiB
C++
Raw Normal View History

// layout.cc -- lay out output file sections for gold
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 10:25:33 +08:00
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
#include "gold.h"
#include <cerrno>
#include <cstring>
2006-09-27 05:00:34 +08:00
#include <algorithm>
#include <iostream>
#include <utility>
#include <fcntl.h>
#include <unistd.h>
#include "libiberty.h"
#include "md5.h"
#include "sha1.h"
2007-09-21 15:20:01 +08:00
#include "parameters.h"
#include "options.h"
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
#include "mapfile.h"
2008-02-04 13:43:05 +08:00
#include "script.h"
#include "script-sections.h"
#include "output.h"
#include "symtab.h"
#include "dynobj.h"
#include "ehframe.h"
2007-12-01 14:34:12 +08:00
#include "compressed_output.h"
#include "reduced_debug_output.h"
2008-02-06 16:13:50 +08:00
#include "reloc.h"
#include "descriptors.h"
#include "plugin.h"
#include "incremental.h"
#include "layout.h"
namespace gold
{
// Layout_task_runner methods.
// Lay out the sections. This is called after all the input objects
// have been read.
void
Layout_task_runner::run(Workqueue* workqueue, const Task* task)
{
off_t file_size = this->layout_->finalize(this->input_objects_,
this->symtab_,
this->target_,
task);
// Now we know the final size of the output file and we know where
// each piece of information goes.
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
if (this->mapfile_ != NULL)
{
this->mapfile_->print_discarded_sections(this->input_objects_);
this->layout_->print_to_mapfile(this->mapfile_);
}
Output_file* of = new Output_file(parameters->options().output_file_name());
if (this->options_.oformat_enum() != General_options::OBJECT_FORMAT_ELF)
2008-02-07 15:33:46 +08:00
of->set_is_temporary();
of->open(file_size);
// Queue up the final set of tasks.
gold::queue_final_tasks(this->options_, this->input_objects_,
this->symtab_, this->layout_, workqueue, of);
}
// Layout methods.
Layout::Layout(int number_of_input_files, Script_options* script_options)
: number_of_input_files_(number_of_input_files),
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
script_options_(script_options),
namepool_(),
sympool_(),
dynpool_(),
signatures_(),
section_name_map_(),
segment_list_(),
section_list_(),
unattached_section_list_(),
special_output_list_(),
section_headers_(NULL),
tls_segment_(NULL),
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
relro_segment_(NULL),
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
symtab_section_(NULL),
symtab_xindex_(NULL),
dynsym_section_(NULL),
dynsym_xindex_(NULL),
dynamic_section_(NULL),
dynamic_data_(NULL),
eh_frame_section_(NULL),
eh_frame_data_(NULL),
added_eh_frame_data_(false),
eh_frame_hdr_section_(NULL),
build_id_note_(NULL),
debug_abbrev_(NULL),
debug_info_(NULL),
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
group_signatures_(),
output_file_size_(-1),
sections_are_attached_(false),
2007-10-23 13:05:48 +08:00
input_requires_executable_stack_(false),
input_with_gnu_stack_note_(false),
input_without_gnu_stack_note_(false),
has_static_tls_(false),
any_postprocessing_sections_(false),
resized_signatures_(false),
have_stabstr_section_(false),
incremental_inputs_(NULL)
2006-09-27 05:00:34 +08:00
{
// Make space for more than enough segments for a typical file.
// This is just for efficiency--it's OK if we wind up needing more.
this->segment_list_.reserve(12);
// We expect two unattached Output_data objects: the file header and
// the segment headers.
this->special_output_list_.reserve(2);
// Initialize structure needed for an incremental build.
if (parameters->options().incremental())
this->incremental_inputs_ = new Incremental_inputs;
// The section name pool is worth optimizing in all cases, because
// it is small, but there are often overlaps due to .rel sections.
this->namepool_.set_optimize();
2006-09-27 05:00:34 +08:00
}
// Hash a key we use to look up an output section mapping.
size_t
Layout::Hash_key::operator()(const Layout::Key& k) const
{
return k.first + k.second.first + k.second.second;
}
// Returns whether the given section is in the list of
// debug-sections-used-by-some-version-of-gdb. Currently,
// we've checked versions of gdb up to and including 6.7.1.
static const char* gdb_sections[] =
{ ".debug_abbrev",
// ".debug_aranges", // not used by gdb as of 6.7.1
".debug_frame",
".debug_info",
".debug_line",
".debug_loc",
".debug_macinfo",
// ".debug_pubnames", // not used by gdb as of 6.7.1
".debug_ranges",
".debug_str",
};
static const char* lines_only_debug_sections[] =
{ ".debug_abbrev",
// ".debug_aranges", // not used by gdb as of 6.7.1
// ".debug_frame",
".debug_info",
".debug_line",
// ".debug_loc",
// ".debug_macinfo",
// ".debug_pubnames", // not used by gdb as of 6.7.1
// ".debug_ranges",
".debug_str",
};
static inline bool
is_gdb_debug_section(const char* str)
{
// We can do this faster: binary search or a hashtable. But why bother?
for (size_t i = 0; i < sizeof(gdb_sections)/sizeof(*gdb_sections); ++i)
if (strcmp(str, gdb_sections[i]) == 0)
return true;
return false;
}
static inline bool
is_lines_only_debug_section(const char* str)
{
// We can do this faster: binary search or a hashtable. But why bother?
for (size_t i = 0;
i < sizeof(lines_only_debug_sections)/sizeof(*lines_only_debug_sections);
++i)
if (strcmp(str, lines_only_debug_sections[i]) == 0)
return true;
return false;
}
// Whether to include this section in the link.
template<int size, bool big_endian>
bool
Layout::include_section(Sized_relobj<size, big_endian>*, const char* name,
const elfcpp::Shdr<size, big_endian>& shdr)
{
if (shdr.get_sh_flags() & elfcpp::SHF_EXCLUDE)
return false;
switch (shdr.get_sh_type())
{
case elfcpp::SHT_NULL:
case elfcpp::SHT_SYMTAB:
case elfcpp::SHT_DYNSYM:
case elfcpp::SHT_HASH:
case elfcpp::SHT_DYNAMIC:
case elfcpp::SHT_SYMTAB_SHNDX:
return false;
case elfcpp::SHT_STRTAB:
// Discard the sections which have special meanings in the ELF
// ABI. Keep others (e.g., .stabstr). We could also do this by
// checking the sh_link fields of the appropriate sections.
return (strcmp(name, ".dynstr") != 0
&& strcmp(name, ".strtab") != 0
&& strcmp(name, ".shstrtab") != 0);
case elfcpp::SHT_RELA:
case elfcpp::SHT_REL:
case elfcpp::SHT_GROUP:
2008-02-28 06:38:18 +08:00
// If we are emitting relocations these should be handled
// elsewhere.
gold_assert(!parameters->options().relocatable()
&& !parameters->options().emit_relocs());
2008-02-06 16:13:50 +08:00
return false;
case elfcpp::SHT_PROGBITS:
if (parameters->options().strip_debug()
&& (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
{
* layout.cc (Layout::include_section): Refactored check for debug info section. (Layout::add_comdat): Add new parameters. Change type of signature parameter. Add object and shndx to signatures table. (Layout::find_kept_object): New function. * layout.h: Include <cstring>. (Layout::is_debug_info_section): New function. (Layout::add_comdat): Add new parameters. (Layout::find_kept_object): New function. (Layout::Kept_section): New struct. (Layout::Signatures): Change type of map range. * object.cc (Relobj::output_section_address): New function. (Sized_relobj::include_section_group): Add new parameters. Change calls to Layout::add_comdat. Change to build table of kept comdat groups and table mapping discarded sections to kept sections. (Sized_relobj::include_linkonce_section): Likewise. Add new parameter. (Sized_relobj::do_layout): Change calls to include_section_group and include_linkonce_section. (Sized_relobj::do_finalize_local_symbols): Do not set local symbol value to zero when section is discarded. (Sized_relobj::map_to_kept_section): New function. * object.h (Relobj::output_section_address): New function. (Relobj::Comdat_group): New type. (Relobj::find_comdat_group): New function. (Relobj::Comdat_group_table): New type. (Relobj::Kept_comdat_section): New type. (Relobj::Kept_comdat_section_table): New type. (Relobj::add_comdat_group): New function. (Relobj::set_kept_comdat_section): New function. (Relobj::get_kept_comdat_section): New function. (Relobj::comdat_groups_): New field. (Relobj::kept_comdat_sections_): New field. (Symbol_value::input_value): Update comment. (Sized_relobj::map_to_kept_section) New function. (Sized_relobj::include_linkonce_section): Add new parameter. * target-reloc.h (Comdat_behavior): New type. (get_comdat_behavior): New function. (relocate_section): Add code to map a discarded section to the corresponding kept section when applying a relocation.
2008-05-01 09:23:21 +08:00
if (is_debug_info_section(name))
return false;
}
if (parameters->options().strip_debug_non_line()
&& (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
{
// Debugging sections can only be recognized by name.
if (is_prefix_of(".debug", name)
&& !is_lines_only_debug_section(name))
return false;
}
if (parameters->options().strip_debug_gdb()
&& (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
{
// Debugging sections can only be recognized by name.
if (is_prefix_of(".debug", name)
&& !is_gdb_debug_section(name))
return false;
}
if (parameters->options().strip_lto_sections()
&& !parameters->options().relocatable()
&& (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
{
// Ignore LTO sections containing intermediate code.
if (is_prefix_of(".gnu.lto_", name))
return false;
}
return true;
default:
return true;
}
}
// Return an output section named NAME, or NULL if there is none.
Output_section*
Layout::find_output_section(const char* name) const
{
2008-02-04 13:43:05 +08:00
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
2008-02-04 13:43:05 +08:00
if (strcmp((*p)->name(), name) == 0)
return *p;
return NULL;
}
// Return an output segment of type TYPE, with segment flags SET set
// and segment flags CLEAR clear. Return NULL if there is none.
Output_segment*
Layout::find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set,
elfcpp::Elf_Word clear) const
{
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
if (static_cast<elfcpp::PT>((*p)->type()) == type
&& ((*p)->flags() & set) == set
&& ((*p)->flags() & clear) == 0)
return *p;
return NULL;
}
// Return the output section to use for section NAME with type TYPE
2008-02-04 13:43:05 +08:00
// and section flags FLAGS. NAME must be canonicalized in the string
// pool, and NAME_KEY is the key.
Output_section*
Layout::get_output_section(const char* name, Stringpool::Key name_key,
elfcpp::Elf_Word type, elfcpp::Elf_Xword flags)
{
elfcpp::Elf_Xword lookup_flags = flags;
// Ignoring SHF_WRITE and SHF_EXECINSTR here means that we combine
// read-write with read-only sections. Some other ELF linkers do
// not do this. FIXME: Perhaps there should be an option
// controlling this.
lookup_flags &= ~(elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR);
const Key key(name_key, std::make_pair(type, lookup_flags));
const std::pair<Key, Output_section*> v(key, NULL);
std::pair<Section_name_map::iterator, bool> ins(
this->section_name_map_.insert(v));
if (!ins.second)
return ins.first->second;
else
{
// This is the first time we've seen this name/type/flags
// combination. For compatibility with the GNU linker, we
// combine sections with contents and zero flags with sections
// with non-zero flags. This is a workaround for cases where
// assembler code forgets to set section flags. FIXME: Perhaps
// there should be an option to control this.
Output_section* os = NULL;
if (type == elfcpp::SHT_PROGBITS)
{
if (flags == 0)
{
Output_section* same_name = this->find_output_section(name);
if (same_name != NULL
&& same_name->type() == elfcpp::SHT_PROGBITS
&& (same_name->flags() & elfcpp::SHF_TLS) == 0)
os = same_name;
}
else if ((flags & elfcpp::SHF_TLS) == 0)
{
elfcpp::Elf_Xword zero_flags = 0;
const Key zero_key(name_key, std::make_pair(type, zero_flags));
Section_name_map::iterator p =
this->section_name_map_.find(zero_key);
if (p != this->section_name_map_.end())
os = p->second;
}
}
if (os == NULL)
os = this->make_output_section(name, type, flags);
ins.first->second = os;
return os;
}
}
2008-02-04 13:43:05 +08:00
// Pick the output section to use for section NAME, in input file
// 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. This will return NULL if the input section should be
// discarded.
2008-02-04 13:43:05 +08:00
Output_section*
Layout::choose_output_section(const Relobj* relobj, const char* name,
elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
bool is_input_section)
2008-02-04 13:43:05 +08:00
{
// We should not see any input sections after we have attached
// sections to segments.
gold_assert(!is_input_section || !this->sections_are_attached_);
// Some flags in the input section should not be automatically
// copied to the output section.
2008-02-04 13:43:05 +08:00
flags &= ~ (elfcpp::SHF_INFO_LINK
| elfcpp::SHF_LINK_ORDER
| elfcpp::SHF_GROUP
| elfcpp::SHF_MERGE
| elfcpp::SHF_STRINGS);
if (this->script_options_->saw_sections_clause())
{
// We are using a SECTIONS clause, so the output section is
// chosen based only on the name.
Script_sections* ss = this->script_options_->script_sections();
const char* file_name = relobj == NULL ? NULL : relobj->name().c_str();
Output_section** output_section_slot;
name = ss->output_section_name(file_name, name, &output_section_slot);
if (name == NULL)
{
// The SECTIONS clause says to discard this input section.
return NULL;
}
// If this is an orphan section--one not mentioned in the linker
// script--then OUTPUT_SECTION_SLOT will be NULL, and we do the
// default processing below.
if (output_section_slot != NULL)
{
if (*output_section_slot != NULL)
{
(*output_section_slot)->update_flags_for_input_section(flags);
return *output_section_slot;
}
2008-02-04 13:43:05 +08:00
// We don't put sections found in the linker script into
// SECTION_NAME_MAP_. That keeps us from getting confused
// if an orphan section is mapped to a section with the same
// name as one in the linker script.
name = this->namepool_.add(name, false, NULL);
Output_section* os = this->make_output_section(name, type, flags);
os->set_found_in_sections_clause();
*output_section_slot = os;
return os;
}
}
// FIXME: Handle SHF_OS_NONCONFORMING somewhere.
// Turn NAME from the name of the input section into the name of the
// output section.
size_t len = strlen(name);
if (is_input_section
&& !this->script_options_->saw_sections_clause()
&& !parameters->options().relocatable())
2008-02-04 13:43:05 +08:00
name = Layout::output_section_name(name, &len);
Stringpool::Key name_key;
name = this->namepool_.add_with_length(name, len, true, &name_key);
// 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);
}
// Return the output section to use for input section SHNDX, with name
// NAME, with header HEADER, from object OBJECT. RELOC_SHNDX is the
// index of a relocation section which applies to this section, or 0
// if none, or -1U if more than one. RELOC_TYPE is the type of the
// relocation section if there is one. Set *OFF to the offset of this
// input section without the output section. Return NULL if the
// section should be discarded. Set *OFF to -1 if the section
// contents should not be written directly to the output file, but
// will instead receive special handling.
template<int size, bool big_endian>
Output_section*
Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
unsigned int reloc_shndx, unsigned int, off_t* off)
{
Handle output sections with more than 0x7fffffff bytes. * object.h (class Relobj): Change map_to_output_ to output_sections_, and just keep a section pointer. Change all uses. Move comdat group support to Sized_relobj. (Relobj::is_section_specially_mapped): Remove. (Relobj::output_section): Remove poff parameter. Change all callers. (Relobj::output_section_offset): New function. (Relobj::set_section_offset): Rewrite. (Relobj::map_to_output): Remove. (Relobj::output_sections): New function. (Relobj::do_output_section_offset): New pure virtual function. (Relobj::do_set_section_offset): Likewise. (class Sized_relobj): Add section_offsets_ field. Add comdat group support from Relobj. Update declarations. (Sized_relobj::get_output_section_offset): New function. (Sized_relobj::do_output_section_offset): New function. (Sized_relobj::do_set_section_offset): New function. * object.cc (Relobj::output_section_address): Remove. (Sized_relobj::Sized_relobj): Initialize new fields. (Sized_relobj::include_section_group): Cast find_kept_object to Sized_relobj. (Sized_relobj::include_linkonce_section): Likewise. (Sized_relobj::do_layout): Use separate arrays for output section and output offset. (Sized_relobj::do_count_local_symbols): Change map_to_output to output_sections. (Sized_relobj::do_finalize_local_symbols): Change map_to_output to output_sections and section_offsets. (Sized_relobj::write_local_symbols): Likewise. (map_to_kept_section): Compute output address directly. * reloc.cc (Sized_relobj::do_read_relocs): Change map_to_output to output_sections and section_offsets. (Sized_relobj::write_sections): Likewise. (Sized_relobj::relocate_sections): Likewise. * symtab.cc (sized_finalize_symbol): Use output_section_offset. * output.h (class Output_reloc): Update declarations. Change u2_.relobj to Sized_relobj*. (class Output_data_reloc): Change add functions to use Sized_relobj*. * output.cc (Output_reloc::Output_reloc): Change relobj to Sized_relobj*. (Output_reloc::local_section_offset): Change return type to Elf_Addr. Use get_output_section_offset. (Output_reloc::get_address): Likewise. (Output_section::is_input_address_mapped): Don't call is_section_specially_mapped. (Output_section::output_offset): Likewise. (Output_section::output_address): Likewise. (Output_section::starting_output_address): Likewise. * copy-relocs.cc (Copy_relocs::copy_reloc): Change object parameter to Sized_relobj*. (Copy_relocs::need_copy_reloc): Likewise. (Copy_relocs::save): Likewise. * copy-relocs.h (class Copy_relocs): Update declarations. (class Copy_relocs::Copy_reloc_entry): Change constructor to use Sized_relobj*. Change relobj_ field to Sized_relobj*. * target-reloc.h (relocate_for_relocatable): Change offset_in_output_section type to Elf_Addr. Change code that uses it as well. * layout.cc (Layout::layout): Always set *off. * mapfile.cc (Mapfile::print_input_section): Use output_section_offset. * i386.cc (Target_i386::copy_reloc): Change object parameter to Sized_relobj*. * powerpc.cc (Target_powerpc::copy_reloc): Likewise. * sparc.cc (Target_sparc::copy_reloc): Likewise. * x86_64.cc (Target_x86_64::copy_reloc): Likewise.
2008-07-11 07:01:20 +08:00
*off = 0;
if (!this->include_section(object, name, shdr))
return NULL;
2008-02-06 16:13:50 +08:00
Output_section* os;
// In a relocatable link a grouped section must not be combined with
// any other sections.
if (parameters->options().relocatable()
2008-02-06 16:13:50 +08:00
&& (shdr.get_sh_flags() & elfcpp::SHF_GROUP) != 0)
{
name = this->namepool_.add(name, true, NULL);
os = this->make_output_section(name, shdr.get_sh_type(),
shdr.get_sh_flags());
}
else
{
os = this->choose_output_section(object, name, shdr.get_sh_type(),
shdr.get_sh_flags(), true);
if (os == NULL)
return NULL;
}
* layout.cc (Layout::layout): If we see an input section with a name that needs sorting, set the must_sort flag for the output section. (Layout::make_output_section): If the name of the output section indicates that it might require sorting, set the may_sort flag. * output.h (Output_section::may_sort_attached_input_sections): New function. (Output_section::set_may_sort_attached_input_sections): New function. (Output_section::must_sort_attached_input_sections): New function. (Output_section::set_must_sort_attached_input_sections): New function. (class Output_section): Declare Input_section_sort_entry. Define Input_section_sort_compare. Declare sort_attached_input_sections. Add new fields: may_sort_attached_input_sections_, must_sort_attached_input_sections_, attached_input_sections_are_sorted_. * output.cc (Output_section::Output_section): Initialize new fields. (Output_section::add_input_section): Add an entry to input_sections_ if may_sort or must_sort are true. (Output_section::set_final_data_size): Call sort_attached_input_sections if necessary. (Output_section::Input_section_sort_entry): Define new class. (Output_section::Input_section_sort_compare::operator()): New function. (Output_section::sort_attached_input_sections): New function. * configure.ac: Check whether the compiler supports constructor priorities. Define a CONSTRUCTOR_PRIORITY automake conditional. * testsuite/initpri1.c: New file. * testsuite/Makefile.am (check_PROGRAMS): Add initpri1 if CONSTRUCTOR_PRIORITY. (initpri1_SOURCES, initpri1_DEPENDENCIES): New variables. (initpri1_LDFLAGS): New variable. * configure, Makefile.in, testsuite/Makefile.in: Rebuild.
2008-03-29 06:42:34 +08:00
// By default the GNU linker sorts input sections whose names match
// .ctor.*, .dtor.*, .init_array.*, or .fini_array.*. The sections
// are sorted by name. This is used to implement constructor
// priority ordering. We are compatible.
if (!this->script_options_->saw_sections_clause()
&& (is_prefix_of(".ctors.", name)
|| is_prefix_of(".dtors.", name)
|| is_prefix_of(".init_array.", name)
|| is_prefix_of(".fini_array.", name)))
os->set_must_sort_attached_input_sections();
// FIXME: Handle SHF_LINK_ORDER somewhere.
2008-02-04 13:43:05 +08:00
*off = os->add_input_section(object, shndx, name, shdr, reloc_shndx,
this->script_options_->saw_sections_clause());
return os;
}
2008-02-06 16:13:50 +08:00
// Handle a relocation section when doing a relocatable link.
template<int size, bool big_endian>
Output_section*
Layout::layout_reloc(Sized_relobj<size, big_endian>* object,
unsigned int,
const elfcpp::Shdr<size, big_endian>& shdr,
Output_section* data_section,
Relocatable_relocs* rr)
{
gold_assert(parameters->options().relocatable()
|| parameters->options().emit_relocs());
2008-02-06 16:13:50 +08:00
int sh_type = shdr.get_sh_type();
std::string name;
if (sh_type == elfcpp::SHT_REL)
name = ".rel";
else if (sh_type == elfcpp::SHT_RELA)
name = ".rela";
else
gold_unreachable();
name += data_section->name();
Output_section* os = this->choose_output_section(object, name.c_str(),
sh_type,
shdr.get_sh_flags(),
false);
os->set_should_link_to_symtab();
os->set_info_section(data_section);
Output_section_data* posd;
if (sh_type == elfcpp::SHT_REL)
{
os->set_entsize(elfcpp::Elf_sizes<size>::rel_size);
posd = new Output_relocatable_relocs<elfcpp::SHT_REL,
size,
big_endian>(rr);
}
else if (sh_type == elfcpp::SHT_RELA)
{
os->set_entsize(elfcpp::Elf_sizes<size>::rela_size);
posd = new Output_relocatable_relocs<elfcpp::SHT_RELA,
size,
big_endian>(rr);
}
else
gold_unreachable();
os->add_output_section_data(posd);
rr->set_output_data(posd);
return os;
}
// Handle a group section when doing a relocatable link.
template<int size, bool big_endian>
void
Layout::layout_group(Symbol_table* symtab,
Sized_relobj<size, big_endian>* object,
unsigned int,
const char* group_section_name,
const char* signature,
const elfcpp::Shdr<size, big_endian>& shdr,
elfcpp::Elf_Word flags,
std::vector<unsigned int>* shndxes)
2008-02-06 16:13:50 +08:00
{
gold_assert(parameters->options().relocatable());
2008-02-06 16:13:50 +08:00
gold_assert(shdr.get_sh_type() == elfcpp::SHT_GROUP);
group_section_name = this->namepool_.add(group_section_name, true, NULL);
Output_section* os = this->make_output_section(group_section_name,
elfcpp::SHT_GROUP,
shdr.get_sh_flags());
// We need to find a symbol with the signature in the symbol table.
// If we don't find one now, we need to look again later.
2008-02-06 16:13:50 +08:00
Symbol* sym = symtab->lookup(signature, NULL);
if (sym != NULL)
os->set_info_symndx(sym);
else
{
// Reserve some space to minimize reallocations.
if (this->group_signatures_.empty())
this->group_signatures_.reserve(this->number_of_input_files_ * 16);
// We will wind up using a symbol whose name is the signature.
// So just put the signature in the symbol name pool to save it.
signature = symtab->canonicalize_name(signature);
this->group_signatures_.push_back(Group_signature(os, signature));
}
2008-02-06 16:13:50 +08:00
os->set_should_link_to_symtab();
os->set_entsize(4);
section_size_type entry_count =
convert_to_section_size_type(shdr.get_sh_size() / 4);
Output_section_data* posd =
new Output_data_group<size, big_endian>(object, entry_count, flags,
shndxes);
2008-02-06 16:13:50 +08:00
os->add_output_section_data(posd);
}
// Special GNU handling of sections name .eh_frame. They will
// normally hold exception frame data as defined by the C++ ABI
// (http://codesourcery.com/cxx-abi/).
template<int size, bool big_endian>
Output_section*
Layout::layout_eh_frame(Sized_relobj<size, big_endian>* object,
const unsigned char* symbols,
off_t symbols_size,
const unsigned char* symbol_names,
off_t symbol_names_size,
unsigned int shndx,
const elfcpp::Shdr<size, big_endian>& shdr,
unsigned int reloc_shndx, unsigned int reloc_type,
off_t* off)
{
gold_assert(shdr.get_sh_type() == elfcpp::SHT_PROGBITS);
gold_assert((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
2008-02-04 13:43:05 +08:00
const char* const name = ".eh_frame";
Output_section* os = this->choose_output_section(object,
name,
elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC,
false);
if (os == NULL)
return NULL;
if (this->eh_frame_section_ == NULL)
{
this->eh_frame_section_ = os;
this->eh_frame_data_ = new Eh_frame();
if (parameters->options().eh_frame_hdr())
{
Output_section* hdr_os =
2008-02-04 13:43:05 +08:00
this->choose_output_section(NULL,
".eh_frame_hdr",
elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC,
false);
2008-02-04 13:43:05 +08:00
if (hdr_os != NULL)
{
Eh_frame_hdr* hdr_posd = new Eh_frame_hdr(os,
this->eh_frame_data_);
hdr_os->add_output_section_data(hdr_posd);
2008-02-04 13:43:05 +08:00
hdr_os->set_after_input_sections();
2008-02-05 06:54:31 +08:00
if (!this->script_options_->saw_phdrs_clause())
{
Output_segment* hdr_oseg;
hdr_oseg = this->make_output_segment(elfcpp::PT_GNU_EH_FRAME,
elfcpp::PF_R);
hdr_oseg->add_output_section(hdr_os, elfcpp::PF_R);
}
2008-02-04 13:43:05 +08:00
this->eh_frame_data_->set_eh_frame_hdr(hdr_posd);
}
}
}
gold_assert(this->eh_frame_section_ == os);
if (this->eh_frame_data_->add_ehframe_input_section(object,
symbols,
symbols_size,
symbol_names,
symbol_names_size,
shndx,
reloc_shndx,
reloc_type))
{
os->update_flags_for_input_section(shdr.get_sh_flags());
// We found a .eh_frame section we are going to optimize, so now
// we can add the set of optimized sections to the output
// section. We need to postpone adding this until we've found a
// section we can optimize so that the .eh_frame section in
// crtbegin.o winds up at the start of the output section.
if (!this->added_eh_frame_data_)
{
os->add_output_section_data(this->eh_frame_data_);
this->added_eh_frame_data_ = true;
}
*off = -1;
}
else
{
// We couldn't handle this .eh_frame section for some reason.
// Add it as a normal section.
2008-02-04 13:43:05 +08:00
bool saw_sections_clause = this->script_options_->saw_sections_clause();
*off = os->add_input_section(object, shndx, name, shdr, reloc_shndx,
saw_sections_clause);
}
return os;
}
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
// Add POSD to an output section using NAME, TYPE, and FLAGS. Return
// the output section.
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
Output_section*
Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type,
elfcpp::Elf_Xword flags,
Output_section_data* posd)
{
2008-02-04 13:43:05 +08:00
Output_section* os = this->choose_output_section(NULL, name, type, flags,
false);
if (os != NULL)
os->add_output_section_data(posd);
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
return os;
}
// Map section flags to segment flags.
elfcpp::Elf_Word
Layout::section_flags_to_segment(elfcpp::Elf_Xword flags)
{
elfcpp::Elf_Word ret = elfcpp::PF_R;
if ((flags & elfcpp::SHF_WRITE) != 0)
ret |= elfcpp::PF_W;
if ((flags & elfcpp::SHF_EXECINSTR) != 0)
ret |= elfcpp::PF_X;
return ret;
}
2007-12-01 14:34:12 +08:00
// Sometimes we compress sections. This is typically done for
// sections that are not part of normal program execution (such as
// .debug_* sections), and where the readers of these sections know
// how to deal with compressed sections. (To make it easier for them,
// we will rename the ouput section in such cases from .foo to
// .foo.zlib.nnnn, where nnnn is the uncompressed size.) This routine
// doesn't say for certain whether we'll compress -- it depends on
// commandline options as well -- just whether this section is a
// candidate for compression.
static bool
is_compressible_debug_section(const char* secname)
{
return (strncmp(secname, ".debug", sizeof(".debug") - 1) == 0);
}
// Make a new Output_section, and attach it to segments as
// appropriate.
Output_section*
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
elfcpp::Elf_Xword flags)
{
2007-12-01 14:34:12 +08:00
Output_section* os;
if ((flags & elfcpp::SHF_ALLOC) == 0
&& strcmp(parameters->options().compress_debug_sections(), "none") != 0
2007-12-01 14:34:12 +08:00
&& is_compressible_debug_section(name))
os = new Output_compressed_section(&parameters->options(), name, type,
flags);
else if ((flags & elfcpp::SHF_ALLOC) == 0
&& parameters->options().strip_debug_non_line()
&& strcmp(".debug_abbrev", name) == 0)
{
os = this->debug_abbrev_ = new Output_reduced_debug_abbrev_section(
name, type, flags);
if (this->debug_info_)
this->debug_info_->set_abbreviations(this->debug_abbrev_);
}
else if ((flags & elfcpp::SHF_ALLOC) == 0
&& parameters->options().strip_debug_non_line()
&& strcmp(".debug_info", name) == 0)
{
os = this->debug_info_ = new Output_reduced_debug_info_section(
name, type, flags);
if (this->debug_abbrev_)
this->debug_info_->set_abbreviations(this->debug_abbrev_);
}
else
2007-12-01 14:34:12 +08:00
os = new Output_section(name, type, flags);
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
parameters->target().new_output_section(os);
this->section_list_.push_back(os);
* layout.cc (Layout::layout): If we see an input section with a name that needs sorting, set the must_sort flag for the output section. (Layout::make_output_section): If the name of the output section indicates that it might require sorting, set the may_sort flag. * output.h (Output_section::may_sort_attached_input_sections): New function. (Output_section::set_may_sort_attached_input_sections): New function. (Output_section::must_sort_attached_input_sections): New function. (Output_section::set_must_sort_attached_input_sections): New function. (class Output_section): Declare Input_section_sort_entry. Define Input_section_sort_compare. Declare sort_attached_input_sections. Add new fields: may_sort_attached_input_sections_, must_sort_attached_input_sections_, attached_input_sections_are_sorted_. * output.cc (Output_section::Output_section): Initialize new fields. (Output_section::add_input_section): Add an entry to input_sections_ if may_sort or must_sort are true. (Output_section::set_final_data_size): Call sort_attached_input_sections if necessary. (Output_section::Input_section_sort_entry): Define new class. (Output_section::Input_section_sort_compare::operator()): New function. (Output_section::sort_attached_input_sections): New function. * configure.ac: Check whether the compiler supports constructor priorities. Define a CONSTRUCTOR_PRIORITY automake conditional. * testsuite/initpri1.c: New file. * testsuite/Makefile.am (check_PROGRAMS): Add initpri1 if CONSTRUCTOR_PRIORITY. (initpri1_SOURCES, initpri1_DEPENDENCIES): New variables. (initpri1_LDFLAGS): New variable. * configure, Makefile.in, testsuite/Makefile.in: Rebuild.
2008-03-29 06:42:34 +08:00
// The GNU linker by default sorts some sections by priority, so we
// do the same. We need to know that this might happen before we
// attach any input sections.
if (!this->script_options_->saw_sections_clause()
&& (strcmp(name, ".ctors") == 0
|| strcmp(name, ".dtors") == 0
|| strcmp(name, ".init_array") == 0
|| strcmp(name, ".fini_array") == 0))
os->set_may_sort_attached_input_sections();
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
// With -z relro, we have to recognize the special sections by name.
// There is no other way.
if (!this->script_options_->saw_sections_clause()
&& parameters->options().relro()
&& type == elfcpp::SHT_PROGBITS
&& (flags & elfcpp::SHF_ALLOC) != 0
&& (flags & elfcpp::SHF_WRITE) != 0)
{
if (strcmp(name, ".data.rel.ro") == 0)
os->set_is_relro();
else if (strcmp(name, ".data.rel.ro.local") == 0)
{
os->set_is_relro();
os->set_is_relro_local();
}
}
// Check for .stab*str sections, as .stab* sections need to link to
// them.
if (type == elfcpp::SHT_STRTAB
&& !this->have_stabstr_section_
&& strncmp(name, ".stab", 5) == 0
&& strcmp(name + strlen(name) - 3, "str") == 0)
this->have_stabstr_section_ = true;
// If we have already attached the sections to segments, then we
// need to attach this one now. This happens for sections created
// directly by the linker.
if (this->sections_are_attached_)
this->attach_section_to_segment(os);
return os;
}
2008-02-04 13:43:05 +08:00
// Attach output sections to segments. This is called after we have
// seen all the input sections.
void
Layout::attach_sections_to_segments()
{
for (Section_list::iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
this->attach_section_to_segment(*p);
this->sections_are_attached_ = true;
}
// Attach an output section to a segment.
void
Layout::attach_section_to_segment(Output_section* os)
{
if ((os->flags() & elfcpp::SHF_ALLOC) == 0)
this->unattached_section_list_.push_back(os);
else
this->attach_allocated_section_to_segment(os);
}
// Attach an allocated output section to a segment.
2008-02-05 06:54:31 +08:00
void
Layout::attach_allocated_section_to_segment(Output_section* os)
{
elfcpp::Elf_Xword flags = os->flags();
gold_assert((flags & elfcpp::SHF_ALLOC) != 0);
if (parameters->options().relocatable())
return;
// If we have a SECTIONS clause, we can't handle the attachment to
// segments until after we've seen all the sections.
if (this->script_options_->saw_sections_clause())
return;
gold_assert(!this->script_options_->saw_phdrs_clause());
2008-02-14 06:47:28 +08:00
// This output section goes into a PT_LOAD segment.
elfcpp::Elf_Word seg_flags = Layout::section_flags_to_segment(flags);
// In general the only thing we really care about for PT_LOAD
// segments is whether or not they are writable, so that is how we
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
// search for them. Large data sections also go into their own
// PT_LOAD segment. People who need segments sorted on some other
// basis will have to use a linker script.
Segment_list::const_iterator p;
for (p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
if ((*p)->type() != elfcpp::PT_LOAD)
continue;
if (!parameters->options().omagic()
&& ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
continue;
// If -Tbss was specified, we need to separate the data and BSS
// segments.
if (parameters->options().user_set_Tbss())
{
if ((os->type() == elfcpp::SHT_NOBITS)
== (*p)->has_any_data_sections())
continue;
}
if (os->is_large_data_section() && !(*p)->is_large_data_segment())
continue;
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
(*p)->add_output_section(os, seg_flags);
break;
}
2006-09-27 05:00:34 +08:00
if (p == this->segment_list_.end())
{
Output_segment* oseg = this->make_output_segment(elfcpp::PT_LOAD,
seg_flags);
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
if (os->is_large_data_section())
oseg->set_is_large_data_segment();
oseg->add_output_section(os, seg_flags);
}
// If we see a loadable SHT_NOTE section, we create a PT_NOTE
// segment.
if (os->type() == elfcpp::SHT_NOTE)
{
// See if we already have an equivalent PT_NOTE segment.
for (p = this->segment_list_.begin();
p != segment_list_.end();
++p)
{
if ((*p)->type() == elfcpp::PT_NOTE
&& (((*p)->flags() & elfcpp::PF_W)
== (seg_flags & elfcpp::PF_W)))
{
(*p)->add_output_section(os, seg_flags);
break;
}
}
if (p == this->segment_list_.end())
{
Output_segment* oseg = this->make_output_segment(elfcpp::PT_NOTE,
seg_flags);
oseg->add_output_section(os, seg_flags);
}
}
// If we see a loadable SHF_TLS section, we create a PT_TLS
// segment. There can only be one such segment.
if ((flags & elfcpp::SHF_TLS) != 0)
{
if (this->tls_segment_ == NULL)
* layout.cc (Layout::attach_allocated_section_to_segment): Don't set tls_segment_ or relro_segment_. (Layout::make_output_segment): Set tls_segment_ and relro_segment_ when appropriate. * output.h (Output_section::clear_is_relro): New function. * output.cc (Output_segment::add_output_section): Handle SHF_TLS sections specially even when output_data_ is empty. (Output_segment::maximum_alignment): When first section is relro, only force alignment for PT_LOAD segments. * script.cc (script_data_segment_align): New function. (script_data_segment_relro_end): New function. * script-c.h (script_data_segment_align): Declare. (script_data_segment_relro_end): Declare. * script-sections.h (class Script_sections): Declare data_segment_align and data_segment_relro_end. Add fields segment_align_index_ and saw_relro_end_. * script-sections.cc (class Sections_element): Add set_is_relro virtual function. Add new bool* parameter to place_orphan_here. Add get_output_section virtual function. (class Output_section_definition): Add set_is_relro. Add new bool* parameter to place_orphan_here. Add get_output_section. Add is_relro_ field. (Output_section_definition::Output_section_definition): Initialize evaluated_address_, evaluated_load_address, evaluated_addralign_, and is_relro_ fields. (Output_section_definition::place_orphan_here): Add is_relro parameter. (Output_section_definition::set_section_addresses): Set relro for output section. (Output_section_definition::alternate_constraint): Likewise. (class Orphan_output_section): Add new bool* parameter to place_orphan_here. Add get_output_section. (Orphan_output_section::place_orphan_here): Add is_relro parameter. (Script_sections::Script_sections): Initialize data_segment_align_index_ and saw_relro_end_. (Script_sections::data_segment_align): New function. (Script_sections::data_segment_relro_end): New function. (Script_sections::place_orphan): Set or clear is_relro. (Script_sections::set_section_addresses): Force alignment of first TLS section. * yyscript.y (exp): Call script_data_segment_align and script_data_segment_relro_end. * testsuite/relro_script_test.t: New file. * testsuite/relro_test.cc (using_script): Declare. (t1, t2): Test using_script. * testsuite/Makefile.am (check_PROGRAMS): Add relro_script_test. (relro_script_test_SOURCES): Define. (relro_script_test_DEPENDENCIES): Define. (relro_script_test_LDFLAGS): Define. (relro_script_test_LDADD): Define. (relro_script_test.so): New target. * testsuite/Makefile.in: Rebuild.
2008-08-13 15:37:46 +08:00
this->make_output_segment(elfcpp::PT_TLS, seg_flags);
this->tls_segment_->add_output_section(os, seg_flags);
}
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
// If -z relro is in effect, and we see a relro section, we create a
// PT_GNU_RELRO segment. There can only be one such segment.
if (os->is_relro() && parameters->options().relro())
{
gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W));
if (this->relro_segment_ == NULL)
* layout.cc (Layout::attach_allocated_section_to_segment): Don't set tls_segment_ or relro_segment_. (Layout::make_output_segment): Set tls_segment_ and relro_segment_ when appropriate. * output.h (Output_section::clear_is_relro): New function. * output.cc (Output_segment::add_output_section): Handle SHF_TLS sections specially even when output_data_ is empty. (Output_segment::maximum_alignment): When first section is relro, only force alignment for PT_LOAD segments. * script.cc (script_data_segment_align): New function. (script_data_segment_relro_end): New function. * script-c.h (script_data_segment_align): Declare. (script_data_segment_relro_end): Declare. * script-sections.h (class Script_sections): Declare data_segment_align and data_segment_relro_end. Add fields segment_align_index_ and saw_relro_end_. * script-sections.cc (class Sections_element): Add set_is_relro virtual function. Add new bool* parameter to place_orphan_here. Add get_output_section virtual function. (class Output_section_definition): Add set_is_relro. Add new bool* parameter to place_orphan_here. Add get_output_section. Add is_relro_ field. (Output_section_definition::Output_section_definition): Initialize evaluated_address_, evaluated_load_address, evaluated_addralign_, and is_relro_ fields. (Output_section_definition::place_orphan_here): Add is_relro parameter. (Output_section_definition::set_section_addresses): Set relro for output section. (Output_section_definition::alternate_constraint): Likewise. (class Orphan_output_section): Add new bool* parameter to place_orphan_here. Add get_output_section. (Orphan_output_section::place_orphan_here): Add is_relro parameter. (Script_sections::Script_sections): Initialize data_segment_align_index_ and saw_relro_end_. (Script_sections::data_segment_align): New function. (Script_sections::data_segment_relro_end): New function. (Script_sections::place_orphan): Set or clear is_relro. (Script_sections::set_section_addresses): Force alignment of first TLS section. * yyscript.y (exp): Call script_data_segment_align and script_data_segment_relro_end. * testsuite/relro_script_test.t: New file. * testsuite/relro_test.cc (using_script): Declare. (t1, t2): Test using_script. * testsuite/Makefile.am (check_PROGRAMS): Add relro_script_test. (relro_script_test_SOURCES): Define. (relro_script_test_DEPENDENCIES): Define. (relro_script_test_LDFLAGS): Define. (relro_script_test_LDADD): Define. (relro_script_test.so): New target. * testsuite/Makefile.in: Rebuild.
2008-08-13 15:37:46 +08:00
this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags);
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
this->relro_segment_->add_output_section(os, seg_flags);
}
}
// Make an output section for a script.
Output_section*
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);
os->set_found_in_sections_clause();
return os;
}
// Return the number of segments we expect to see.
size_t
Layout::expected_segment_count() const
{
size_t ret = this->segment_list_.size();
// If we didn't see a SECTIONS clause in a linker script, we should
// already have the complete list of segments. Otherwise we ask the
// SECTIONS clause how many segments it expects, and add in the ones
// we already have (PT_GNU_STACK, PT_GNU_EH_FRAME, etc.)
if (!this->script_options_->saw_sections_clause())
return ret;
else
{
const Script_sections* ss = this->script_options_->script_sections();
return ret + ss->expected_segment_count(this);
}
}
2007-10-23 13:05:48 +08:00
// Handle the .note.GNU-stack section at layout time. SEEN_GNU_STACK
// is whether we saw a .note.GNU-stack section in the object file.
// GNU_STACK_FLAGS is the section flags. The flags give the
// protection required for stack memory. We record this in an
// executable as a PT_GNU_STACK segment. If an object file does not
// have a .note.GNU-stack segment, we must assume that it is an old
// object. On some targets that will force an executable stack.
void
Layout::layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags)
{
if (!seen_gnu_stack)
this->input_without_gnu_stack_note_ = true;
else
{
this->input_with_gnu_stack_note_ = true;
if ((gnu_stack_flags & elfcpp::SHF_EXECINSTR) != 0)
this->input_requires_executable_stack_ = true;
}
}
// Create automatic note sections.
void
Layout::create_notes()
{
this->create_gold_note();
this->create_executable_stack_info();
this->create_build_id();
}
// Create the dynamic sections which are needed before we read the
// relocs.
void
Layout::create_initial_dynamic_sections(Symbol_table* symtab)
{
if (parameters->doing_static_link())
return;
this->dynamic_section_ = this->choose_output_section(NULL, ".dynamic",
elfcpp::SHT_DYNAMIC,
(elfcpp::SHF_ALLOC
| elfcpp::SHF_WRITE),
false);
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
this->dynamic_section_->set_is_relro();
symtab->define_in_output_data("_DYNAMIC", NULL, this->dynamic_section_, 0, 0,
elfcpp::STT_OBJECT, elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0, false, false);
2006-12-02 00:51:25 +08:00
2007-09-26 15:01:35 +08:00
this->dynamic_data_ = new Output_data_dynamic(&this->dynpool_);
2006-12-02 00:51:25 +08:00
this->dynamic_section_->add_output_section_data(this->dynamic_data_);
}
2007-09-22 12:42:09 +08:00
// For each output section whose name can be represented as C symbol,
// define __start and __stop symbols for the section. This is a GNU
// extension.
void
Layout::define_section_symbols(Symbol_table* symtab)
2007-09-22 12:42:09 +08:00
{
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
const char* const name = (*p)->name();
if (name[strspn(name,
("0123456789"
"ABCDEFGHIJKLMNOPWRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"_"))]
== '\0')
{
const std::string name_string(name);
const std::string start_name("__start_" + name_string);
const std::string stop_name("__stop_" + name_string);
symtab->define_in_output_data(start_name.c_str(),
2007-09-22 12:42:09 +08:00
NULL, // version
*p,
0, // value
0, // symsize
elfcpp::STT_NOTYPE,
elfcpp::STB_GLOBAL,
elfcpp::STV_DEFAULT,
0, // nonvis
false, // offset_is_from_end
2008-02-04 13:43:05 +08:00
true); // only_if_ref
2007-09-22 12:42:09 +08:00
symtab->define_in_output_data(stop_name.c_str(),
2007-09-22 12:42:09 +08:00
NULL, // version
*p,
0, // value
0, // symsize
elfcpp::STT_NOTYPE,
elfcpp::STB_GLOBAL,
elfcpp::STV_DEFAULT,
0, // nonvis
true, // offset_is_from_end
2008-02-04 13:43:05 +08:00
true); // only_if_ref
2007-09-22 12:42:09 +08:00
}
}
}
// Define symbols for group signatures.
void
Layout::define_group_signatures(Symbol_table* symtab)
{
for (Group_signatures::iterator p = this->group_signatures_.begin();
p != this->group_signatures_.end();
++p)
{
Symbol* sym = symtab->lookup(p->signature, NULL);
if (sym != NULL)
p->section->set_info_symndx(sym);
else
{
// Force the name of the group section to the group
// signature, and use the group's section symbol as the
// signature symbol.
if (strcmp(p->section->name(), p->signature) != 0)
{
const char* name = this->namepool_.add(p->signature,
true, NULL);
p->section->set_name(name);
}
p->section->set_needs_symtab_index();
p->section->set_info_section_symndx(p->section);
}
}
this->group_signatures_.clear();
}
2006-09-28 06:53:42 +08:00
// Find the first read-only PT_LOAD segment, creating one if
// necessary.
2006-09-27 05:00:34 +08:00
2006-09-28 06:53:42 +08:00
Output_segment*
Layout::find_first_load_seg()
2006-09-27 05:00:34 +08:00
{
2006-09-28 06:53:42 +08:00
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
if ((*p)->type() == elfcpp::PT_LOAD
&& ((*p)->flags() & elfcpp::PF_R) != 0
&& (parameters->options().omagic()
|| ((*p)->flags() & elfcpp::PF_W) == 0))
2006-09-28 06:53:42 +08:00
return *p;
}
2008-02-05 06:54:31 +08:00
gold_assert(!this->script_options_->saw_phdrs_clause());
Output_segment* load_seg = this->make_output_segment(elfcpp::PT_LOAD,
elfcpp::PF_R);
2006-09-28 06:53:42 +08:00
return load_seg;
2006-09-27 05:00:34 +08:00
}
// Finalize the layout. When this is called, we have created all the
// output sections and all the output segments which are based on
// input sections. We have several things to do, and we have to do
// them in the right order, so that we get the right results correctly
// and efficiently.
// 1) Finalize the list of output segments and create the segment
// table header.
// 2) Finalize the dynamic symbol table and associated sections.
// 3) Determine the final file offset of all the output segments.
// 4) Determine the final file offset of all the SHF_ALLOC output
// sections.
2006-09-28 06:53:42 +08:00
// 5) Create the symbol table sections and the section name table
// section.
// 6) Finalize the symbol table: set symbol values to their final
2006-09-27 05:00:34 +08:00
// value and make a final determination of which symbols are going
// into the output symbol table.
// 7) Create the section table header.
// 8) Determine the final file offset of all the output sections which
// are not SHF_ALLOC, including the section table header.
// 9) Finalize the ELF file header.
2006-09-28 06:53:42 +08:00
// This function returns the size of the output file.
off_t
Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
Target* target, const Task* task)
2006-09-27 05:00:34 +08:00
{
2007-09-21 15:20:01 +08:00
target->finalize_sections(this);
this->count_local_symbols(task, input_objects);
this->link_stabs_sections();
Output_segment* phdr_seg = NULL;
if (!parameters->options().relocatable() && !parameters->doing_static_link())
2006-09-27 05:00:34 +08:00
{
// There was a dynamic object in the link. We need to create
// some information for the dynamic linker.
// Create the PT_PHDR segment which will hold the program
// headers.
2008-02-05 06:54:31 +08:00
if (!this->script_options_->saw_phdrs_clause())
phdr_seg = this->make_output_segment(elfcpp::PT_PHDR, elfcpp::PF_R);
2006-12-06 08:02:36 +08:00
// Create the dynamic symbol table, including the hash table.
Output_section* dynstr;
std::vector<Symbol*> dynamic_symbols;
unsigned int local_dynamic_count;
Versions versions(*this->script_options()->version_script_info(),
&this->dynpool_);
this->create_dynamic_symtab(input_objects, symtab, &dynstr,
2006-12-06 08:02:36 +08:00
&local_dynamic_count, &dynamic_symbols,
&versions);
// Create the .interp section to hold the name of the
// interpreter, and put it in a PT_INTERP segment.
if (!parameters->options().shared())
this->create_interp(target);
// Finish the .dynamic section to hold the dynamic data, and put
// it in a PT_DYNAMIC segment.
2006-12-02 00:51:25 +08:00
this->finish_dynamic_section(input_objects, symtab);
2006-12-06 08:02:36 +08:00
// We should have added everything we need to the dynamic string
// table.
this->dynpool_.set_string_offsets();
// Create the version sections. We can't do this until the
// dynamic string table is complete.
2007-10-23 07:08:22 +08:00
this->create_version_sections(&versions, symtab, local_dynamic_count,
2006-12-06 08:02:36 +08:00
dynamic_symbols, dynstr);
2006-09-27 05:00:34 +08:00
}
if (this->incremental_inputs_)
{
this->incremental_inputs_->finalize();
this->create_incremental_info_sections();
}
2006-09-27 05:00:34 +08:00
2008-02-04 13:43:05 +08:00
// If there is a SECTIONS clause, put all the input sections into
// the required order.
Output_segment* load_seg;
if (this->script_options_->saw_sections_clause())
2008-02-04 13:43:05 +08:00
load_seg = this->set_section_addresses_from_script(symtab);
else if (parameters->options().relocatable())
load_seg = NULL;
2008-02-04 13:43:05 +08:00
else
load_seg = this->find_first_load_seg();
2006-09-27 05:00:34 +08:00
if (parameters->options().oformat_enum()
!= General_options::OBJECT_FORMAT_ELF)
2008-02-07 15:33:46 +08:00
load_seg = NULL;
gold_assert(phdr_seg == NULL || load_seg != NULL);
2006-09-28 06:53:42 +08:00
// Lay out the segment headers.
Output_segment_headers* segment_headers;
if (parameters->options().relocatable())
2008-02-06 16:13:50 +08:00
segment_headers = NULL;
else
{
segment_headers = new Output_segment_headers(this->segment_list_);
if (load_seg != NULL)
load_seg->add_initial_output_data(segment_headers);
if (phdr_seg != NULL)
phdr_seg->add_initial_output_data(segment_headers);
}
2006-09-28 06:53:42 +08:00
// Lay out the file header.
Output_file_header* file_header;
file_header = new Output_file_header(target, symtab, segment_headers,
parameters->options().entry());
2008-02-04 13:43:05 +08:00
if (load_seg != NULL)
load_seg->add_initial_output_data(file_header);
this->special_output_list_.push_back(file_header);
2008-02-06 16:13:50 +08:00
if (segment_headers != NULL)
this->special_output_list_.push_back(segment_headers);
2006-09-28 06:53:42 +08:00
2008-02-06 16:13:50 +08:00
if (this->script_options_->saw_phdrs_clause()
&& !parameters->options().relocatable())
2008-02-05 06:54:31 +08:00
{
// Support use of FILEHDRS and PHDRS attachments in a PHDRS
// clause in a linker script.
Script_sections* ss = this->script_options_->script_sections();
ss->put_headers_in_phdrs(file_header, segment_headers);
}
// We set the output section indexes in set_segment_offsets and
// set_section_indexes.
unsigned int shndx = 1;
// Set the file offsets of all the segments, and all the sections
// they contain.
2008-02-06 16:13:50 +08:00
off_t off;
if (!parameters->options().relocatable())
2008-02-06 16:13:50 +08:00
off = this->set_segment_offsets(target, load_seg, &shndx);
else
off = this->set_relocatable_section_offsets(file_header, &shndx);
2006-09-28 06:53:42 +08:00
// Set the file offsets of all the non-data sections we've seen so
// far which don't have to wait for the input sections. We need
// this in order to finalize local symbols in non-allocated
// sections.
off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
// Set the section indexes of all unallocated sections seen so far,
// in case any of them are somehow referenced by a symbol.
shndx = this->set_section_indexes(shndx);
2006-09-28 06:53:42 +08:00
// Create the symbol table sections.
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
this->create_symtab_sections(input_objects, symtab, shndx, &off);
if (!parameters->doing_static_link())
this->assign_local_dynsym_offsets(input_objects);
2006-09-28 06:53:42 +08:00
// Process any symbol assignments from a linker script. This must
// be called after the symbol table has been finalized.
this->script_options_->finalize_symbols(symtab, this);
2006-09-28 06:53:42 +08:00
// Create the .shstrtab section.
Output_section* shstrtab_section = this->create_shstrtab();
// Set the file offsets of the rest of the non-data sections which
// don't have to wait for the input sections.
off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
// Now that all sections have been created, set the section indexes
// for any sections which haven't been done yet.
shndx = this->set_section_indexes(shndx);
2006-09-28 06:53:42 +08:00
// Create the section table header.
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
this->create_shdrs(shstrtab_section, &off);
2006-09-28 06:53:42 +08:00
// If there are no sections which require postprocessing, we can
// handle the section names now, and avoid a resize later.
if (!this->any_postprocessing_sections_)
off = this->set_section_offsets(off,
STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS);
file_header->set_section_info(this->section_headers_, shstrtab_section);
2006-09-28 06:53:42 +08:00
// Now we know exactly where everything goes in the output file
// (except for non-allocated sections which require postprocessing).
Output_data::layout_complete();
2006-09-28 06:53:42 +08:00
this->output_file_size_ = off;
2006-09-28 06:53:42 +08:00
return off;
}
// Create a note header following the format defined in the ELF ABI.
// NAME is the name, NOTE_TYPE is the type, SECTION_NAME is the name
// of the section to create, DESCSZ is the size of the descriptor.
// ALLOCATE is true if the section should be allocated in memory.
// This returns the new note section. It sets *TRAILING_PADDING to
// the number of trailing zero bytes required.
Output_section*
Layout::create_note(const char* name, int note_type,
const char* section_name, size_t descsz,
bool allocate, size_t* trailing_padding)
{
// Authorities all agree that the values in a .note field should
// be aligned on 4-byte boundaries for 32-bit binaries. However,
// they differ on what the alignment is for 64-bit binaries.
// The GABI says unambiguously they take 8-byte alignment:
// http://sco.com/developers/gabi/latest/ch5.pheader.html#note_section
// Other documentation says alignment should always be 4 bytes:
// http://www.netbsd.org/docs/kernel/elf-notes.html#note-format
// GNU ld and GNU readelf both support the latter (at least as of
// version 2.16.91), and glibc always generates the latter for
// .note.ABI-tag (as of version 1.6), so that's the one we go with
// here.
2007-10-23 13:05:48 +08:00
#ifdef GABI_FORMAT_FOR_DOTNOTE_SECTION // This is not defined by default.
const int size = parameters->target().get_size();
#else
const int size = 32;
#endif
// The contents of the .note section.
size_t namesz = strlen(name) + 1;
size_t aligned_namesz = align_address(namesz, size / 8);
size_t aligned_descsz = align_address(descsz, size / 8);
size_t notehdrsz = 3 * (size / 8) + aligned_namesz;
unsigned char* buffer = new unsigned char[notehdrsz];
memset(buffer, 0, notehdrsz);
bool is_big_endian = parameters->target().is_big_endian();
if (size == 32)
{
if (!is_big_endian)
{
elfcpp::Swap<32, false>::writeval(buffer, namesz);
elfcpp::Swap<32, false>::writeval(buffer + 4, descsz);
elfcpp::Swap<32, false>::writeval(buffer + 8, note_type);
}
else
{
elfcpp::Swap<32, true>::writeval(buffer, namesz);
elfcpp::Swap<32, true>::writeval(buffer + 4, descsz);
elfcpp::Swap<32, true>::writeval(buffer + 8, note_type);
}
}
else if (size == 64)
{
if (!is_big_endian)
{
elfcpp::Swap<64, false>::writeval(buffer, namesz);
elfcpp::Swap<64, false>::writeval(buffer + 8, descsz);
elfcpp::Swap<64, false>::writeval(buffer + 16, note_type);
}
else
{
elfcpp::Swap<64, true>::writeval(buffer, namesz);
elfcpp::Swap<64, true>::writeval(buffer + 8, descsz);
elfcpp::Swap<64, true>::writeval(buffer + 16, note_type);
}
}
else
gold_unreachable();
memcpy(buffer + 3 * (size / 8), name, namesz);
elfcpp::Elf_Xword flags = 0;
if (allocate)
flags = elfcpp::SHF_ALLOC;
Output_section* os = this->choose_output_section(NULL, section_name,
elfcpp::SHT_NOTE,
flags, false);
if (os == NULL)
return NULL;
Output_section_data* posd = new Output_data_const_buffer(buffer, notehdrsz,
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
size / 8,
"** note header");
os->add_output_section_data(posd);
*trailing_padding = aligned_descsz - descsz;
return os;
}
// For an executable or shared library, create a note to record the
// version of gold used to create the binary.
void
Layout::create_gold_note()
{
if (parameters->options().relocatable())
return;
std::string desc = std::string("gold ") + gold::get_version_string();
size_t trailing_padding;
Output_section *os = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
".note.gnu.gold-version", desc.size(),
false, &trailing_padding);
if (os == NULL)
return;
Output_section_data* posd = new Output_data_const(desc, 4);
os->add_output_section_data(posd);
if (trailing_padding > 0)
{
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
posd = new Output_data_zero_fill(trailing_padding, 0);
os->add_output_section_data(posd);
}
}
2007-10-23 13:05:48 +08:00
// Record whether the stack should be executable. This can be set
// from the command line using the -z execstack or -z noexecstack
// options. Otherwise, if any input file has a .note.GNU-stack
// section with the SHF_EXECINSTR flag set, the stack should be
// executable. Otherwise, if at least one input file a
// .note.GNU-stack section, and some input file has no .note.GNU-stack
// section, we use the target default for whether the stack should be
// executable. Otherwise, we don't generate a stack note. When
// generating a object file, we create a .note.GNU-stack section with
// the appropriate marking. When generating an executable or shared
// library, we create a PT_GNU_STACK segment.
void
Layout::create_executable_stack_info()
2007-10-23 13:05:48 +08:00
{
bool is_stack_executable;
if (parameters->options().is_execstack_set())
is_stack_executable = parameters->options().is_stack_executable();
2007-10-23 13:05:48 +08:00
else if (!this->input_with_gnu_stack_note_)
return;
else
{
if (this->input_requires_executable_stack_)
is_stack_executable = true;
else if (this->input_without_gnu_stack_note_)
is_stack_executable =
parameters->target().is_default_stack_executable();
2007-10-23 13:05:48 +08:00
else
is_stack_executable = false;
}
if (parameters->options().relocatable())
2007-10-23 13:05:48 +08:00
{
const char* name = this->namepool_.add(".note.GNU-stack", false, NULL);
elfcpp::Elf_Xword flags = 0;
if (is_stack_executable)
flags |= elfcpp::SHF_EXECINSTR;
this->make_output_section(name, elfcpp::SHT_PROGBITS, flags);
}
else
{
2008-02-05 06:54:31 +08:00
if (this->script_options_->saw_phdrs_clause())
return;
2007-10-23 13:05:48 +08:00
int flags = elfcpp::PF_R | elfcpp::PF_W;
if (is_stack_executable)
flags |= elfcpp::PF_X;
this->make_output_segment(elfcpp::PT_GNU_STACK, flags);
2007-10-23 13:05:48 +08:00
}
}
// If --build-id was used, set up the build ID note.
void
Layout::create_build_id()
{
if (!parameters->options().user_set_build_id())
return;
const char* style = parameters->options().build_id();
if (strcmp(style, "none") == 0)
return;
// Set DESCSZ to the size of the note descriptor. When possible,
// set DESC to the note descriptor contents.
size_t descsz;
std::string desc;
if (strcmp(style, "md5") == 0)
descsz = 128 / 8;
else if (strcmp(style, "sha1") == 0)
descsz = 160 / 8;
else if (strcmp(style, "uuid") == 0)
{
const size_t uuidsz = 128 / 8;
char buffer[uuidsz];
memset(buffer, 0, uuidsz);
int descriptor = open_descriptor(-1, "/dev/urandom", O_RDONLY);
if (descriptor < 0)
gold_error(_("--build-id=uuid failed: could not open /dev/urandom: %s"),
strerror(errno));
else
{
ssize_t got = ::read(descriptor, buffer, uuidsz);
release_descriptor(descriptor, true);
if (got < 0)
gold_error(_("/dev/urandom: read failed: %s"), strerror(errno));
else if (static_cast<size_t>(got) != uuidsz)
gold_error(_("/dev/urandom: expected %zu bytes, got %zd bytes"),
uuidsz, got);
}
desc.assign(buffer, uuidsz);
descsz = uuidsz;
}
else if (strncmp(style, "0x", 2) == 0)
{
hex_init();
const char* p = style + 2;
while (*p != '\0')
{
if (hex_p(p[0]) && hex_p(p[1]))
{
char c = (hex_value(p[0]) << 4) | hex_value(p[1]);
desc += c;
p += 2;
}
else if (*p == '-' || *p == ':')
++p;
else
gold_fatal(_("--build-id argument '%s' not a valid hex number"),
style);
}
descsz = desc.size();
}
else
gold_fatal(_("unrecognized --build-id argument '%s'"), style);
// Create the note.
size_t trailing_padding;
Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_BUILD_ID,
".note.gnu.build-id", descsz, true,
&trailing_padding);
if (os == NULL)
return;
if (!desc.empty())
{
// We know the value already, so we fill it in now.
gold_assert(desc.size() == descsz);
Output_section_data* posd = new Output_data_const(desc, 4);
os->add_output_section_data(posd);
if (trailing_padding != 0)
{
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
posd = new Output_data_zero_fill(trailing_padding, 0);
os->add_output_section_data(posd);
}
}
else
{
// We need to compute a checksum after we have completed the
// link.
gold_assert(trailing_padding == 0);
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
this->build_id_note_ = new Output_data_zero_fill(descsz, 4);
os->add_output_section_data(this->build_id_note_);
}
}
// If we have both .stabXX and .stabXXstr sections, then the sh_link
// field of the former should point to the latter. I'm not sure who
// started this, but the GNU linker does it, and some tools depend
// upon it.
void
Layout::link_stabs_sections()
{
if (!this->have_stabstr_section_)
return;
for (Section_list::iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if ((*p)->type() != elfcpp::SHT_STRTAB)
continue;
const char* name = (*p)->name();
if (strncmp(name, ".stab", 5) != 0)
continue;
size_t len = strlen(name);
if (strcmp(name + len - 3, "str") != 0)
continue;
std::string stab_name(name, len - 3);
Output_section* stab_sec;
stab_sec = this->find_output_section(stab_name.c_str());
if (stab_sec != NULL)
stab_sec->set_link_section(*p);
}
}
// Create .gnu_incremental_inputs and .gnu_incremental_strtab sections needed
// for the next run of incremental linking to check what has changed.
void
Layout::create_incremental_info_sections()
{
gold_assert(this->incremental_inputs_ != NULL);
// Add the .gnu_incremental_inputs section.
const char *incremental_inputs_name =
this->namepool_.add(".gnu_incremental_inputs", false, NULL);
Output_section* inputs_os =
this->make_output_section(incremental_inputs_name,
elfcpp::SHT_GNU_INCREMENTAL_INPUTS, 0);
Output_section_data* posd =
this->incremental_inputs_->create_incremental_inputs_section_data();
inputs_os->add_output_section_data(posd);
// Add the .gnu_incremental_strtab section.
const char *incremental_strtab_name =
this->namepool_.add(".gnu_incremental_strtab", false, NULL);
Output_section* strtab_os = this->make_output_section(incremental_strtab_name,
elfcpp::SHT_STRTAB,
0);
Output_data_strtab* strtab_data =
new Output_data_strtab(this->incremental_inputs_->get_stringpool());
strtab_os->add_output_section_data(strtab_data);
inputs_os->set_link_section(strtab_data);
}
2006-09-28 06:53:42 +08:00
// Return whether SEG1 should be before SEG2 in the output file. This
// is based entirely on the segment type and flags. When this is
// called the segment addresses has normally not yet been set.
bool
Layout::segment_precedes(const Output_segment* seg1,
const Output_segment* seg2)
{
elfcpp::Elf_Word type1 = seg1->type();
elfcpp::Elf_Word type2 = seg2->type();
// The single PT_PHDR segment is required to precede any loadable
// segment. We simply make it always first.
if (type1 == elfcpp::PT_PHDR)
{
gold_assert(type2 != elfcpp::PT_PHDR);
2006-09-28 06:53:42 +08:00
return true;
}
if (type2 == elfcpp::PT_PHDR)
return false;
// The single PT_INTERP segment is required to precede any loadable
// segment. We simply make it always second.
if (type1 == elfcpp::PT_INTERP)
{
gold_assert(type2 != elfcpp::PT_INTERP);
2006-09-28 06:53:42 +08:00
return true;
}
if (type2 == elfcpp::PT_INTERP)
return false;
// We then put PT_LOAD segments before any other segments.
if (type1 == elfcpp::PT_LOAD && type2 != elfcpp::PT_LOAD)
return true;
if (type2 == elfcpp::PT_LOAD && type1 != elfcpp::PT_LOAD)
return false;
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
// We put the PT_TLS segment last except for the PT_GNU_RELRO
// segment, because that is where the dynamic linker expects to find
// it (this is just for efficiency; other positions would also work
// correctly).
if (type1 == elfcpp::PT_TLS
&& type2 != elfcpp::PT_TLS
&& type2 != elfcpp::PT_GNU_RELRO)
return false;
if (type2 == elfcpp::PT_TLS
&& type1 != elfcpp::PT_TLS
&& type1 != elfcpp::PT_GNU_RELRO)
return true;
// We put the PT_GNU_RELRO segment last, because that is where the
// dynamic linker expects to find it (as with PT_TLS, this is just
// for efficiency).
if (type1 == elfcpp::PT_GNU_RELRO && type2 != elfcpp::PT_GNU_RELRO)
return false;
* options.h (class General_options): Add -z relro. * layout.cc (Layout::Layout): Initialize relro_segment_. (Layout::add_output_section_data): Return the output section. (Layout::make_output_section): Rcognize relro sections and mark them appropriately. (Layout::attach_allocated_section_to_segment): Put relro sections in a PT_GNU_RELRO segment. (Layout::create_initial_dynamic_sections): Mark the .dynamic section as relro. (Layout::segment_precedes): Sort PT_GNU_RELRO segments after PT_TLS segments. (Layout::linkonce_mapping): Map d.rel.ro.local to .data.rel.ro.local. (Layout::output_section_name): Us .data.rel.ro.local for any section which begins with that. * layout.h (class Layout): Update add_output_section_data declaration. Add relro_segment_ field. * output.cc (Output_section::Output_section): Initialize is_relro_ and is_relro_local_ fields. (Output_segment::add_output_section): Group relro sections. (Output_segment::is_first_section_relro): New function. (Output_segment::maximum_alignment): If there is a relro section, align the segment to the common page size. (Output_segment::set_section_addresses): Track whether we are looking at relro sections. If the last section is a relro section, align to the common page size. (Output_segment::set_section_list_addresses): Add in_relro parameter. Change all callers. Align to the page size when moving from relro to non-relro section. (Output_segment::set_offset): Align memsz of a PT_GNU_RELRO segment. * output.h (class Output_section): Add is_relro_ and is_relro_local_ fields. (Output_section::is_relro): New function. (Output_section::set_is_relro): New function. (Output_section::is_relro_local): New function. (Output_section::set_is_relro_local): New function. (class Output_segment): Update declarations. * i386.cc (Target_i386::got_section): Mark .got section as relro. * sparc.cc (Target_sparc::got_section): Likewise. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_test_main.cc: New file. * testsuite/relro_test.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add relro_test. (relro_test_SOURCES, relro_test_DEPENDENCIES): New variables. (relro_test_LDFLAGS, relro_test_LDADD): New variables. (relro_test.so, relro_test_pic.o): New targets. * testsuite/Makefile.in: Rebuild.
2008-05-20 12:00:47 +08:00
if (type2 == elfcpp::PT_GNU_RELRO && type1 != elfcpp::PT_GNU_RELRO)
return true;
2006-09-28 06:53:42 +08:00
const elfcpp::Elf_Word flags1 = seg1->flags();
const elfcpp::Elf_Word flags2 = seg2->flags();
// The order of non-PT_LOAD segments is unimportant. We simply sort
// by the numeric segment type and flags values. There should not
// be more than one segment with the same type and flags.
if (type1 != elfcpp::PT_LOAD)
{
if (type1 != type2)
return type1 < type2;
gold_assert(flags1 != flags2);
2006-09-28 06:53:42 +08:00
return flags1 < flags2;
}
2008-02-04 13:43:05 +08:00
// If the addresses are set already, sort by load address.
if (seg1->are_addresses_set())
{
if (!seg2->are_addresses_set())
return true;
unsigned int section_count1 = seg1->output_section_count();
unsigned int section_count2 = seg2->output_section_count();
if (section_count1 == 0 && section_count2 > 0)
return true;
if (section_count1 > 0 && section_count2 == 0)
return false;
uint64_t paddr1 = seg1->first_section_load_address();
uint64_t paddr2 = seg2->first_section_load_address();
if (paddr1 != paddr2)
return paddr1 < paddr2;
}
else if (seg2->are_addresses_set())
return false;
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
// A segment which holds large data comes after a segment which does
// not hold large data.
if (seg1->is_large_data_segment())
{
if (!seg2->is_large_data_segment())
return false;
}
else if (seg2->is_large_data_segment())
return true;
// Otherwise, we sort PT_LOAD segments based on the flags. Readonly
// segments come before writable segments. Then writable segments
// with data come before writable segments without data. Then
// executable segments come before non-executable segments. Then
// the unlikely case of a non-readable segment comes before the
// normal case of a readable segment. If there are multiple
// segments with the same type and flags, we require that the
// address be set, and we sort by virtual address and then physical
// address.
2006-09-28 06:53:42 +08:00
if ((flags1 & elfcpp::PF_W) != (flags2 & elfcpp::PF_W))
return (flags1 & elfcpp::PF_W) == 0;
2008-02-14 06:47:28 +08:00
if ((flags1 & elfcpp::PF_W) != 0
&& seg1->has_any_data_sections() != seg2->has_any_data_sections())
return seg1->has_any_data_sections();
2006-09-28 06:53:42 +08:00
if ((flags1 & elfcpp::PF_X) != (flags2 & elfcpp::PF_X))
return (flags1 & elfcpp::PF_X) != 0;
if ((flags1 & elfcpp::PF_R) != (flags2 & elfcpp::PF_R))
return (flags1 & elfcpp::PF_R) == 0;
2008-02-04 13:43:05 +08:00
// We shouldn't get here--we shouldn't create segments which we
// can't distinguish.
gold_unreachable();
2006-09-28 06:53:42 +08:00
}
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
// Increase OFF so that it is congruent to ADDR modulo ABI_PAGESIZE.
static off_t
align_file_offset(off_t off, uint64_t addr, uint64_t abi_pagesize)
{
uint64_t unsigned_off = off;
uint64_t aligned_off = ((unsigned_off & ~(abi_pagesize - 1))
| (addr & (abi_pagesize - 1)));
if (aligned_off < unsigned_off)
aligned_off += abi_pagesize;
return aligned_off;
}
// Set the file offsets of all the segments, and all the sections they
// contain. They have all been created. LOAD_SEG must be be laid out
// first. Return the offset of the data to follow.
2006-09-28 06:53:42 +08:00
off_t
Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
unsigned int *pshndx)
2006-09-28 06:53:42 +08:00
{
// Sort them into the final order.
2006-09-27 05:00:34 +08:00
std::sort(this->segment_list_.begin(), this->segment_list_.end(),
Layout::Compare_segments());
2006-09-28 06:53:42 +08:00
// Find the PT_LOAD segments, and set their addresses and offsets
// and their section's addresses and offsets.
uint64_t addr;
if (parameters->options().user_set_Ttext())
addr = parameters->options().Ttext();
else if (parameters->options().shared())
2008-02-04 13:43:05 +08:00
addr = 0;
else
addr = target->default_text_segment_address();
2006-09-28 06:53:42 +08:00
off_t off = 0;
2008-02-04 13:43:05 +08:00
// If LOAD_SEG is NULL, then the file header and segment headers
// will not be loadable. But they still need to be at offset 0 in
// the file. Set their offsets now.
if (load_seg == NULL)
{
for (Data_list::iterator p = this->special_output_list_.begin();
p != this->special_output_list_.end();
++p)
{
off = align_address(off, (*p)->addralign());
(*p)->set_address_and_file_offset(0, off);
off += (*p)->data_size();
}
}
const bool check_sections = parameters->options().check_sections();
Output_segment* last_load_segment = NULL;
2006-09-28 06:53:42 +08:00
bool was_readonly = false;
for (Segment_list::iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
if ((*p)->type() == elfcpp::PT_LOAD)
{
if (load_seg != NULL && load_seg != *p)
gold_unreachable();
2006-09-28 06:53:42 +08:00
load_seg = NULL;
2008-02-14 06:47:28 +08:00
bool are_addresses_set = (*p)->are_addresses_set();
if (are_addresses_set)
{
// When it comes to setting file offsets, we care about
// the physical address.
addr = (*p)->paddr();
}
else if (parameters->options().user_set_Tdata()
2008-02-14 06:47:28 +08:00
&& ((*p)->flags() & elfcpp::PF_W) != 0
&& (!parameters->options().user_set_Tbss()
2008-02-14 06:47:28 +08:00
|| (*p)->has_any_data_sections()))
{
addr = parameters->options().Tdata();
2008-02-14 06:47:28 +08:00
are_addresses_set = true;
}
else if (parameters->options().user_set_Tbss()
2008-02-14 06:47:28 +08:00
&& ((*p)->flags() & elfcpp::PF_W) != 0
&& !(*p)->has_any_data_sections())
{
addr = parameters->options().Tbss();
2008-02-14 06:47:28 +08:00
are_addresses_set = true;
}
2006-09-28 06:53:42 +08:00
uint64_t orig_addr = addr;
uint64_t orig_off = off;
2008-02-04 13:43:05 +08:00
uint64_t aligned_addr = 0;
2006-09-28 06:53:42 +08:00
uint64_t abi_pagesize = target->abi_pagesize();
uint64_t common_pagesize = target->common_pagesize();
if (!parameters->options().nmagic()
&& !parameters->options().omagic())
(*p)->set_minimum_p_align(common_pagesize);
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
if (!are_addresses_set)
2008-02-04 13:43:05 +08:00
{
// If the last segment was readonly, and this one is
// not, then skip the address forward one page,
// maintaining the same position within the page. This
// lets us store both segments overlapping on a single
// page in the file, but the loader will put them on
// different pages in memory.
addr = align_address(addr, (*p)->maximum_alignment());
2006-09-28 06:53:42 +08:00
aligned_addr = addr;
2008-02-04 13:43:05 +08:00
if (was_readonly && ((*p)->flags() & elfcpp::PF_W) != 0)
{
if ((addr & (abi_pagesize - 1)) != 0)
addr = addr + abi_pagesize;
}
off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1));
2006-09-28 06:53:42 +08:00
}
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
if (!parameters->options().nmagic()
&& !parameters->options().omagic())
off = align_file_offset(off, addr, abi_pagesize);
unsigned int shndx_hold = *pshndx;
uint64_t new_addr = (*p)->set_section_addresses(this, false, addr,
&off, pshndx);
2006-09-28 06:53:42 +08:00
// Now that we know the size of this segment, we may be able
// to save a page in memory, at the cost of wasting some
// file space, by instead aligning to the start of a new
// page. Here we use the real machine page size rather than
// the ABI mandated page size.
2008-02-04 13:43:05 +08:00
if (!are_addresses_set && aligned_addr != addr)
2006-09-28 06:53:42 +08:00
{
uint64_t first_off = (common_pagesize
- (aligned_addr
& (common_pagesize - 1)));
uint64_t last_off = new_addr & (common_pagesize - 1);
if (first_off > 0
&& last_off > 0
&& ((aligned_addr & ~ (common_pagesize - 1))
!= (new_addr & ~ (common_pagesize - 1)))
&& first_off + last_off <= common_pagesize)
{
*pshndx = shndx_hold;
addr = align_address(aligned_addr, common_pagesize);
2008-02-04 13:43:05 +08:00
addr = align_address(addr, (*p)->maximum_alignment());
2006-09-28 06:53:42 +08:00
off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1));
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 14:51:53 +08:00
off = align_file_offset(off, addr, abi_pagesize);
new_addr = (*p)->set_section_addresses(this, true, addr,
&off, pshndx);
2006-09-28 06:53:42 +08:00
}
}
addr = new_addr;
if (((*p)->flags() & elfcpp::PF_W) == 0)
was_readonly = true;
// Implement --check-sections. We know that the segments
// are sorted by LMA.
if (check_sections && last_load_segment != NULL)
{
gold_assert(last_load_segment->paddr() <= (*p)->paddr());
if (last_load_segment->paddr() + last_load_segment->memsz()
> (*p)->paddr())
{
unsigned long long lb1 = last_load_segment->paddr();
unsigned long long le1 = lb1 + last_load_segment->memsz();
unsigned long long lb2 = (*p)->paddr();
unsigned long long le2 = lb2 + (*p)->memsz();
gold_error(_("load segment overlap [0x%llx -> 0x%llx] and "
"[0x%llx -> 0x%llx]"),
lb1, le1, lb2, le2);
}
}
last_load_segment = *p;
2006-09-28 06:53:42 +08:00
}
}
// Handle the non-PT_LOAD segments, setting their offsets from their
// section's offsets.
for (Segment_list::iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
if ((*p)->type() != elfcpp::PT_LOAD)
(*p)->set_offset();
}
// Set the TLS offsets for each section in the PT_TLS segment.
if (this->tls_segment_ != NULL)
this->tls_segment_->set_tls_offsets();
2006-09-28 06:53:42 +08:00
return off;
}
2008-02-06 16:13:50 +08:00
// Set the offsets of all the allocated sections when doing a
// relocatable link. This does the same jobs as set_segment_offsets,
// only for a relocatable link.
off_t
Layout::set_relocatable_section_offsets(Output_data* file_header,
unsigned int *pshndx)
{
off_t off = 0;
file_header->set_address_and_file_offset(0, 0);
off += file_header->data_size();
for (Section_list::iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
// We skip unallocated sections here, except that group sections
// have to come first.
if (((*p)->flags() & elfcpp::SHF_ALLOC) == 0
&& (*p)->type() != elfcpp::SHT_GROUP)
continue;
off = align_address(off, (*p)->addralign());
// The linker script might have set the address.
if (!(*p)->is_address_valid())
(*p)->set_address(0);
(*p)->set_file_offset(off);
(*p)->finalize_data_size();
off += (*p)->data_size();
(*p)->set_out_shndx(*pshndx);
++*pshndx;
}
return off;
}
2006-09-28 06:53:42 +08:00
// Set the file offset of all the sections not associated with a
// segment.
off_t
Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
2006-09-28 06:53:42 +08:00
{
for (Section_list::iterator p = this->unattached_section_list_.begin();
p != this->unattached_section_list_.end();
2006-09-28 06:53:42 +08:00
++p)
{
// The symtab section is handled in create_symtab_sections.
if (*p == this->symtab_section_)
continue;
// If we've already set the data size, don't set it again.
if ((*p)->is_offset_valid() && (*p)->is_data_size_valid())
continue;
2007-12-01 14:34:12 +08:00
if (pass == BEFORE_INPUT_SECTIONS_PASS
&& (*p)->requires_postprocessing())
{
(*p)->create_postprocessing_buffer();
this->any_postprocessing_sections_ = true;
}
2007-12-01 14:34:12 +08:00
if (pass == BEFORE_INPUT_SECTIONS_PASS
&& (*p)->after_input_sections())
continue;
else if (pass == POSTPROCESSING_SECTIONS_PASS
&& (!(*p)->after_input_sections()
|| (*p)->type() == elfcpp::SHT_STRTAB))
continue;
else if (pass == STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS
&& (!(*p)->after_input_sections()
|| (*p)->type() != elfcpp::SHT_STRTAB))
continue;
off = align_address(off, (*p)->addralign());
(*p)->set_file_offset(off);
(*p)->finalize_data_size();
2006-09-28 06:53:42 +08:00
off += (*p)->data_size();
2007-12-01 14:34:12 +08:00
// At this point the name must be set.
if (pass != STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS)
2007-12-01 14:34:12 +08:00
this->namepool_.add((*p)->name(), false, NULL);
2006-09-28 06:53:42 +08:00
}
return off;
}
// Set the section indexes of all the sections not associated with a
// segment.
unsigned int
Layout::set_section_indexes(unsigned int shndx)
{
for (Section_list::iterator p = this->unattached_section_list_.begin();
p != this->unattached_section_list_.end();
++p)
{
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
if (!(*p)->has_out_shndx())
{
(*p)->set_out_shndx(shndx);
++shndx;
}
}
return shndx;
}
2008-02-04 13:43:05 +08:00
// Set the section addresses according to the linker script. This is
// only called when we see a SECTIONS clause. This returns the
// program segment which should hold the file header and segment
// headers, if any. It will return NULL if they should not be in a
// segment.
Output_segment*
Layout::set_section_addresses_from_script(Symbol_table* symtab)
{
Script_sections* ss = this->script_options_->script_sections();
gold_assert(ss->saw_sections_clause());
// Place each orphaned output section in the script.
for (Section_list::iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if (!(*p)->found_in_sections_clause())
ss->place_orphan(*p);
}
return this->script_options_->set_section_addresses(symtab, this);
}
// Count the local symbols in the regular symbol table and the dynamic
// symbol table, and build the respective string pools.
void
Layout::count_local_symbols(const Task* task,
const Input_objects* input_objects)
{
// First, figure out an upper bound on the number of symbols we'll
// be inserting into each pool. This helps us create the pools with
// the right size, to avoid unnecessary hashtable resizing.
unsigned int symbol_count = 0;
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
p != input_objects->relobj_end();
++p)
symbol_count += (*p)->local_symbol_count();
// Go from "upper bound" to "estimate." We overcount for two
// reasons: we double-count symbols that occur in more than one
// object file, and we count symbols that are dropped from the
// output. Add it all together and assume we overcount by 100%.
symbol_count /= 2;
// We assume all symbols will go into both the sympool and dynpool.
this->sympool_.reserve(symbol_count);
this->dynpool_.reserve(symbol_count);
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
p != input_objects->relobj_end();
++p)
{
Task_lock_obj<Object> tlo(task, *p);
(*p)->count_local_symbols(&this->sympool_, &this->dynpool_);
}
}
2007-05-17 01:42:48 +08:00
// Create the symbol table sections. Here we also set the final
// values of the symbols. At this point all the loadable sections are
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
// fully laid out. SHNUM is the number of sections so far.
2006-09-28 06:53:42 +08:00
void
2007-09-26 15:01:35 +08:00
Layout::create_symtab_sections(const Input_objects* input_objects,
2006-09-28 06:53:42 +08:00
Symbol_table* symtab,
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
unsigned int shnum,
2006-12-02 00:51:25 +08:00
off_t* poff)
2006-09-28 06:53:42 +08:00
{
int symsize;
unsigned int align;
if (parameters->target().get_size() == 32)
{
symsize = elfcpp::Elf_sizes<32>::sym_size;
align = 4;
}
else if (parameters->target().get_size() == 64)
{
symsize = elfcpp::Elf_sizes<64>::sym_size;
align = 8;
}
else
gold_unreachable();
off_t off = *poff;
off = align_address(off, align);
off_t startoff = off;
// Save space for the dummy symbol at the start of the section. We
// never bother to write this out--it will just be left as zero.
off += symsize;
unsigned int local_symbol_index = 1;
// Add STT_SECTION symbols for each Output section which needs one.
for (Section_list::iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if (!(*p)->needs_symtab_index())
(*p)->set_symtab_index(-1U);
else
{
(*p)->set_symtab_index(local_symbol_index);
++local_symbol_index;
off += symsize;
}
}
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
p != input_objects->relobj_end();
2006-09-28 06:53:42 +08:00
++p)
{
unsigned int index = (*p)->finalize_local_symbols(local_symbol_index,
off);
off += (index - local_symbol_index) * symsize;
local_symbol_index = index;
2006-09-28 06:53:42 +08:00
}
unsigned int local_symcount = local_symbol_index;
gold_assert(local_symcount * symsize == off - startoff);
2006-12-02 00:51:25 +08:00
off_t dynoff;
size_t dyn_global_index;
size_t dyncount;
if (this->dynsym_section_ == NULL)
{
dynoff = 0;
dyn_global_index = 0;
dyncount = 0;
}
else
{
dyn_global_index = this->dynsym_section_->info();
off_t locsize = dyn_global_index * this->dynsym_section_->entsize();
dynoff = this->dynsym_section_->offset() + locsize;
dyncount = (this->dynsym_section_->data_size() - locsize) / symsize;
gold_assert(static_cast<off_t>(dyncount * symsize)
2006-12-02 00:51:25 +08:00
== this->dynsym_section_->data_size() - locsize);
}
off = symtab->finalize(off, dynoff, dyn_global_index, dyncount,
&this->sympool_, &local_symcount);
2006-09-28 06:53:42 +08:00
if (!parameters->options().strip_all())
{
this->sympool_.set_string_offsets();
const char* symtab_name = this->namepool_.add(".symtab", false, NULL);
Output_section* osymtab = this->make_output_section(symtab_name,
elfcpp::SHT_SYMTAB,
0);
this->symtab_section_ = osymtab;
Output_section_data* pos = new Output_data_fixed_space(off - startoff,
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
align,
"** symtab");
osymtab->add_output_section_data(pos);
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
// We generate a .symtab_shndx section if we have more than
// SHN_LORESERVE sections. Technically it is possible that we
// don't need one, because it is possible that there are no
// symbols in any of sections with indexes larger than
// SHN_LORESERVE. That is probably unusual, though, and it is
// easier to always create one than to compute section indexes
// twice (once here, once when writing out the symbols).
if (shnum >= elfcpp::SHN_LORESERVE)
{
const char* symtab_xindex_name = this->namepool_.add(".symtab_shndx",
false, NULL);
Output_section* osymtab_xindex =
this->make_output_section(symtab_xindex_name,
elfcpp::SHT_SYMTAB_SHNDX, 0);
size_t symcount = (off - startoff) / symsize;
this->symtab_xindex_ = new Output_symtab_xindex(symcount);
osymtab_xindex->add_output_section_data(this->symtab_xindex_);
osymtab_xindex->set_link_section(osymtab);
osymtab_xindex->set_addralign(4);
osymtab_xindex->set_entsize(4);
osymtab_xindex->set_after_input_sections();
// This tells the driver code to wait until the symbol table
// has written out before writing out the postprocessing
// sections, including the .symtab_shndx section.
this->any_postprocessing_sections_ = true;
}
const char* strtab_name = this->namepool_.add(".strtab", false, NULL);
Output_section* ostrtab = this->make_output_section(strtab_name,
elfcpp::SHT_STRTAB,
0);
Output_section_data* pstr = new Output_data_strtab(&this->sympool_);
ostrtab->add_output_section_data(pstr);
osymtab->set_file_offset(startoff);
osymtab->finalize_data_size();
osymtab->set_link_section(ostrtab);
osymtab->set_info(local_symcount);
osymtab->set_entsize(symsize);
*poff = off;
}
2006-09-28 06:53:42 +08:00
}
// Create the .shstrtab section, which holds the names of the
// sections. At the time this is called, we have created all the
// output sections except .shstrtab itself.
Output_section*
Layout::create_shstrtab()
{
// FIXME: We don't need to create a .shstrtab section if we are
// stripping everything.
const char* name = this->namepool_.add(".shstrtab", false, NULL);
2006-09-28 06:53:42 +08:00
Output_section* os = this->make_output_section(name, elfcpp::SHT_STRTAB, 0);
2006-09-28 06:53:42 +08:00
// We can't write out this section until we've set all the section
// names, and we don't set the names of compressed output sections
// until relocations are complete.
os->set_after_input_sections();
Output_section_data* posd = new Output_data_strtab(&this->namepool_);
os->add_output_section_data(posd);
2006-09-28 06:53:42 +08:00
return os;
}
// Create the section headers. SIZE is 32 or 64. OFF is the file
// offset.
void
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
Layout::create_shdrs(const Output_section* shstrtab_section, off_t* poff)
2006-09-28 06:53:42 +08:00
{
Output_section_headers* oshdrs;
2007-09-26 15:01:35 +08:00
oshdrs = new Output_section_headers(this,
2006-12-02 00:51:25 +08:00
&this->segment_list_,
2008-02-06 16:13:50 +08:00
&this->section_list_,
2006-12-02 00:51:25 +08:00
&this->unattached_section_list_,
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
&this->namepool_,
shstrtab_section);
off_t off = align_address(*poff, oshdrs->addralign());
oshdrs->set_address_and_file_offset(0, off);
off += oshdrs->data_size();
*poff = off;
this->section_headers_ = oshdrs;
2006-09-27 05:00:34 +08:00
}
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
// Count the allocated sections.
size_t
Layout::allocated_output_section_count() const
{
size_t section_count = 0;
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
section_count += (*p)->output_section_count();
return section_count;
}
// Create the dynamic symbol table.
void
Layout::create_dynamic_symtab(const Input_objects* input_objects,
Symbol_table* symtab,
2006-12-06 08:02:36 +08:00
Output_section **pdynstr,
unsigned int* plocal_dynamic_count,
std::vector<Symbol*>* pdynamic_symbols,
Versions* pversions)
{
// Count all the symbols in the dynamic symbol table, and set the
// dynamic symbol indexes.
// Skip symbol 0, which is always all zeroes.
unsigned int index = 1;
// Add STT_SECTION symbols for each Output section which needs one.
for (Section_list::iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if (!(*p)->needs_dynsym_index())
(*p)->set_dynsym_index(-1U);
else
{
(*p)->set_dynsym_index(index);
++index;
}
}
// Count the local symbols that need to go in the dynamic symbol table,
// and set the dynamic symbol indexes.
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
p != input_objects->relobj_end();
++p)
{
unsigned int new_index = (*p)->set_local_dynsym_indexes(index);
index = new_index;
}
unsigned int local_symcount = index;
2006-12-06 08:02:36 +08:00
*plocal_dynamic_count = local_symcount;
index = symtab->set_dynsym_indexes(index, pdynamic_symbols,
2007-10-23 13:05:48 +08:00
&this->dynpool_, pversions);
int symsize;
unsigned int align;
const int size = parameters->target().get_size();
if (size == 32)
{
symsize = elfcpp::Elf_sizes<32>::sym_size;
align = 4;
}
else if (size == 64)
{
symsize = elfcpp::Elf_sizes<64>::sym_size;
align = 8;
}
else
gold_unreachable();
2006-12-06 08:02:36 +08:00
// Create the dynamic symbol table section.
Output_section* dynsym = this->choose_output_section(NULL, ".dynsym",
elfcpp::SHT_DYNSYM,
elfcpp::SHF_ALLOC,
false);
Output_section_data* odata = new Output_data_fixed_space(index * symsize,
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
align,
"** dynsym");
dynsym->add_output_section_data(odata);
dynsym->set_info(local_symcount);
dynsym->set_entsize(symsize);
dynsym->set_addralign(align);
this->dynsym_section_ = dynsym;
2006-12-02 00:51:25 +08:00
Output_data_dynamic* const odyn = this->dynamic_data_;
odyn->add_section_address(elfcpp::DT_SYMTAB, dynsym);
odyn->add_constant(elfcpp::DT_SYMENT, symsize);
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
// If there are more than SHN_LORESERVE allocated sections, we
// create a .dynsym_shndx section. It is possible that we don't
// need one, because it is possible that there are no dynamic
// symbols in any of the sections with indexes larger than
// SHN_LORESERVE. This is probably unusual, though, and at this
// time we don't know the actual section indexes so it is
// inconvenient to check.
if (this->allocated_output_section_count() >= elfcpp::SHN_LORESERVE)
{
Output_section* dynsym_xindex =
this->choose_output_section(NULL, ".dynsym_shndx",
elfcpp::SHT_SYMTAB_SHNDX,
elfcpp::SHF_ALLOC,
false);
this->dynsym_xindex_ = new Output_symtab_xindex(index);
dynsym_xindex->add_output_section_data(this->dynsym_xindex_);
dynsym_xindex->set_link_section(dynsym);
dynsym_xindex->set_addralign(4);
dynsym_xindex->set_entsize(4);
dynsym_xindex->set_after_input_sections();
// This tells the driver code to wait until the symbol table has
// written out before writing out the postprocessing sections,
// including the .dynsym_shndx section.
this->any_postprocessing_sections_ = true;
}
2006-12-06 08:02:36 +08:00
// Create the dynamic string table section.
Output_section* dynstr = this->choose_output_section(NULL, ".dynstr",
elfcpp::SHT_STRTAB,
elfcpp::SHF_ALLOC,
false);
Output_section_data* strdata = new Output_data_strtab(&this->dynpool_);
dynstr->add_output_section_data(strdata);
2006-12-02 00:51:25 +08:00
dynsym->set_link_section(dynstr);
this->dynamic_section_->set_link_section(dynstr);
odyn->add_section_address(elfcpp::DT_STRTAB, dynstr);
odyn->add_section_size(elfcpp::DT_STRSZ, dynstr);
2006-12-06 08:02:36 +08:00
*pdynstr = dynstr;
// Create the hash tables.
2008-03-06 08:15:04 +08:00
if (strcmp(parameters->options().hash_style(), "sysv") == 0
|| strcmp(parameters->options().hash_style(), "both") == 0)
{
unsigned char* phash;
unsigned int hashlen;
Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen);
Output_section* hashsec = this->choose_output_section(NULL, ".hash",
elfcpp::SHT_HASH,
elfcpp::SHF_ALLOC,
false);
Output_section_data* hashdata = new Output_data_const_buffer(phash,
hashlen,
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
align,
"** hash");
2008-03-06 08:15:04 +08:00
hashsec->add_output_section_data(hashdata);
hashsec->set_link_section(dynsym);
hashsec->set_entsize(4);
2008-03-06 08:15:04 +08:00
odyn->add_section_address(elfcpp::DT_HASH, hashsec);
}
if (strcmp(parameters->options().hash_style(), "gnu") == 0
|| strcmp(parameters->options().hash_style(), "both") == 0)
{
unsigned char* phash;
unsigned int hashlen;
Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen);
2008-03-06 08:15:04 +08:00
Output_section* hashsec = this->choose_output_section(NULL, ".gnu.hash",
elfcpp::SHT_GNU_HASH,
elfcpp::SHF_ALLOC,
false);
2008-03-06 08:15:04 +08:00
Output_section_data* hashdata = new Output_data_const_buffer(phash,
hashlen,
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
align,
"** hash");
2008-03-06 08:15:04 +08:00
hashsec->add_output_section_data(hashdata);
2008-03-06 08:15:04 +08:00
hashsec->set_link_section(dynsym);
hashsec->set_entsize(4);
2008-03-06 08:15:04 +08:00
odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
}
}
// Assign offsets to each local portion of the dynamic symbol table.
void
Layout::assign_local_dynsym_offsets(const Input_objects* input_objects)
{
Output_section* dynsym = this->dynsym_section_;
gold_assert(dynsym != NULL);
off_t off = dynsym->offset();
// Skip the dummy symbol at the start of the section.
off += dynsym->entsize();
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
p != input_objects->relobj_end();
++p)
{
unsigned int count = (*p)->set_local_dynsym_offset(off);
off += count * dynsym->entsize();
}
}
2006-12-06 08:02:36 +08:00
// Create the version sections.
void
2007-09-26 15:01:35 +08:00
Layout::create_version_sections(const Versions* versions,
2007-10-23 07:08:22 +08:00
const Symbol_table* symtab,
2006-12-06 08:02:36 +08:00
unsigned int local_symcount,
const std::vector<Symbol*>& dynamic_symbols,
const Output_section* dynstr)
{
if (!versions->any_defs() && !versions->any_needs())
return;
switch (parameters->size_and_endianness())
2006-12-06 08:02:36 +08:00
{
#ifdef HAVE_TARGET_32_LITTLE
case Parameters::TARGET_32_LITTLE:
2008-03-01 03:19:17 +08:00
this->sized_create_version_sections<32, false>(versions, symtab,
local_symcount,
dynamic_symbols, dynstr);
break;
#endif
#ifdef HAVE_TARGET_32_BIG
case Parameters::TARGET_32_BIG:
2008-03-01 03:19:17 +08:00
this->sized_create_version_sections<32, true>(versions, symtab,
local_symcount,
dynamic_symbols, dynstr);
break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
case Parameters::TARGET_64_LITTLE:
2008-03-01 03:19:17 +08:00
this->sized_create_version_sections<64, false>(versions, symtab,
local_symcount,
dynamic_symbols, dynstr);
break;
#endif
#ifdef HAVE_TARGET_64_BIG
case Parameters::TARGET_64_BIG:
2008-03-01 03:19:17 +08:00
this->sized_create_version_sections<64, true>(versions, symtab,
local_symcount,
dynamic_symbols, dynstr);
break;
#endif
default:
gold_unreachable();
2006-12-06 08:02:36 +08:00
}
}
// Create the version sections, sized version.
template<int size, bool big_endian>
void
Layout::sized_create_version_sections(
const Versions* versions,
2007-10-23 07:08:22 +08:00
const Symbol_table* symtab,
2006-12-06 08:02:36 +08:00
unsigned int local_symcount,
const std::vector<Symbol*>& dynamic_symbols,
2008-03-01 03:19:17 +08:00
const Output_section* dynstr)
2006-12-06 08:02:36 +08:00
{
Output_section* vsec = this->choose_output_section(NULL, ".gnu.version",
elfcpp::SHT_GNU_versym,
elfcpp::SHF_ALLOC,
false);
2006-12-06 08:02:36 +08:00
unsigned char* vbuf;
unsigned int vsize;
2008-03-01 03:19:17 +08:00
versions->symbol_section_contents<size, big_endian>(symtab, &this->dynpool_,
local_symcount,
dynamic_symbols,
&vbuf, &vsize);
2006-12-06 08:02:36 +08:00
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
Output_section_data* vdata = new Output_data_const_buffer(vbuf, vsize, 2,
"** versions");
2006-12-06 08:02:36 +08:00
vsec->add_output_section_data(vdata);
vsec->set_entsize(2);
vsec->set_link_section(this->dynsym_section_);
Output_data_dynamic* const odyn = this->dynamic_data_;
odyn->add_section_address(elfcpp::DT_VERSYM, vsec);
if (versions->any_defs())
{
Output_section* vdsec;
vdsec= this->choose_output_section(NULL, ".gnu.version_d",
elfcpp::SHT_GNU_verdef,
elfcpp::SHF_ALLOC,
false);
2006-12-06 08:02:36 +08:00
unsigned char* vdbuf;
unsigned int vdsize;
unsigned int vdentries;
2008-03-01 03:19:17 +08:00
versions->def_section_contents<size, big_endian>(&this->dynpool_, &vdbuf,
&vdsize, &vdentries);
2006-12-06 08:02:36 +08:00
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
Output_section_data* vddata =
new Output_data_const_buffer(vdbuf, vdsize, 4, "** version defs");
2006-12-06 08:02:36 +08:00
vdsec->add_output_section_data(vddata);
vdsec->set_link_section(dynstr);
vdsec->set_info(vdentries);
odyn->add_section_address(elfcpp::DT_VERDEF, vdsec);
odyn->add_constant(elfcpp::DT_VERDEFNUM, vdentries);
}
if (versions->any_needs())
{
Output_section* vnsec;
vnsec = this->choose_output_section(NULL, ".gnu.version_r",
elfcpp::SHT_GNU_verneed,
elfcpp::SHF_ALLOC,
false);
2006-12-06 08:02:36 +08:00
unsigned char* vnbuf;
unsigned int vnsize;
unsigned int vnentries;
2008-03-01 03:19:17 +08:00
versions->need_section_contents<size, big_endian>(&this->dynpool_,
&vnbuf, &vnsize,
&vnentries);
2006-12-06 08:02:36 +08:00
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
Output_section_data* vndata =
new Output_data_const_buffer(vnbuf, vnsize, 4, "** version refs");
2006-12-06 08:02:36 +08:00
vnsec->add_output_section_data(vndata);
vnsec->set_link_section(dynstr);
vnsec->set_info(vnentries);
odyn->add_section_address(elfcpp::DT_VERNEED, vnsec);
odyn->add_constant(elfcpp::DT_VERNEEDNUM, vnentries);
}
}
// Create the .interp section and PT_INTERP segment.
void
Layout::create_interp(const Target* target)
{
const char* interp = parameters->options().dynamic_linker();
if (interp == NULL)
{
interp = target->dynamic_linker();
gold_assert(interp != NULL);
}
size_t len = strlen(interp) + 1;
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);
osec->add_output_section_data(odata);
2008-02-05 06:54:31 +08:00
if (!this->script_options_->saw_phdrs_clause())
{
Output_segment* oseg = this->make_output_segment(elfcpp::PT_INTERP,
elfcpp::PF_R);
oseg->add_output_section(osec, elfcpp::PF_R);
2008-02-05 06:54:31 +08:00
}
}
// Finish the .dynamic section and PT_DYNAMIC segment.
void
Layout::finish_dynamic_section(const Input_objects* input_objects,
2006-12-02 00:51:25 +08:00
const Symbol_table* symtab)
{
2008-02-05 06:54:31 +08:00
if (!this->script_options_->saw_phdrs_clause())
{
Output_segment* oseg = this->make_output_segment(elfcpp::PT_DYNAMIC,
(elfcpp::PF_R
| elfcpp::PF_W));
oseg->add_output_section(this->dynamic_section_,
elfcpp::PF_R | elfcpp::PF_W);
2008-02-05 06:54:31 +08:00
}
2006-12-02 00:51:25 +08:00
Output_data_dynamic* const odyn = this->dynamic_data_;
for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
p != input_objects->dynobj_end();
++p)
{
// FIXME: Handle --as-needed.
odyn->add_string(elfcpp::DT_NEEDED, (*p)->soname());
}
if (parameters->options().shared())
2008-01-04 13:35:24 +08:00
{
const char* soname = parameters->options().soname();
2008-01-04 13:35:24 +08:00
if (soname != NULL)
odyn->add_string(elfcpp::DT_SONAME, soname);
}
// FIXME: Support --init and --fini.
Symbol* sym = symtab->lookup("_init");
2006-12-06 08:02:36 +08:00
if (sym != NULL && sym->is_defined() && !sym->is_from_dynobj())
odyn->add_symbol(elfcpp::DT_INIT, sym);
sym = symtab->lookup("_fini");
2006-12-06 08:02:36 +08:00
if (sym != NULL && sym->is_defined() && !sym->is_from_dynobj())
odyn->add_symbol(elfcpp::DT_FINI, sym);
// FIXME: Support DT_INIT_ARRAY and DT_FINI_ARRAY.
2007-08-22 04:37:32 +08:00
// Add a DT_RPATH entry if needed.
const General_options::Dir_list& rpath(parameters->options().rpath());
2007-08-22 04:37:32 +08:00
if (!rpath.empty())
{
std::string rpath_val;
for (General_options::Dir_list::const_iterator p = rpath.begin();
p != rpath.end();
++p)
{
if (rpath_val.empty())
2007-10-04 13:49:04 +08:00
rpath_val = p->name();
2007-08-22 04:37:32 +08:00
else
{
// Eliminate duplicates.
General_options::Dir_list::const_iterator q;
for (q = rpath.begin(); q != p; ++q)
2007-10-04 13:49:04 +08:00
if (q->name() == p->name())
2007-08-22 04:37:32 +08:00
break;
if (q == p)
{
rpath_val += ':';
2007-10-04 13:49:04 +08:00
rpath_val += p->name();
2007-08-22 04:37:32 +08:00
}
}
}
odyn->add_string(elfcpp::DT_RPATH, rpath_val);
if (parameters->options().enable_new_dtags())
odyn->add_string(elfcpp::DT_RUNPATH, rpath_val);
2007-08-22 04:37:32 +08:00
}
// Look for text segments that have dynamic relocations.
bool have_textrel = false;
if (!this->script_options_->saw_sections_clause())
{
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
if (((*p)->flags() & elfcpp::PF_W) == 0
&& (*p)->dynamic_reloc_count() > 0)
{
have_textrel = true;
break;
}
}
}
else
{
// We don't know the section -> segment mapping, so we are
// conservative and just look for readonly sections with
// relocations. If those sections wind up in writable segments,
// then we have created an unnecessary DT_TEXTREL entry.
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0
&& ((*p)->flags() & elfcpp::SHF_WRITE) == 0
&& ((*p)->dynamic_reloc_count() > 0))
{
have_textrel = true;
break;
}
}
}
// Add a DT_FLAGS entry. We add it even if no flags are set so that
// post-link tools can easily modify these flags if desired.
unsigned int flags = 0;
if (have_textrel)
{
// Add a DT_TEXTREL for compatibility with older loaders.
odyn->add_constant(elfcpp::DT_TEXTREL, 0);
flags |= elfcpp::DF_TEXTREL;
}
if (parameters->options().shared() && this->has_static_tls())
flags |= elfcpp::DF_STATIC_TLS;
if (parameters->options().origin())
flags |= elfcpp::DF_ORIGIN;
if (parameters->options().now())
flags |= elfcpp::DF_BIND_NOW;
odyn->add_constant(elfcpp::DT_FLAGS, flags);
flags = 0;
if (parameters->options().initfirst())
flags |= elfcpp::DF_1_INITFIRST;
if (parameters->options().interpose())
flags |= elfcpp::DF_1_INTERPOSE;
if (parameters->options().loadfltr())
flags |= elfcpp::DF_1_LOADFLTR;
if (parameters->options().nodefaultlib())
flags |= elfcpp::DF_1_NODEFLIB;
if (parameters->options().nodelete())
flags |= elfcpp::DF_1_NODELETE;
if (parameters->options().nodlopen())
flags |= elfcpp::DF_1_NOOPEN;
if (parameters->options().nodump())
flags |= elfcpp::DF_1_NODUMP;
if (!parameters->options().shared())
flags &= ~(elfcpp::DF_1_INITFIRST
| elfcpp::DF_1_NODELETE
| elfcpp::DF_1_NOOPEN);
if (parameters->options().origin())
flags |= elfcpp::DF_1_ORIGIN;
if (parameters->options().now())
flags |= elfcpp::DF_1_NOW;
if (flags)
odyn->add_constant(elfcpp::DT_FLAGS_1, flags);
}
// The mapping of input section name prefixes to output section names.
// In some cases one prefix is itself a prefix of another prefix; in
// such a case the longer prefix must come first. These prefixes are
// based on the GNU linker default ELF linker script.
#define MAPPING_INIT(f, t) { f, sizeof(f) - 1, t, sizeof(t) - 1 }
const Layout::Section_name_mapping Layout::section_name_mapping[] =
{
MAPPING_INIT(".text.", ".text"),
MAPPING_INIT(".ctors.", ".ctors"),
MAPPING_INIT(".dtors.", ".dtors"),
MAPPING_INIT(".rodata.", ".rodata"),
MAPPING_INIT(".data.rel.ro.local", ".data.rel.ro.local"),
MAPPING_INIT(".data.rel.ro", ".data.rel.ro"),
MAPPING_INIT(".data.", ".data"),
MAPPING_INIT(".bss.", ".bss"),
MAPPING_INIT(".tdata.", ".tdata"),
MAPPING_INIT(".tbss.", ".tbss"),
MAPPING_INIT(".init_array.", ".init_array"),
MAPPING_INIT(".fini_array.", ".fini_array"),
MAPPING_INIT(".sdata.", ".sdata"),
MAPPING_INIT(".sbss.", ".sbss"),
// FIXME: In the GNU linker, .sbss2 and .sdata2 are handled
// differently depending on whether it is creating a shared library.
MAPPING_INIT(".sdata2.", ".sdata"),
MAPPING_INIT(".sbss2.", ".sbss"),
MAPPING_INIT(".lrodata.", ".lrodata"),
MAPPING_INIT(".ldata.", ".ldata"),
MAPPING_INIT(".lbss.", ".lbss"),
MAPPING_INIT(".gcc_except_table.", ".gcc_except_table"),
MAPPING_INIT(".gnu.linkonce.d.rel.ro.local.", ".data.rel.ro.local"),
MAPPING_INIT(".gnu.linkonce.d.rel.ro.", ".data.rel.ro"),
MAPPING_INIT(".gnu.linkonce.t.", ".text"),
MAPPING_INIT(".gnu.linkonce.r.", ".rodata"),
MAPPING_INIT(".gnu.linkonce.d.", ".data"),
MAPPING_INIT(".gnu.linkonce.b.", ".bss"),
MAPPING_INIT(".gnu.linkonce.s.", ".sdata"),
MAPPING_INIT(".gnu.linkonce.sb.", ".sbss"),
MAPPING_INIT(".gnu.linkonce.s2.", ".sdata"),
MAPPING_INIT(".gnu.linkonce.sb2.", ".sbss"),
MAPPING_INIT(".gnu.linkonce.wi.", ".debug_info"),
MAPPING_INIT(".gnu.linkonce.td.", ".tdata"),
MAPPING_INIT(".gnu.linkonce.tb.", ".tbss"),
MAPPING_INIT(".gnu.linkonce.lr.", ".lrodata"),
MAPPING_INIT(".gnu.linkonce.l.", ".ldata"),
MAPPING_INIT(".gnu.linkonce.lb.", ".lbss"),
MAPPING_INIT(".ARM.extab.", ".ARM.extab"),
MAPPING_INIT(".gnu.linkonce.armextab.", ".ARM.extab"),
MAPPING_INIT(".ARM.exidx.", ".ARM.exidx"),
MAPPING_INIT(".gnu.linkonce.armexidx.", ".ARM.exidx"),
};
#undef MAPPING_INIT
const int Layout::section_name_mapping_count =
(sizeof(Layout::section_name_mapping)
/ sizeof(Layout::section_name_mapping[0]));
// Choose the output section name to use given an input section name.
// Set *PLEN to the length of the name. *PLEN is initialized to the
// length of NAME.
const char*
Layout::output_section_name(const char* name, size_t* plen)
{
// gcc 4.3 generates the following sorts of section names when it
// needs a section name specific to a function:
// .text.FN
// .rodata.FN
// .sdata2.FN
// .data.FN
// .data.rel.FN
// .data.rel.local.FN
// .data.rel.ro.FN
// .data.rel.ro.local.FN
// .sdata.FN
// .bss.FN
// .sbss.FN
// .tdata.FN
// .tbss.FN
// The GNU linker maps all of those to the part before the .FN,
// except that .data.rel.local.FN is mapped to .data, and
// .data.rel.ro.local.FN is mapped to .data.rel.ro. The sections
// beginning with .data.rel.ro.local are grouped together.
// For an anonymous namespace, the string FN can contain a '.'.
// Also of interest: .rodata.strN.N, .rodata.cstN, both of which the
// GNU linker maps to .rodata.
// The .data.rel.ro sections are used with -z relro. The sections
// are recognized by name. We use the same names that the GNU
// linker does for these sections.
// It is hard to handle this in a principled way, so we don't even
// try. We use a table of mappings. If the input section name is
// not found in the table, we simply use it as the output section
// name.
const Section_name_mapping* psnm = section_name_mapping;
for (int i = 0; i < section_name_mapping_count; ++i, ++psnm)
{
if (strncmp(name, psnm->from, psnm->fromlen) == 0)
{
*plen = psnm->tolen;
return psnm->to;
}
}
return name;
}
// Check if a comdat group or .gnu.linkonce section with the given
// NAME is selected for the link. If there is already a section,
// *KEPT_SECTION is set to point to the signature and the function
// returns false. Otherwise, the CANDIDATE signature is recorded for
// this NAME in the layout object, *KEPT_SECTION is set to the
// internal copy and the function return false. In some cases, with
// CANDIDATE->GROUP_ being false, KEPT_SECTION can point back to
// CANDIDATE.
bool
Layout::find_or_add_kept_section(const std::string& name,
Kept_section* candidate,
Kept_section** kept_section)
{
// It's normal to see a couple of entries here, for the x86 thunk
// sections. If we see more than a few, we're linking a C++
// program, and we resize to get more space to minimize rehashing.
if (this->signatures_.size() > 4
&& !this->resized_signatures_)
{
reserve_unordered_map(&this->signatures_,
this->number_of_input_files_ * 64);
this->resized_signatures_ = true;
}
std::pair<Signatures::iterator, bool> ins(
this->signatures_.insert(std::make_pair(name, *candidate)));
if (kept_section)
*kept_section = &ins.first->second;
if (ins.second)
{
// This is the first time we've seen this signature.
return true;
}
if (ins.first->second.is_group)
{
// We've already seen a real section group with this signature.
// If the kept group is from a plugin object, and we're in
// the replacement phase, accept the new one as a replacement.
if (ins.first->second.object == NULL
&& parameters->options().plugins()->in_replacement_phase())
{
ins.first->second = *candidate;
return true;
}
return false;
}
else if (candidate->is_group)
{
// This is a real section group, and we've already seen a
2007-09-24 03:50:33 +08:00
// linkonce section with this signature. Record that we've seen
// a section group, and don't include this section group.
ins.first->second.is_group = true;
return false;
}
else
{
// We've already seen a linkonce section and this is a linkonce
// section. These don't block each other--this may be the same
// symbol name with different section types.
*kept_section = candidate;
return true;
}
}
* layout.cc (Layout::include_section): Refactored check for debug info section. (Layout::add_comdat): Add new parameters. Change type of signature parameter. Add object and shndx to signatures table. (Layout::find_kept_object): New function. * layout.h: Include <cstring>. (Layout::is_debug_info_section): New function. (Layout::add_comdat): Add new parameters. (Layout::find_kept_object): New function. (Layout::Kept_section): New struct. (Layout::Signatures): Change type of map range. * object.cc (Relobj::output_section_address): New function. (Sized_relobj::include_section_group): Add new parameters. Change calls to Layout::add_comdat. Change to build table of kept comdat groups and table mapping discarded sections to kept sections. (Sized_relobj::include_linkonce_section): Likewise. Add new parameter. (Sized_relobj::do_layout): Change calls to include_section_group and include_linkonce_section. (Sized_relobj::do_finalize_local_symbols): Do not set local symbol value to zero when section is discarded. (Sized_relobj::map_to_kept_section): New function. * object.h (Relobj::output_section_address): New function. (Relobj::Comdat_group): New type. (Relobj::find_comdat_group): New function. (Relobj::Comdat_group_table): New type. (Relobj::Kept_comdat_section): New type. (Relobj::Kept_comdat_section_table): New type. (Relobj::add_comdat_group): New function. (Relobj::set_kept_comdat_section): New function. (Relobj::get_kept_comdat_section): New function. (Relobj::comdat_groups_): New field. (Relobj::kept_comdat_sections_): New field. (Symbol_value::input_value): Update comment. (Sized_relobj::map_to_kept_section) New function. (Sized_relobj::include_linkonce_section): Add new parameter. * target-reloc.h (Comdat_behavior): New type. (get_comdat_behavior): New function. (relocate_section): Add code to map a discarded section to the corresponding kept section when applying a relocation.
2008-05-01 09:23:21 +08:00
// Find the given comdat signature, and return the object and section
// index of the kept group.
Relobj*
Layout::find_kept_object(const std::string& signature,
unsigned int* pshndx) const
{
Signatures::const_iterator p = this->signatures_.find(signature);
if (p == this->signatures_.end())
return NULL;
if (pshndx != NULL)
*pshndx = p->second.shndx;
return p->second.object;
* layout.cc (Layout::include_section): Refactored check for debug info section. (Layout::add_comdat): Add new parameters. Change type of signature parameter. Add object and shndx to signatures table. (Layout::find_kept_object): New function. * layout.h: Include <cstring>. (Layout::is_debug_info_section): New function. (Layout::add_comdat): Add new parameters. (Layout::find_kept_object): New function. (Layout::Kept_section): New struct. (Layout::Signatures): Change type of map range. * object.cc (Relobj::output_section_address): New function. (Sized_relobj::include_section_group): Add new parameters. Change calls to Layout::add_comdat. Change to build table of kept comdat groups and table mapping discarded sections to kept sections. (Sized_relobj::include_linkonce_section): Likewise. Add new parameter. (Sized_relobj::do_layout): Change calls to include_section_group and include_linkonce_section. (Sized_relobj::do_finalize_local_symbols): Do not set local symbol value to zero when section is discarded. (Sized_relobj::map_to_kept_section): New function. * object.h (Relobj::output_section_address): New function. (Relobj::Comdat_group): New type. (Relobj::find_comdat_group): New function. (Relobj::Comdat_group_table): New type. (Relobj::Kept_comdat_section): New type. (Relobj::Kept_comdat_section_table): New type. (Relobj::add_comdat_group): New function. (Relobj::set_kept_comdat_section): New function. (Relobj::get_kept_comdat_section): New function. (Relobj::comdat_groups_): New field. (Relobj::kept_comdat_sections_): New field. (Symbol_value::input_value): Update comment. (Sized_relobj::map_to_kept_section) New function. (Sized_relobj::include_linkonce_section): Add new parameter. * target-reloc.h (Comdat_behavior): New type. (get_comdat_behavior): New function. (relocate_section): Add code to map a discarded section to the corresponding kept section when applying a relocation.
2008-05-01 09:23:21 +08:00
}
2008-02-04 13:43:05 +08:00
// Store the allocated sections into the section list.
void
Layout::get_allocated_sections(Section_list* section_list) const
{
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0)
section_list->push_back(*p);
}
// Create an output segment.
Output_segment*
Layout::make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
{
gold_assert(!parameters->options().relocatable());
2008-02-04 13:43:05 +08:00
Output_segment* oseg = new Output_segment(type, flags);
this->segment_list_.push_back(oseg);
* layout.cc (Layout::attach_allocated_section_to_segment): Don't set tls_segment_ or relro_segment_. (Layout::make_output_segment): Set tls_segment_ and relro_segment_ when appropriate. * output.h (Output_section::clear_is_relro): New function. * output.cc (Output_segment::add_output_section): Handle SHF_TLS sections specially even when output_data_ is empty. (Output_segment::maximum_alignment): When first section is relro, only force alignment for PT_LOAD segments. * script.cc (script_data_segment_align): New function. (script_data_segment_relro_end): New function. * script-c.h (script_data_segment_align): Declare. (script_data_segment_relro_end): Declare. * script-sections.h (class Script_sections): Declare data_segment_align and data_segment_relro_end. Add fields segment_align_index_ and saw_relro_end_. * script-sections.cc (class Sections_element): Add set_is_relro virtual function. Add new bool* parameter to place_orphan_here. Add get_output_section virtual function. (class Output_section_definition): Add set_is_relro. Add new bool* parameter to place_orphan_here. Add get_output_section. Add is_relro_ field. (Output_section_definition::Output_section_definition): Initialize evaluated_address_, evaluated_load_address, evaluated_addralign_, and is_relro_ fields. (Output_section_definition::place_orphan_here): Add is_relro parameter. (Output_section_definition::set_section_addresses): Set relro for output section. (Output_section_definition::alternate_constraint): Likewise. (class Orphan_output_section): Add new bool* parameter to place_orphan_here. Add get_output_section. (Orphan_output_section::place_orphan_here): Add is_relro parameter. (Script_sections::Script_sections): Initialize data_segment_align_index_ and saw_relro_end_. (Script_sections::data_segment_align): New function. (Script_sections::data_segment_relro_end): New function. (Script_sections::place_orphan): Set or clear is_relro. (Script_sections::set_section_addresses): Force alignment of first TLS section. * yyscript.y (exp): Call script_data_segment_align and script_data_segment_relro_end. * testsuite/relro_script_test.t: New file. * testsuite/relro_test.cc (using_script): Declare. (t1, t2): Test using_script. * testsuite/Makefile.am (check_PROGRAMS): Add relro_script_test. (relro_script_test_SOURCES): Define. (relro_script_test_DEPENDENCIES): Define. (relro_script_test_LDFLAGS): Define. (relro_script_test_LDADD): Define. (relro_script_test.so): New target. * testsuite/Makefile.in: Rebuild.
2008-08-13 15:37:46 +08:00
if (type == elfcpp::PT_TLS)
this->tls_segment_ = oseg;
else if (type == elfcpp::PT_GNU_RELRO)
this->relro_segment_ = oseg;
2008-02-04 13:43:05 +08:00
return oseg;
}
// Write out the Output_sections. Most won't have anything to write,
// since most of the data will come from input sections which are
// handled elsewhere. But some Output_sections do have Output_data.
void
Layout::write_output_sections(Output_file* of) const
{
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if (!(*p)->after_input_sections())
(*p)->write(of);
}
}
// Write out data not associated with a section or the symbol table.
void
2007-09-26 15:01:35 +08:00
Layout::write_data(const Symbol_table* symtab, Output_file* of) const
{
if (!parameters->options().strip_all())
{
const Output_section* symtab_section = this->symtab_section_;
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if ((*p)->needs_symtab_index())
{
gold_assert(symtab_section != NULL);
unsigned int index = (*p)->symtab_index();
gold_assert(index > 0 && index != -1U);
off_t off = (symtab_section->offset()
+ index * symtab_section->entsize());
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
symtab->write_section_symbol(*p, this->symtab_xindex_, of, off);
}
}
}
const Output_section* dynsym_section = this->dynsym_section_;
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if ((*p)->needs_dynsym_index())
{
gold_assert(dynsym_section != NULL);
unsigned int index = (*p)->dynsym_index();
gold_assert(index > 0 && index != -1U);
off_t off = (dynsym_section->offset()
+ index * dynsym_section->entsize());
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
symtab->write_section_symbol(*p, this->dynsym_xindex_, of, off);
}
}
// Write out the Output_data which are not in an Output_section.
for (Data_list::const_iterator p = this->special_output_list_.begin();
p != this->special_output_list_.end();
++p)
(*p)->write(of);
}
// Write out the Output_sections which can only be written after the
// input sections are complete.
void
Layout::write_sections_after_input_sections(Output_file* of)
{
// Determine the final section offsets, and thus the final output
// file size. Note we finalize the .shstrab last, to allow the
// after_input_section sections to modify their section-names before
// writing.
if (this->any_postprocessing_sections_)
{
off_t off = this->output_file_size_;
off = this->set_section_offsets(off, POSTPROCESSING_SECTIONS_PASS);
// Now that we've finalized the names, we can finalize the shstrab.
off =
this->set_section_offsets(off,
STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS);
if (off > this->output_file_size_)
{
of->resize(off);
this->output_file_size_ = off;
}
}
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
{
if ((*p)->after_input_sections())
(*p)->write(of);
}
this->section_headers_->write(of);
}
// If the build ID requires computing a checksum, do so here, and
// write it out. We compute a checksum over the entire file because
// that is simplest.
void
Layout::write_build_id(Output_file* of) const
{
if (this->build_id_note_ == NULL)
return;
const unsigned char* iv = of->get_input_view(0, this->output_file_size_);
unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
this->build_id_note_->data_size());
const char* style = parameters->options().build_id();
if (strcmp(style, "sha1") == 0)
{
sha1_ctx ctx;
sha1_init_ctx(&ctx);
sha1_process_bytes(iv, this->output_file_size_, &ctx);
sha1_finish_ctx(&ctx, ov);
}
else if (strcmp(style, "md5") == 0)
{
md5_ctx ctx;
md5_init_ctx(&ctx);
md5_process_bytes(iv, this->output_file_size_, &ctx);
md5_finish_ctx(&ctx, ov);
}
else
gold_unreachable();
of->write_output_view(this->build_id_note_->offset(),
this->build_id_note_->data_size(),
ov);
of->free_input_view(0, this->output_file_size_, iv);
}
2008-02-07 15:33:46 +08:00
// Write out a binary file. This is called after the link is
// complete. IN is the temporary output file we used to generate the
// ELF code. We simply walk through the segments, read them from
// their file offset in IN, and write them to their load address in
// the output file. FIXME: with a bit more work, we could support
// S-records and/or Intel hex format here.
void
Layout::write_binary(Output_file* in) const
{
gold_assert(parameters->options().oformat_enum()
== General_options::OBJECT_FORMAT_BINARY);
2008-02-07 15:33:46 +08:00
// Get the size of the binary file.
uint64_t max_load_address = 0;
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
if ((*p)->type() == elfcpp::PT_LOAD && (*p)->filesz() > 0)
{
uint64_t max_paddr = (*p)->paddr() + (*p)->filesz();
if (max_paddr > max_load_address)
max_load_address = max_paddr;
}
}
Output_file out(parameters->options().output_file_name());
2008-02-07 15:33:46 +08:00
out.open(max_load_address);
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
{
if ((*p)->type() == elfcpp::PT_LOAD && (*p)->filesz() > 0)
{
const unsigned char* vin = in->get_input_view((*p)->offset(),
(*p)->filesz());
unsigned char* vout = out.get_output_view((*p)->paddr(),
(*p)->filesz());
memcpy(vout, vin, (*p)->filesz());
out.write_output_view((*p)->paddr(), (*p)->filesz(), vout);
in->free_input_view((*p)->offset(), (*p)->filesz(), vin);
}
}
out.close();
}
* mapfile.cc: New file. * mapfile.h: New file. * options.h (class General_options): Add -M/--print-map and -Map. * options.cc (General_options::finalize): Make -M equivalent to -Map -. * main.cc: Include <cstdio> and "mapfile.h". (main): Open mapfile if requested. * gold.cc (class Middle_runner): Add mapfile_ field. Update constructor. Change caller. (queue_initial_tasks): Add mapfile parameter. Change caller. (queue_middle_tasks): Likewise. * gold.h (queue_initial_tasks, queue_middle_tasks): Update declarations. * archive.cc: Include "mapfile.h". (Archive::add_symbols): Add mapfile parameter. Change all callers. Pass mapfile, symbol, and reason to include_member. (Archive::include_all_members): Add mapfile parameter. Change all callers. (Archive::include_member): Add mapfile, sym, and why parameters. Change all callers. Report inclusion to map file. * archive.h: Include "fileread.h". (class Archive): Update declarations. (Archive::file): New const method. (class Add_archive_symbols): Add mapfile_ field. Update constructor. Change all callers. * readsyms.h (class Read_symbols): Likewise. (class Finish_group): Likewise. (class Read_script): Likewise. * common.cc: Include "mapfile.h". (Symbol_table::allocate_commons): Add mapfile parameter. Change all callers. (Symbol_table::do_allocate_commons): Likewise. (Symbol_table::do_allocate_commons_list): Likewise. Report common symbol allocation to mapfile. * common.h (class Allocate_commons_task): Add mapfile_ field. Update constructor. Change all callers. * symtab.h (class Symbol_table): Update declarations. * layout.cc: Include "mapfile.h". (Layout_task_runner::run): Print information to mapfile. (Layout::create_gold_note): Change Output_data_fixed_space to Output_data_zero_fill. (Layout::create_build_id): Likewise. (Layout::print_to_mapfile): New function. * layout.h (class Layout_task_runner): Add mapfile_ field. Update constructor. Change caller. (class Layout): Declare print_to_mapfile. * output.cc (Output_section::Input_section::print_to_mapfile): New function. (Output_section::add_input_section): If producing a map, always add to input_sections_ list. (Output_section::do_print_to_mapfile): New function. (Output_segment::print_sections_to_mapfile): New function. (Output_segment::print_section_list_to_mapfile): New function. * output.h: Include "mapfile.h". (Output_data::print_to_mapfile): New function. (Output_data::do_print_to_mapfile): New virtual function. (Output_segment_headers::do_print_to_mapfile): New function. (Output_file_header::do_print_to_mapfile): New function. (Output_data_const::do_print_to_mapfile): New function. (class Output_data_const_buffer): Add map_name_ field. Update constructor. Change all callers. Add do_print_to_mapfile function. (class Output_data_fixed_space): Likewise. (class Output_data_space): Likewise. (class Output_data_zero_fill): New class. (Output_data_strtab::do_print_to_mapfile): New function. (Output_data_reloc_base::do_print_to_mapfile): New function. (Output_relocatable_relocs::do_print_to_mapfile): New function. (Output_data_group::do_print_to_mapfile): New function. (Output_data_got::do_print_to_mapfile): New function. (Output_data_dynamic::do_print_to_mapfile): New function. (Output_symtab_xindex::do_print_to_mapfile): New function. (class Output_section): Declare do_print_to_mapflie. Declare print_to_mapfile in Input_section. (class Output_segment): Declare new functions. * object.h (Sized_relobj::symbol_count): New function. * script-sections.cc (Output_section_element_dot_assignment::set_section_addresses): Change Output_data_fixed_space to Output_data_zero_fill. (Output_data_expression::do_print_to_mapfile): New function. * script.cc (read_input_script): Add mapfile parameter. Change all callers. * script.h (read_input_script): Update declaration. * ehframe.h (Eh_frame_hdr::do_print_to_mapfile): New function. (Eh_frame::do_print_to_mapfile): New function. * merge.h (Output_merge_data::do_print_to_mapfile): New function. (Output_merge_string::do_print_to_mapfile): New function. * i386.cc (Output_data_plt_i386::do_print_to_mapfile): New function. * sparc.cc (Output_data_plt_sparc::do_print_to_mapfile): New function. * x86_64.cc (Output_data_plt_x86_64::do_print_to_mapfile): New function. * Makefile.am (CCFILES): Add mapfile.cc. (HFILES): Add mapfile.h. * Makefile.in: Rebuild.
2008-05-22 05:37:44 +08:00
// Print the output sections to the map file.
void
Layout::print_to_mapfile(Mapfile* mapfile) const
{
for (Segment_list::const_iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
++p)
(*p)->print_sections_to_mapfile(mapfile);
}
// Print statistical information to stderr. This is used for --stats.
void
Layout::print_stats() const
{
this->namepool_.print_stats("section name pool");
this->sympool_.print_stats("output symbol name pool");
this->dynpool_.print_stats("dynamic name pool");
for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end();
++p)
(*p)->print_merge_stats();
}
// Write_sections_task methods.
// We can always run this task.
Task_token*
Write_sections_task::is_runnable()
{
return NULL;
}
// We need to unlock both OUTPUT_SECTIONS_BLOCKER and FINAL_BLOCKER
// when finished.
void
Write_sections_task::locks(Task_locker* tl)
{
tl->add(this, this->output_sections_blocker_);
tl->add(this, this->final_blocker_);
}
// Run the task--write out the data.
void
Write_sections_task::run(Workqueue*)
{
this->layout_->write_output_sections(this->of_);
}
// Write_data_task methods.
// We can always run this task.
Task_token*
Write_data_task::is_runnable()
{
return NULL;
}
// We need to unlock FINAL_BLOCKER when finished.
void
Write_data_task::locks(Task_locker* tl)
{
tl->add(this, this->final_blocker_);
}
// Run the task--write out the data.
void
Write_data_task::run(Workqueue*)
{
2007-09-26 15:01:35 +08:00
this->layout_->write_data(this->symtab_, this->of_);
}
// Write_symbols_task methods.
// We can always run this task.
Task_token*
Write_symbols_task::is_runnable()
{
return NULL;
}
// We need to unlock FINAL_BLOCKER when finished.
void
Write_symbols_task::locks(Task_locker* tl)
{
tl->add(this, this->final_blocker_);
}
// Run the task--write out the symbols.
void
Write_symbols_task::run(Workqueue*)
{
this->symtab_->write_globals(this->sympool_, this->dynpool_,
this->layout_->symtab_xindex(),
* object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild.
2008-04-20 02:30:58 +08:00
this->layout_->dynsym_xindex(), this->of_);
}
// Write_after_input_sections_task methods.
// We can only run this task after the input sections have completed.
Task_token*
Write_after_input_sections_task::is_runnable()
{
if (this->input_sections_blocker_->is_blocked())
return this->input_sections_blocker_;
return NULL;
}
// We need to unlock FINAL_BLOCKER when finished.
void
Write_after_input_sections_task::locks(Task_locker* tl)
{
tl->add(this, this->final_blocker_);
}
// Run the task.
void
Write_after_input_sections_task::run(Workqueue*)
{
this->layout_->write_sections_after_input_sections(this->of_);
}
// Close_task_runner methods.
// Run the task--close the file.
void
Close_task_runner::run(Workqueue*, const Task*)
{
// If we need to compute a checksum for the BUILD if, we do so here.
this->layout_->write_build_id(this->of_);
2008-02-07 15:33:46 +08:00
// If we've been asked to create a binary file, we do so here.
if (this->options_->oformat_enum() != General_options::OBJECT_FORMAT_ELF)
2008-02-07 15:33:46 +08:00
this->layout_->write_binary(this->of_);
this->of_->close();
}
// Instantiate the templates we need. We could use the configure
// script to restrict this to only the ones for implemented targets.
#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::layout<32, false>(Sized_relobj<32, false>* object, unsigned int shndx,
const char* name,
const elfcpp::Shdr<32, false>& shdr,
unsigned int, unsigned int, off_t*);
#endif
#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::layout<32, true>(Sized_relobj<32, true>* object, unsigned int shndx,
const char* name,
const elfcpp::Shdr<32, true>& shdr,
unsigned int, unsigned int, off_t*);
#endif
#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::layout<64, false>(Sized_relobj<64, false>* object, unsigned int shndx,
const char* name,
const elfcpp::Shdr<64, false>& shdr,
unsigned int, unsigned int, off_t*);
#endif
#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::layout<64, true>(Sized_relobj<64, true>* object, unsigned int shndx,
const char* name,
const elfcpp::Shdr<64, true>& shdr,
unsigned int, unsigned int, off_t*);
#endif
2008-02-06 16:13:50 +08:00
#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::layout_reloc<32, false>(Sized_relobj<32, false>* object,
unsigned int reloc_shndx,
const elfcpp::Shdr<32, false>& shdr,
Output_section* data_section,
Relocatable_relocs* rr);
#endif
#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::layout_reloc<32, true>(Sized_relobj<32, true>* object,
unsigned int reloc_shndx,
const elfcpp::Shdr<32, true>& shdr,
Output_section* data_section,
Relocatable_relocs* rr);
#endif
#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::layout_reloc<64, false>(Sized_relobj<64, false>* object,
unsigned int reloc_shndx,
const elfcpp::Shdr<64, false>& shdr,
Output_section* data_section,
Relocatable_relocs* rr);
#endif
#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::layout_reloc<64, true>(Sized_relobj<64, true>* object,
unsigned int reloc_shndx,
const elfcpp::Shdr<64, true>& shdr,
Output_section* data_section,
Relocatable_relocs* rr);
#endif
#ifdef HAVE_TARGET_32_LITTLE
template
void
Layout::layout_group<32, false>(Symbol_table* symtab,
Sized_relobj<32, false>* object,
unsigned int,
const char* group_section_name,
const char* signature,
const elfcpp::Shdr<32, false>& shdr,
elfcpp::Elf_Word flags,
std::vector<unsigned int>* shndxes);
2008-02-06 16:13:50 +08:00
#endif
#ifdef HAVE_TARGET_32_BIG
template
void
Layout::layout_group<32, true>(Symbol_table* symtab,
Sized_relobj<32, true>* object,
unsigned int,
const char* group_section_name,
const char* signature,
const elfcpp::Shdr<32, true>& shdr,
elfcpp::Elf_Word flags,
std::vector<unsigned int>* shndxes);
2008-02-06 16:13:50 +08:00
#endif
#ifdef HAVE_TARGET_64_LITTLE
template
void
Layout::layout_group<64, false>(Symbol_table* symtab,
Sized_relobj<64, false>* object,
unsigned int,
const char* group_section_name,
const char* signature,
const elfcpp::Shdr<64, false>& shdr,
elfcpp::Elf_Word flags,
std::vector<unsigned int>* shndxes);
2008-02-06 16:13:50 +08:00
#endif
#ifdef HAVE_TARGET_64_BIG
template
void
Layout::layout_group<64, true>(Symbol_table* symtab,
Sized_relobj<64, true>* object,
unsigned int,
const char* group_section_name,
const char* signature,
const elfcpp::Shdr<64, true>& shdr,
elfcpp::Elf_Word flags,
std::vector<unsigned int>* shndxes);
2008-02-06 16:13:50 +08:00
#endif
#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::layout_eh_frame<32, false>(Sized_relobj<32, false>* object,
const unsigned char* symbols,
off_t symbols_size,
const unsigned char* symbol_names,
off_t symbol_names_size,
unsigned int shndx,
const elfcpp::Shdr<32, false>& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type,
off_t* off);
#endif
#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::layout_eh_frame<32, true>(Sized_relobj<32, true>* object,
const unsigned char* symbols,
off_t symbols_size,
const unsigned char* symbol_names,
off_t symbol_names_size,
unsigned int shndx,
const elfcpp::Shdr<32, true>& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type,
off_t* off);
#endif
#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::layout_eh_frame<64, false>(Sized_relobj<64, false>* object,
const unsigned char* symbols,
off_t symbols_size,
const unsigned char* symbol_names,
off_t symbol_names_size,
unsigned int shndx,
const elfcpp::Shdr<64, false>& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type,
off_t* off);
#endif
#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::layout_eh_frame<64, true>(Sized_relobj<64, true>* object,
const unsigned char* symbols,
off_t symbols_size,
const unsigned char* symbol_names,
off_t symbol_names_size,
unsigned int shndx,
const elfcpp::Shdr<64, true>& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type,
off_t* off);
#endif
} // End namespace gold.