binutils-gdb/gold/ehframe.h

547 lines
16 KiB
C
Raw Normal View History

// ehframe.h -- handle exception frame sections for gold -*- C++ -*-
// Copyright (C) 2006-2023 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.
#ifndef GOLD_EHFRAME_H
#define GOLD_EHFRAME_H
2008-02-02 14:50:45 +08:00
#include <map>
#include <set>
#include <vector>
#include "output.h"
#include "merge.h"
namespace gold
{
template<int size, bool big_endian>
class Track_relocs;
class Eh_frame;
// This class manages the .eh_frame_hdr section, which holds the data
// for the PT_GNU_EH_FRAME segment. gcc's unwind support code uses
// the PT_GNU_EH_FRAME segment to find the list of FDEs. This saves
// the time required to register the exception handlers at startup
// time and when a shared object is loaded, and the time required to
// deregister the exception handlers when a shared object is unloaded.
class Eh_frame_hdr : public Output_section_data
{
public:
Eh_frame_hdr(Output_section* eh_frame_section, const Eh_frame*);
// Record that we found an unrecognized .eh_frame section.
void
found_unrecognized_eh_frame_section()
{ this->any_unrecognized_eh_frame_sections_ = true; }
// Record an FDE.
void
record_fde(section_offset_type fde_offset, unsigned char fde_encoding)
{
if (!this->any_unrecognized_eh_frame_sections_)
this->fde_offsets_.push_back(std::make_pair(fde_offset, fde_encoding));
}
* 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
protected:
// Set the final data size.
void
set_final_data_size();
// Write the data to the file.
void
do_write(Output_file*);
* 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
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** eh_frame_hdr")); }
private:
// Write the data to the file with the right endianness.
template<int size, bool big_endian>
void
do_sized_write(Output_file*);
// The data we record for one FDE: the offset of the FDE within the
// .eh_frame section, and the FDE encoding.
typedef std::pair<section_offset_type, unsigned char> Fde_offset;
// The list of information we record for an FDE.
typedef std::vector<Fde_offset> Fde_offsets;
// When writing out the header, we convert the FDE offsets into FDE
// addresses. This is a list of pairs of the offset from the header
// to the FDE PC and to the FDE itself.
template<int size>
class Fde_addresses
{
public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
typedef typename std::pair<Address, Address> Fde_address;
typedef typename std::vector<Fde_address> Fde_address_list;
typedef typename Fde_address_list::iterator iterator;
Fde_addresses(unsigned int reserve)
: fde_addresses_()
{ this->fde_addresses_.reserve(reserve); }
void
push_back(Address pc_address, Address fde_address)
{
this->fde_addresses_.push_back(std::make_pair(pc_address, fde_address));
}
iterator
begin()
{ return this->fde_addresses_.begin(); }
iterator
end()
{ return this->fde_addresses_.end(); }
private:
Fde_address_list fde_addresses_;
};
// Compare Fde_address objects.
template<int size>
struct Fde_address_compare
{
bool
operator()(const typename Fde_addresses<size>::Fde_address& f1,
const typename Fde_addresses<size>::Fde_address& f2) const
{ return f1.first < f2.first; }
};
// Return the PC to which an FDE refers.
template<int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr
get_fde_pc(typename elfcpp::Elf_types<size>::Elf_Addr eh_frame_address,
const unsigned char* eh_frame_contents,
section_offset_type fde_offset, unsigned char fde_encoding);
// Convert Fde_offsets to Fde_addresses.
template<int size, bool big_endian>
void
get_fde_addresses(Output_file* of,
const Fde_offsets* fde_offsets,
Fde_addresses<size>* fde_addresses);
// The .eh_frame section.
Output_section* eh_frame_section_;
// The .eh_frame section data.
const Eh_frame* eh_frame_data_;
// Data from the FDEs in the .eh_frame sections.
Fde_offsets fde_offsets_;
// Whether we found any .eh_frame sections which we could not
// process.
bool any_unrecognized_eh_frame_sections_;
};
// This class holds an FDE.
class Fde
{
public:
Fde(Relobj* object, unsigned int shndx, section_offset_type input_offset,
const unsigned char* contents, size_t length)
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
: object_(object),
contents_(reinterpret_cast<const char*>(contents), length)
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
{
this->u_.from_object.shndx = shndx;
this->u_.from_object.input_offset = input_offset;
}
// Create an FDE associated with a PLT.
Fde(Output_data* plt, const unsigned char* contents, size_t length,
bool post_map)
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
: object_(NULL),
contents_(reinterpret_cast<const char*>(contents), length)
{
this->u_.from_linker.plt = plt;
this->u_.from_linker.post_map = post_map;
}
// Return the length of this FDE. Add 4 for the length and 4 for
// the offset to the CIE.
size_t
length() const
{ return this->contents_.length() + 8; }
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// Add a mapping for this FDE to MERGE_MAP, so that relocations
// against the FDE are applied to right part of the output file.
void
Remove empty class Merge_map. 2015-03-02 Rafael Ávila de Espíndola <rafael.espindola@gmail.com> * ehframe.cc (Cie::set_output_offset): Pass in and use a Output_section_data instead of a Merge_map. (Eh_frame::Eh_frame): Don't initialize merge_map_. (Eh_frame::read_cie): Use add_merge_mapping instead of Merge_map::add_mapping. (Eh_frame::read_fde): Ditto. (Eh_frame::set_final_data_size): Use this instead of this->merge_map_. (Eh_frame::do_output_offset): Use merge_output_offset istead of merge_map_->get_output_offset. (Eh_frame::do_is_merge_section_for): Delete. * ehframe.h (Fde::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Cie::set_output_offset): Pass in a Output_section_data instead of a Merge_map. (Eh_frame::do_is_merge_section_for): Delete. (Eh_frame::merge_map_): Delete. * merge.cc (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::add_mapping): Ditto. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::do_output_offset): Use merge_output_offset instead of merge_map_.get_output_offset. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_data::do_add_input_section): Use object->add_merge_mapping instead of add_mapping. (Output_merge_string<Char_type>::finalize_merged_data): Ditto. * merge.h (Merge_map): Delete forward declaration. (Object_merge_map::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Input_merge_map::Object_merge_map::merge_map): Replace with output_data. (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::Output_merge_base): Don't initialize merge_map_. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_base::add_mapping): Delete. (Output_merge_base::merge_map_): Delete. * object.cc (Relobj::initialize_input_to_output_map): New. (Relobj::initialize_input_to_output_map): New. (Relobj::merge_output_offset): New. (Relobj::is_merge_section_for): New. (Relobj::initialize_input_to_output_map): Instantiate for 32 and 64 bits. * object.h (Relobj::merge_map): Delete. (initialize_input_to_output_map): New. (set_merge_map): Delete. (add_merge_mapping): New. (merge_output_offset): New. (is_merge_section_for): New. * output.cc (Output_section::Input_section::is_merge_section_for): Use object->is_merge_section_for. * output.h (Output_section_data::is_merge_section_for): Delete. (Output_section_data::do_is_merge_section_for): Delete. * reloc.cc (Merged_symbol_value<size>::initialize_input_to_output_map): Use object->initialize_input_to_output_map. (Merged_symbol_value<size>::value_from_output_section): Use object->merge_output_offset.
2015-03-05 07:10:18 +08:00
add_mapping(section_offset_type output_offset,
Output_section_data* output_data) const
{
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
if (this->object_ != NULL)
Remove empty class Merge_map. 2015-03-02 Rafael Ávila de Espíndola <rafael.espindola@gmail.com> * ehframe.cc (Cie::set_output_offset): Pass in and use a Output_section_data instead of a Merge_map. (Eh_frame::Eh_frame): Don't initialize merge_map_. (Eh_frame::read_cie): Use add_merge_mapping instead of Merge_map::add_mapping. (Eh_frame::read_fde): Ditto. (Eh_frame::set_final_data_size): Use this instead of this->merge_map_. (Eh_frame::do_output_offset): Use merge_output_offset istead of merge_map_->get_output_offset. (Eh_frame::do_is_merge_section_for): Delete. * ehframe.h (Fde::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Cie::set_output_offset): Pass in a Output_section_data instead of a Merge_map. (Eh_frame::do_is_merge_section_for): Delete. (Eh_frame::merge_map_): Delete. * merge.cc (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::add_mapping): Ditto. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::do_output_offset): Use merge_output_offset instead of merge_map_.get_output_offset. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_data::do_add_input_section): Use object->add_merge_mapping instead of add_mapping. (Output_merge_string<Char_type>::finalize_merged_data): Ditto. * merge.h (Merge_map): Delete forward declaration. (Object_merge_map::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Input_merge_map::Object_merge_map::merge_map): Replace with output_data. (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::Output_merge_base): Don't initialize merge_map_. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_base::add_mapping): Delete. (Output_merge_base::merge_map_): Delete. * object.cc (Relobj::initialize_input_to_output_map): New. (Relobj::initialize_input_to_output_map): New. (Relobj::merge_output_offset): New. (Relobj::is_merge_section_for): New. (Relobj::initialize_input_to_output_map): Instantiate for 32 and 64 bits. * object.h (Relobj::merge_map): Delete. (initialize_input_to_output_map): New. (set_merge_map): Delete. (add_merge_mapping): New. (merge_output_offset): New. (is_merge_section_for): New. * output.cc (Output_section::Input_section::is_merge_section_for): Use object->is_merge_section_for. * output.h (Output_section_data::is_merge_section_for): Delete. (Output_section_data::do_is_merge_section_for): Delete. * reloc.cc (Merged_symbol_value<size>::initialize_input_to_output_map): Use object->initialize_input_to_output_map. (Merged_symbol_value<size>::value_from_output_section): Use object->merge_output_offset.
2015-03-05 07:10:18 +08:00
this->object_->add_merge_mapping(output_data, this->u_.from_object.shndx,
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
this->u_.from_object.input_offset, this->length(),
output_offset);
}
// Return whether this FDE was added after merge mapping.
bool
[GOLD] PowerPC notoc eh_frame When generating notoc call and branch stubs without the benefit of pc-relative insns, the stubs need to use LR to access the run time PC. All LR changes must be described in .eh_frame if we're to support unwinding through asynchronous exceptions. That's what this patch does. The patch has gone through way too many iterations. At first I attempted to add multiple FDEs, one for each stub. That ran into difficulties with do_plt_fde_location which is only capable of setting the address of a single FDE per Output_data section, and with removing any FDEs added on a previous do_relax pass. Removing FDEs (git commit be897fb774) went overboard in matching the FDE contents. That means either stashing the contents created for add_eh_frame_for_plt to use when calling remove_eh_frame_for_plt, or recreating contents on the fly (*) just to remove FDEs. In fact, FDE content matching is quite unnecesary. FDEs added by a previous do_relax pass are those with u_.from_linker.post_map set. So they can easily be recognised just by looking at that flag. This patch keeps that part of the multiple FDE changes. In the end I went for just one FDE per stub group to describe the call stubs. That's reasonably efficient for the common case of only needing to describe the __tls_get_addr_opt call stub. We don't expect to be making many calls using notoc stubs without pc-relative insns. *) Which has it's own set of problems. The contents must be recreated using the old stub layout, but .eh_frame size can affect stub requirements so you need to temporarily keep the old .eh_frame size when creating new stubs, then reset .eh_frame size before adding new FDEs. * ehframe.cc (Fde::operator==): Delete. (Cie::remove_fde): Delete. (Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length parameters. Remove all post-map plt FDEs. * ehframe.h (Fde:post_map): Make const, add variant to compare plt. (Fde::operator==): Delete. (Cie::remove_fde): Implement here. (Cie::last_fde): New accessor. (Eh_frame::remove_ehframe_for_plt): Update prototype. * layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and fde_length parameters. * layout.h (Layout::remove_eh_frame_for_plt): Update prototype. * powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete. (Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete. (Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_. (eh_advance): New function. (stub_sort): New function. (Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and branches as well as __tls_get_addr_opt plt call stub. (Stub_table::remove_eh_frame): Update to suit.
2019-07-01 13:07:49 +08:00
post_map() const
{ return this->object_ == NULL && this->u_.from_linker.post_map; }
[GOLD] PowerPC notoc eh_frame When generating notoc call and branch stubs without the benefit of pc-relative insns, the stubs need to use LR to access the run time PC. All LR changes must be described in .eh_frame if we're to support unwinding through asynchronous exceptions. That's what this patch does. The patch has gone through way too many iterations. At first I attempted to add multiple FDEs, one for each stub. That ran into difficulties with do_plt_fde_location which is only capable of setting the address of a single FDE per Output_data section, and with removing any FDEs added on a previous do_relax pass. Removing FDEs (git commit be897fb774) went overboard in matching the FDE contents. That means either stashing the contents created for add_eh_frame_for_plt to use when calling remove_eh_frame_for_plt, or recreating contents on the fly (*) just to remove FDEs. In fact, FDE content matching is quite unnecesary. FDEs added by a previous do_relax pass are those with u_.from_linker.post_map set. So they can easily be recognised just by looking at that flag. This patch keeps that part of the multiple FDE changes. In the end I went for just one FDE per stub group to describe the call stubs. That's reasonably efficient for the common case of only needing to describe the __tls_get_addr_opt call stub. We don't expect to be making many calls using notoc stubs without pc-relative insns. *) Which has it's own set of problems. The contents must be recreated using the old stub layout, but .eh_frame size can affect stub requirements so you need to temporarily keep the old .eh_frame size when creating new stubs, then reset .eh_frame size before adding new FDEs. * ehframe.cc (Fde::operator==): Delete. (Cie::remove_fde): Delete. (Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length parameters. Remove all post-map plt FDEs. * ehframe.h (Fde:post_map): Make const, add variant to compare plt. (Fde::operator==): Delete. (Cie::remove_fde): Implement here. (Cie::last_fde): New accessor. (Eh_frame::remove_ehframe_for_plt): Update prototype. * layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and fde_length parameters. * layout.h (Layout::remove_eh_frame_for_plt): Update prototype. * powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete. (Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete. (Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_. (eh_advance): New function. (stub_sort): New function. (Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and branches as well as __tls_get_addr_opt plt call stub. (Stub_table::remove_eh_frame): Update to suit.
2019-07-01 13:07:49 +08:00
// Return whether this FDE was added for the PLT after merge mapping.
bool
post_map(const Output_data* plt) const
{ return this->post_map() && this->u_.from_linker.plt == plt; }
// Write the FDE to OVIEW starting at OFFSET. FDE_ENCODING is the
2008-02-14 10:40:15 +08:00
// encoding, from the CIE. Round up the bytes to ADDRALIGN if
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// necessary. ADDRESS is the virtual address of OVIEW. Record the
// FDE in EH_FRAME_HDR. Return the new offset.
template<int size, bool big_endian>
section_offset_type
Fix problem with optimization of .eh_frame section and --sort-section option. When --sort-section=name is used, gold will sort the linker-generated contents of .eh_frame (after optimization) after the endcap provided by crtendS.o. This causes two problems: the .eh_frame_hdr section is generated assuming that the optimized .eh_frame contents will be placed at the very beginning of the section, and the endcap no longer appears at the end of the section. This patch fixes the first problem by adjusting FDE offsets to take into account the actual starting offset within the output section, and fixes the second problem by sorting linker-generated (Output_section_data) sections based on the name of the output section. gold/ PR gold/17005 * ehframe.cc (Fde::write): Add output_offset parameter. (Cie::write): Likewise. (Eh_frame::set_final_data_size): Account for offset within output section. (Eh_frame::do_sized_write): Likewise. * ehframe.h (Fde::write): Add output_offset parameter. (Cie::write): Likewise. * output.cc (Output_section::Input_section_sort_entry): Remove section_has_name_; add output_section_name parameter. Use output section name for non-input sections. (Output_section::Input_section_sort_entry::section_has_name): Remove. (Output_section::Input_section_sort_entry::section_has_name_): Remove. (Output_section::Input_section_sort_compare): Remove logic for sections without names. (Output_section::Input_section_sort_init_fini_compare): Likewise. (Output_section::Input_section_sort_section_prefix_special_ordering_compare): Likewise. (Output_section::Input_section_sort_section_name_compare): Likewise.
2014-07-03 00:39:41 +08:00
write(unsigned char* oview, section_offset_type output_section_offset,
section_offset_type offset, uint64_t address, unsigned int addralign,
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
section_offset_type cie_offset, unsigned char fde_encoding,
Eh_frame_hdr* eh_frame_hdr);
private:
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// The object in which this FDE was seen. This will be NULL for a
// linker generated FDE.
Relobj* object_;
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
union
{
// These fields are used if the FDE is from an input object (the
// object_ field is not NULL).
struct
{
// Input section index for this FDE.
unsigned int shndx;
// Offset within the input section for this FDE.
section_offset_type input_offset;
} from_object;
// This field is used if the FDE is generated by the linker (the
// object_ field is NULL).
struct
{
// The only linker generated FDEs are for PLT sections, and this
// points to the PLT section.
Output_data* plt;
// Set if the FDE was added after merge mapping.
bool post_map;
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
} from_linker;
} u_;
// FDE data.
std::string contents_;
};
// A FDE plus some info from a CIE to allow later writing of the FDE.
struct Post_fde
{
Post_fde(Fde* f, section_offset_type cie_off, unsigned char encoding)
: fde(f), cie_offset(cie_off), fde_encoding(encoding)
{ }
Fde* fde;
section_offset_type cie_offset;
unsigned char fde_encoding;
};
typedef std::vector<Post_fde> Post_fdes;
// This class holds a CIE.
class Cie
{
public:
Cie(Relobj* object, unsigned int shndx, section_offset_type input_offset,
unsigned char fde_encoding, const char* personality_name,
const unsigned char* contents, size_t length)
: object_(object),
shndx_(shndx),
input_offset_(input_offset),
fde_encoding_(fde_encoding),
personality_name_(personality_name),
fdes_(),
contents_(reinterpret_cast<const char*>(contents), length)
{ }
~Cie();
// We permit copying a CIE when there are no FDEs. This is
// convenient in the code which creates them.
Cie(const Cie& cie)
: object_(cie.object_),
shndx_(cie.shndx_),
input_offset_(cie.input_offset_),
fde_encoding_(cie.fde_encoding_),
personality_name_(cie.personality_name_),
fdes_(),
contents_(cie.contents_)
{ gold_assert(cie.fdes_.empty()); }
// Add an FDE associated with this CIE.
void
add_fde(Fde* fde)
{ this->fdes_.push_back(fde); }
[GOLD] PowerPC notoc eh_frame When generating notoc call and branch stubs without the benefit of pc-relative insns, the stubs need to use LR to access the run time PC. All LR changes must be described in .eh_frame if we're to support unwinding through asynchronous exceptions. That's what this patch does. The patch has gone through way too many iterations. At first I attempted to add multiple FDEs, one for each stub. That ran into difficulties with do_plt_fde_location which is only capable of setting the address of a single FDE per Output_data section, and with removing any FDEs added on a previous do_relax pass. Removing FDEs (git commit be897fb774) went overboard in matching the FDE contents. That means either stashing the contents created for add_eh_frame_for_plt to use when calling remove_eh_frame_for_plt, or recreating contents on the fly (*) just to remove FDEs. In fact, FDE content matching is quite unnecesary. FDEs added by a previous do_relax pass are those with u_.from_linker.post_map set. So they can easily be recognised just by looking at that flag. This patch keeps that part of the multiple FDE changes. In the end I went for just one FDE per stub group to describe the call stubs. That's reasonably efficient for the common case of only needing to describe the __tls_get_addr_opt call stub. We don't expect to be making many calls using notoc stubs without pc-relative insns. *) Which has it's own set of problems. The contents must be recreated using the old stub layout, but .eh_frame size can affect stub requirements so you need to temporarily keep the old .eh_frame size when creating new stubs, then reset .eh_frame size before adding new FDEs. * ehframe.cc (Fde::operator==): Delete. (Cie::remove_fde): Delete. (Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length parameters. Remove all post-map plt FDEs. * ehframe.h (Fde:post_map): Make const, add variant to compare plt. (Fde::operator==): Delete. (Cie::remove_fde): Implement here. (Cie::last_fde): New accessor. (Eh_frame::remove_ehframe_for_plt): Update prototype. * layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and fde_length parameters. * layout.h (Layout::remove_eh_frame_for_plt): Update prototype. * powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete. (Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete. (Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_. (eh_advance): New function. (stub_sort): New function. (Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and branches as well as __tls_get_addr_opt plt call stub. (Stub_table::remove_eh_frame): Update to suit.
2019-07-01 13:07:49 +08:00
// Remove the last FDE associated with this CIE.
[GOLD] PowerPC recreate eh_frame for stubs on each relax pass There is a very small but non-zero probability that a stub group contains stubs on one relax pass, but does not on the next. In that case we would get an FDE covering a zero length address range. (Actually, it's even worse. Alignment padding for stubs can mean the address for the non-existent stubs is past the end of the original section to which stubs are attached, and due to the way do_plt_fde_location calculates the length we can get a negative length.) Fixing this properly requires removing the FDE. Also, I have been implementing the __tls_get_addr_opt support for gold, and that stub needs something other than the default FDE. The necessary FDE will depend on the offset to the __tls_get_addr_opt stub, which of course can change during relaxation. That means at the very least, rewriting the FDE on each pass, possibly changing the FDE size. I think that is better done by completely recreating PLT eh_frame FDEs. * ehframe.cc (Fde::operator==): New. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): New. * ehframe.h (Fde::operator==): Declare. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): Likewise. * layout.cc (Layout::remove_eh_frame_for_plt): New. * layout.h (Layout::remove_eh_frame_for_plt): Declare. * powerpc.cc (Target_powerpc::do_relax): Remove old eh_frame FDEs. (Stub_table::add_eh_frame): Delete eh_frame_added_ condition. Don't add eh_frame for empty stub section. (Stub_table::remove_eh_frame): New.
2017-08-01 12:38:53 +08:00
void
[GOLD] PowerPC notoc eh_frame When generating notoc call and branch stubs without the benefit of pc-relative insns, the stubs need to use LR to access the run time PC. All LR changes must be described in .eh_frame if we're to support unwinding through asynchronous exceptions. That's what this patch does. The patch has gone through way too many iterations. At first I attempted to add multiple FDEs, one for each stub. That ran into difficulties with do_plt_fde_location which is only capable of setting the address of a single FDE per Output_data section, and with removing any FDEs added on a previous do_relax pass. Removing FDEs (git commit be897fb774) went overboard in matching the FDE contents. That means either stashing the contents created for add_eh_frame_for_plt to use when calling remove_eh_frame_for_plt, or recreating contents on the fly (*) just to remove FDEs. In fact, FDE content matching is quite unnecesary. FDEs added by a previous do_relax pass are those with u_.from_linker.post_map set. So they can easily be recognised just by looking at that flag. This patch keeps that part of the multiple FDE changes. In the end I went for just one FDE per stub group to describe the call stubs. That's reasonably efficient for the common case of only needing to describe the __tls_get_addr_opt call stub. We don't expect to be making many calls using notoc stubs without pc-relative insns. *) Which has it's own set of problems. The contents must be recreated using the old stub layout, but .eh_frame size can affect stub requirements so you need to temporarily keep the old .eh_frame size when creating new stubs, then reset .eh_frame size before adding new FDEs. * ehframe.cc (Fde::operator==): Delete. (Cie::remove_fde): Delete. (Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length parameters. Remove all post-map plt FDEs. * ehframe.h (Fde:post_map): Make const, add variant to compare plt. (Fde::operator==): Delete. (Cie::remove_fde): Implement here. (Cie::last_fde): New accessor. (Eh_frame::remove_ehframe_for_plt): Update prototype. * layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and fde_length parameters. * layout.h (Layout::remove_eh_frame_for_plt): Update prototype. * powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete. (Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete. (Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_. (eh_advance): New function. (stub_sort): New function. (Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and branches as well as __tls_get_addr_opt plt call stub. (Stub_table::remove_eh_frame): Update to suit.
2019-07-01 13:07:49 +08:00
remove_fde()
{ this->fdes_.pop_back(); }
// Access the last FDE associated with this CIE.
const Fde*
last_fde() const
{ return this->fdes_.back(); }
[GOLD] PowerPC recreate eh_frame for stubs on each relax pass There is a very small but non-zero probability that a stub group contains stubs on one relax pass, but does not on the next. In that case we would get an FDE covering a zero length address range. (Actually, it's even worse. Alignment padding for stubs can mean the address for the non-existent stubs is past the end of the original section to which stubs are attached, and due to the way do_plt_fde_location calculates the length we can get a negative length.) Fixing this properly requires removing the FDE. Also, I have been implementing the __tls_get_addr_opt support for gold, and that stub needs something other than the default FDE. The necessary FDE will depend on the offset to the __tls_get_addr_opt stub, which of course can change during relaxation. That means at the very least, rewriting the FDE on each pass, possibly changing the FDE size. I think that is better done by completely recreating PLT eh_frame FDEs. * ehframe.cc (Fde::operator==): New. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): New. * ehframe.h (Fde::operator==): Declare. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): Likewise. * layout.cc (Layout::remove_eh_frame_for_plt): New. * layout.h (Layout::remove_eh_frame_for_plt): Declare. * powerpc.cc (Target_powerpc::do_relax): Remove old eh_frame FDEs. (Stub_table::add_eh_frame): Delete eh_frame_added_ condition. Don't add eh_frame for empty stub section. (Stub_table::remove_eh_frame): New.
2017-08-01 12:38:53 +08:00
// Return the number of FDEs.
unsigned int
fde_count() const
{ return this->fdes_.size(); }
// Set the output offset of this CIE to OUTPUT_OFFSET. It will be
// followed by all its FDEs. ADDRALIGN is the required address
// alignment, typically 4 or 8. This updates MERGE_MAP with the
// mapping. It returns the new output offset.
section_offset_type
set_output_offset(section_offset_type output_offset, unsigned int addralign,
Remove empty class Merge_map. 2015-03-02 Rafael Ávila de Espíndola <rafael.espindola@gmail.com> * ehframe.cc (Cie::set_output_offset): Pass in and use a Output_section_data instead of a Merge_map. (Eh_frame::Eh_frame): Don't initialize merge_map_. (Eh_frame::read_cie): Use add_merge_mapping instead of Merge_map::add_mapping. (Eh_frame::read_fde): Ditto. (Eh_frame::set_final_data_size): Use this instead of this->merge_map_. (Eh_frame::do_output_offset): Use merge_output_offset istead of merge_map_->get_output_offset. (Eh_frame::do_is_merge_section_for): Delete. * ehframe.h (Fde::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Cie::set_output_offset): Pass in a Output_section_data instead of a Merge_map. (Eh_frame::do_is_merge_section_for): Delete. (Eh_frame::merge_map_): Delete. * merge.cc (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::add_mapping): Ditto. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::do_output_offset): Use merge_output_offset instead of merge_map_.get_output_offset. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_data::do_add_input_section): Use object->add_merge_mapping instead of add_mapping. (Output_merge_string<Char_type>::finalize_merged_data): Ditto. * merge.h (Merge_map): Delete forward declaration. (Object_merge_map::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Input_merge_map::Object_merge_map::merge_map): Replace with output_data. (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::Output_merge_base): Don't initialize merge_map_. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_base::add_mapping): Delete. (Output_merge_base::merge_map_): Delete. * object.cc (Relobj::initialize_input_to_output_map): New. (Relobj::initialize_input_to_output_map): New. (Relobj::merge_output_offset): New. (Relobj::is_merge_section_for): New. (Relobj::initialize_input_to_output_map): Instantiate for 32 and 64 bits. * object.h (Relobj::merge_map): Delete. (initialize_input_to_output_map): New. (set_merge_map): Delete. (add_merge_mapping): New. (merge_output_offset): New. (is_merge_section_for): New. * output.cc (Output_section::Input_section::is_merge_section_for): Use object->is_merge_section_for. * output.h (Output_section_data::is_merge_section_for): Delete. (Output_section_data::do_is_merge_section_for): Delete. * reloc.cc (Merged_symbol_value<size>::initialize_input_to_output_map): Use object->initialize_input_to_output_map. (Merged_symbol_value<size>::value_from_output_section): Use object->merge_output_offset.
2015-03-05 07:10:18 +08:00
Output_section_data*);
// Write the CIE to OVIEW starting at OFFSET. Round up the bytes to
// ADDRALIGN. ADDRESS is the virtual address of OVIEW.
// EH_FRAME_HDR is the exception frame header for FDE recording.
// POST_FDES stashes FDEs created after mappings were done, for later
// writing. Return the new offset.
template<int size, bool big_endian>
section_offset_type
Fix problem with optimization of .eh_frame section and --sort-section option. When --sort-section=name is used, gold will sort the linker-generated contents of .eh_frame (after optimization) after the endcap provided by crtendS.o. This causes two problems: the .eh_frame_hdr section is generated assuming that the optimized .eh_frame contents will be placed at the very beginning of the section, and the endcap no longer appears at the end of the section. This patch fixes the first problem by adjusting FDE offsets to take into account the actual starting offset within the output section, and fixes the second problem by sorting linker-generated (Output_section_data) sections based on the name of the output section. gold/ PR gold/17005 * ehframe.cc (Fde::write): Add output_offset parameter. (Cie::write): Likewise. (Eh_frame::set_final_data_size): Account for offset within output section. (Eh_frame::do_sized_write): Likewise. * ehframe.h (Fde::write): Add output_offset parameter. (Cie::write): Likewise. * output.cc (Output_section::Input_section_sort_entry): Remove section_has_name_; add output_section_name parameter. Use output section name for non-input sections. (Output_section::Input_section_sort_entry::section_has_name): Remove. (Output_section::Input_section_sort_entry::section_has_name_): Remove. (Output_section::Input_section_sort_compare): Remove logic for sections without names. (Output_section::Input_section_sort_init_fini_compare): Likewise. (Output_section::Input_section_sort_section_prefix_special_ordering_compare): Likewise. (Output_section::Input_section_sort_section_name_compare): Likewise.
2014-07-03 00:39:41 +08:00
write(unsigned char* oview, section_offset_type output_section_offset,
section_offset_type offset, uint64_t address,
unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
Post_fdes* post_fdes);
// Return the FDE encoding.
unsigned char
fde_encoding() const
{ return this->fde_encoding_; }
friend bool operator<(const Cie&, const Cie&);
friend bool operator==(const Cie&, const Cie&);
private:
// The class is not assignable.
Cie& operator=(const Cie&);
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// The object in which this CIE was first seen. This will be NULL
// for a linker generated CIE.
Relobj* object_;
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// Input section index for this CIE. This will be 0 for a linker
// generated CIE.
unsigned int shndx_;
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// Offset within the input section for this CIE. This will be 0 for
// a linker generated CIE.
section_offset_type input_offset_;
// The encoding of the FDE. This is a DW_EH_PE code.
unsigned char fde_encoding_;
// The name of the personality routine. This will be the name of a
// global symbol, or will be the empty string.
std::string personality_name_;
// List of FDEs.
std::vector<Fde*> fdes_;
// CIE data.
std::string contents_;
};
extern bool operator<(const Cie&, const Cie&);
extern bool operator==(const Cie&, const Cie&);
// This class manages .eh_frame sections. It discards duplicate
// exception information.
class Eh_frame : public Output_section_data
{
public:
enum Eh_frame_section_disposition
{
EH_EMPTY_SECTION,
EH_UNRECOGNIZED_SECTION,
EH_OPTIMIZABLE_SECTION,
EH_END_MARKER_SECTION
};
Eh_frame();
// Record the associated Eh_frame_hdr, if any.
void
set_eh_frame_hdr(Eh_frame_hdr* hdr)
{ this->eh_frame_hdr_ = hdr; }
// Add the input section SHNDX in OBJECT. SYMBOLS is the contents
// of the symbol table section (size SYMBOLS_SIZE), SYMBOL_NAMES is
// the symbol names section (size SYMBOL_NAMES_SIZE). RELOC_SHNDX
// is the relocation section if any (0 for none, -1U for multiple).
// RELOC_TYPE is the type of the relocation section if any. This
// returns whether the section was incorporated into the .eh_frame
// data.
template<int size, bool big_endian>
Eh_frame_section_disposition
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc info; adjust display of GOT entries. * incremental.cc (Sized_incremental_binary::setup_readers): Allocate vector of input objects; remove file_status_. (Sized_incremental_binary::do_reserve_layout): Remove file_status_. (Sized_incremental_binary::do_process_got_plt): Adjust calls to got_plt reader; call target hooks to reserve GOT entries. (Output_section_incremental_inputs::set_final_data_size): Adjust size of input file info header and GOT info entry. (Output_section_incremental_inputs::write_info_blocks): Write dynamic relocation info. (Got_plt_view_info::got_descriptor): Remove. (Got_plt_view_info::sym_index): New data member. (Got_plt_view_info::input_index): New data member. (Local_got_offset_visitor::visit): Write input file index. (Global_got_offset_visitor::visit): Write 0 for input file index. (Global_symbol_visitor_got_plt::operator()): Replace got_descriptor with sym_index and input_index. (Output_section_incremental_inputs::write_got_plt): Adjust size of incremental info GOT entry; replace got_descriptor with input_index. (Sized_relobj_incr::Sized_relobj_incr): Adjust initializers; record map from input file index to object. (Sized_relobj_incr::do_layout): Replace direct data member reference with accessor function. (Sized_relobj_incr::do_for_all_local_got_entries): Move to base class. * incremental.h (Incremental_input_entry_reader::get_symbol_offset): Adjust size of input file info header. (Incremental_input_entry_reader::get_first_dyn_reloc): New function. (Incremental_input_entry_reader::get_dyn_reloc_count): New function. (Incremental_input_entry_reader::get_input_section): Adjust size of input file info header. (Incremental_got_plt_reader::Incremental_got_plt_reader): Adjust size of incremental info GOT entry. (Incremental_got_plt_reader::get_got_desc): Remove. (Incremental_got_plt_reader::get_got_symndx): New function. (Incremental_got_plt_reader::get_got_input_index): New function. (Sized_incremental_binary::Sized_incremental_binary): Remove file_status_; add input_objects_. (Sized_incremental_binary::~Sized_incremental_binary): Remove. (Sized_incremental_binary::set_file_is_unchanged): Remove. (Sized_incremental_binary::file_is_unchanged): Remove. (Sized_incremental_binary::set_input_object): New function. (Sized_incremental_binary::input_object): New function. (Sized_incremental_binary::file_status_): Remove. (Sized_incremental_binary::input_objects_): New data member. (Sized_relobj_incr): Rename Sized_incr_relobj to this; adjust all references. (Sized_relobj_incr::invalid_address): Move to base class. (Sized_relobj_incr::is_output_section_offset_invalid): Move to base class. (Sized_relobj_incr::do_output_section_offset): Likewise. (Sized_relobj_incr::do_for_all_local_got_entries): Likewise. (Sized_relobj_incr::section_offsets_): Likewise. * object.cc (Sized_relobj::do_for_all_local_got_entries): New function. (Sized_relobj_file::Sized_relobj_file): Remove local_got_offsets_. (Sized_relobj_file::layout_section): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_layout): Likewise. (Sized_relobj_file::do_layout_deferred_sections): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Move to base class. (Sized_relobj_file::compute_final_local_value): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_finalize_local_symbols): Likewise. * object.h (Relobj::Relobj): Initialize new data members. (Relobj::add_dyn_reloc): New function. (Relobj::first_dyn_reloc): New function. (Relobj::dyn_reloc_count): New function. (Relobj::first_dyn_reloc_): New data member. (Relobj::dyn_reloc_count_): New data member. (Sized_relobj): Rename Sized_relobj_base to this; adjust all references. (Sized_relobj::Address): New typedef. (Sized_relobj::invalid_address): Move here from child class. (Sized_relobj::Sized_relobj): Initialize new data members. (Sized_relobj::sized_relobj): New function. (Sized_relobj::is_output_section_offset_invalid): Move here from child class. (Sized_relobj::get_output_section_offset): Likewise. (Sized_relobj::local_has_got_offset): Likewise. (Sized_relobj::local_got_offset): Likewise. (Sized_relobj::set_local_got_offset): Likewise. (Sized_relobj::do_for_all_local_got_entries): Likewise. (Sized_relobj::clear_got_offsets): New function. (Sized_relobj::section_offsets): Move here from child class. (Sized_relobj::do_output_section_offset): Likewise. (Sized_relobj::do_set_section_offset): Likewise. (Sized_relobj::Local_got_offsets): Likewise. (Sized_relobj::local_got_offsets_): Likewise. (Sized_relobj::section_offsets_): Likewise. (Sized_relobj_file): Rename Sized_relobj to this; adjust all references. (Sized_relobj_file::is_output_section_offset_invalid): Move to base class. (Sized_relobj_file::sized_relobj): New function (Sized_relobj_file::local_has_got_offset): Move to base class. (Sized_relobj_file::local_got_offset): Likewise. (Sized_relobj_file::set_local_got_offset): Likewise. (Sized_relobj_file::get_output_section_offset): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Likewise. (Sized_relobj_file::do_output_section_offset): Likewise. (Sized_relobj_file::do_set_section_offset): Likewise. (Sized_relobj_file::Local_got_offsets): Likewise. (Sized_relobj_file::local_got_offsets_): Likewise. (Sized_relobj_file::section_offsets_): Likewise. * output.cc (Output_reloc::Output_reloc): Adjust type of relobj (all constructors). (set_needs_dynsym_index): Convert relobj to derived class pointer. (Output_reloc::get_symbol_index): Likewise. (Output_reloc::local_section_offset): Likewise. (Output_reloc::get_address): Likewise. (Output_reloc::symbol_value): Likewise. (Output_data_got::reserve_slot): Move to class definition. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_slot_for_global): Remove. (Output_data_got::reserve_global): New function. * output.h (Output_reloc::Output_reloc): Adjust type of relobj (all constructors, two instantiations). (Output_reloc::get_relobj): New function (two instantiations). (Output_reloc::u1_.relobj, Output_reloc::u2_.relobj): Adjust type. (Output_data_reloc_base::add): Convert relobj to derived class pointer. (Output_data_reloc::add_global): Adjust type of relobj. (Output_data_reloc::add_global_relative): Likewise. (Output_data_reloc::add_symbolless_global_addend): Likewise. (Output_data_reloc::add_local): Likewise. (Output_data_reloc::add_local_relative): Likewise. (Output_data_reloc::add_symbolless_local_addend): Likewise. (Output_data_reloc::add_local_section): Likewise. (Output_data_reloc::add_output_section): Likewise. (Output_data_reloc::add_absolute): Likewise. (Output_data_reloc::add_target_specific): Likewise. (Output_data_got::reserve_slot): Move definition here. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_global): New function. * reloc.cc (Sized_relobj_file::do_read_relocs): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::write_sections): Likewise. (Sized_relobj_file::do_relocate_sections): Likewise. * target.h (Sized_target::reserve_local_got_entry): New function. (Sized_target::reserve_global_got_entry): New function. * x86_64.cc (Target_x86_64::reserve_local_got_entry): New function. (Target_x86_64::reserve_global_got_entry): New function. (Target_x86_64::init_got_plt_for_update): Create rela_dyn section.
2011-05-25 05:41:10 +08:00
add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
const unsigned char* symbols,
section_size_type symbols_size,
const unsigned char* symbol_names,
section_size_type symbol_names_size,
unsigned int shndx, unsigned int reloc_shndx,
unsigned int reloc_type);
PR gold/12571 * options.h (class General_options): Add --ld-generated-unwind-info. * ehframe.cc (Fde::write): Add address parameter. Change all callers. If associated with PLT, fill in address and size. (Cie::set_output_offset): Only add merge mapping if there is an object. (Cie::write): Add address parameter. Change all callers. (Eh_frame::add_ehframe_for_plt): New function. * ehframe.h (class Fde): Update declarations. Move shndx_ and input_offset_ fields into union u_, with new plt field. (Fde::Fde): Adjust for new union field. (Fde::Fde) [Output_data version]: New constructor. (Fde::add_mapping): Only add merge mapping if there is an object. (class Cie): Update declarations. (class Eh_frame): Declare add_ehframe_for_plt. * layout.cc (Layout::layout_eh_frame): Break out code into make_eh_frame_section, and call it. (Layout::make_eh_frame_section): New function. (Layout::add_eh_frame_for_plt): New function. * layout.h (class Layout): Update declarations. * merge.cc (Merge_map::add_mapping): Add assertion. * i386.cc: Include "dwarf.h". (class Output_data_plt_i386): Make first_plt_entry, dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte boundary. Call add_eh_frame_for_plt if appropriate. * x86_64.cc: Include "dwarf.h". (class Output_data_plt_x86_64): Align to 16-byte boundary. Make first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie, and plt_eh_frame_fde. (Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if appropriate.
2011-07-02 06:05:01 +08:00
// Add a CIE and an FDE for a PLT section, to permit unwinding
// through a PLT. The FDE data should start with 8 bytes of zero,
// which will be replaced by a 4 byte PC relative reference to the
// address of PLT and a 4 byte size of PLT.
void
add_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
size_t cie_length, const unsigned char* fde_data,
size_t fde_length);
[GOLD] PowerPC notoc eh_frame When generating notoc call and branch stubs without the benefit of pc-relative insns, the stubs need to use LR to access the run time PC. All LR changes must be described in .eh_frame if we're to support unwinding through asynchronous exceptions. That's what this patch does. The patch has gone through way too many iterations. At first I attempted to add multiple FDEs, one for each stub. That ran into difficulties with do_plt_fde_location which is only capable of setting the address of a single FDE per Output_data section, and with removing any FDEs added on a previous do_relax pass. Removing FDEs (git commit be897fb774) went overboard in matching the FDE contents. That means either stashing the contents created for add_eh_frame_for_plt to use when calling remove_eh_frame_for_plt, or recreating contents on the fly (*) just to remove FDEs. In fact, FDE content matching is quite unnecesary. FDEs added by a previous do_relax pass are those with u_.from_linker.post_map set. So they can easily be recognised just by looking at that flag. This patch keeps that part of the multiple FDE changes. In the end I went for just one FDE per stub group to describe the call stubs. That's reasonably efficient for the common case of only needing to describe the __tls_get_addr_opt call stub. We don't expect to be making many calls using notoc stubs without pc-relative insns. *) Which has it's own set of problems. The contents must be recreated using the old stub layout, but .eh_frame size can affect stub requirements so you need to temporarily keep the old .eh_frame size when creating new stubs, then reset .eh_frame size before adding new FDEs. * ehframe.cc (Fde::operator==): Delete. (Cie::remove_fde): Delete. (Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length parameters. Remove all post-map plt FDEs. * ehframe.h (Fde:post_map): Make const, add variant to compare plt. (Fde::operator==): Delete. (Cie::remove_fde): Implement here. (Cie::last_fde): New accessor. (Eh_frame::remove_ehframe_for_plt): Update prototype. * layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and fde_length parameters. * layout.h (Layout::remove_eh_frame_for_plt): Update prototype. * powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete. (Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete. (Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_. (eh_advance): New function. (stub_sort): New function. (Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and branches as well as __tls_get_addr_opt plt call stub. (Stub_table::remove_eh_frame): Update to suit.
2019-07-01 13:07:49 +08:00
// Remove all post-map unwind information for a PLT.
[GOLD] PowerPC recreate eh_frame for stubs on each relax pass There is a very small but non-zero probability that a stub group contains stubs on one relax pass, but does not on the next. In that case we would get an FDE covering a zero length address range. (Actually, it's even worse. Alignment padding for stubs can mean the address for the non-existent stubs is past the end of the original section to which stubs are attached, and due to the way do_plt_fde_location calculates the length we can get a negative length.) Fixing this properly requires removing the FDE. Also, I have been implementing the __tls_get_addr_opt support for gold, and that stub needs something other than the default FDE. The necessary FDE will depend on the offset to the __tls_get_addr_opt stub, which of course can change during relaxation. That means at the very least, rewriting the FDE on each pass, possibly changing the FDE size. I think that is better done by completely recreating PLT eh_frame FDEs. * ehframe.cc (Fde::operator==): New. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): New. * ehframe.h (Fde::operator==): Declare. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): Likewise. * layout.cc (Layout::remove_eh_frame_for_plt): New. * layout.h (Layout::remove_eh_frame_for_plt): Declare. * powerpc.cc (Target_powerpc::do_relax): Remove old eh_frame FDEs. (Stub_table::add_eh_frame): Delete eh_frame_added_ condition. Don't add eh_frame for empty stub section. (Stub_table::remove_eh_frame): New.
2017-08-01 12:38:53 +08:00
void
remove_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
[GOLD] PowerPC notoc eh_frame When generating notoc call and branch stubs without the benefit of pc-relative insns, the stubs need to use LR to access the run time PC. All LR changes must be described in .eh_frame if we're to support unwinding through asynchronous exceptions. That's what this patch does. The patch has gone through way too many iterations. At first I attempted to add multiple FDEs, one for each stub. That ran into difficulties with do_plt_fde_location which is only capable of setting the address of a single FDE per Output_data section, and with removing any FDEs added on a previous do_relax pass. Removing FDEs (git commit be897fb774) went overboard in matching the FDE contents. That means either stashing the contents created for add_eh_frame_for_plt to use when calling remove_eh_frame_for_plt, or recreating contents on the fly (*) just to remove FDEs. In fact, FDE content matching is quite unnecesary. FDEs added by a previous do_relax pass are those with u_.from_linker.post_map set. So they can easily be recognised just by looking at that flag. This patch keeps that part of the multiple FDE changes. In the end I went for just one FDE per stub group to describe the call stubs. That's reasonably efficient for the common case of only needing to describe the __tls_get_addr_opt call stub. We don't expect to be making many calls using notoc stubs without pc-relative insns. *) Which has it's own set of problems. The contents must be recreated using the old stub layout, but .eh_frame size can affect stub requirements so you need to temporarily keep the old .eh_frame size when creating new stubs, then reset .eh_frame size before adding new FDEs. * ehframe.cc (Fde::operator==): Delete. (Cie::remove_fde): Delete. (Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length parameters. Remove all post-map plt FDEs. * ehframe.h (Fde:post_map): Make const, add variant to compare plt. (Fde::operator==): Delete. (Cie::remove_fde): Implement here. (Cie::last_fde): New accessor. (Eh_frame::remove_ehframe_for_plt): Update prototype. * layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and fde_length parameters. * layout.h (Layout::remove_eh_frame_for_plt): Update prototype. * powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete. (Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete. (Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_. (eh_advance): New function. (stub_sort): New function. (Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and branches as well as __tls_get_addr_opt plt call stub. (Stub_table::remove_eh_frame): Update to suit.
2019-07-01 13:07:49 +08:00
size_t cie_length);
[GOLD] PowerPC recreate eh_frame for stubs on each relax pass There is a very small but non-zero probability that a stub group contains stubs on one relax pass, but does not on the next. In that case we would get an FDE covering a zero length address range. (Actually, it's even worse. Alignment padding for stubs can mean the address for the non-existent stubs is past the end of the original section to which stubs are attached, and due to the way do_plt_fde_location calculates the length we can get a negative length.) Fixing this properly requires removing the FDE. Also, I have been implementing the __tls_get_addr_opt support for gold, and that stub needs something other than the default FDE. The necessary FDE will depend on the offset to the __tls_get_addr_opt stub, which of course can change during relaxation. That means at the very least, rewriting the FDE on each pass, possibly changing the FDE size. I think that is better done by completely recreating PLT eh_frame FDEs. * ehframe.cc (Fde::operator==): New. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): New. * ehframe.h (Fde::operator==): Declare. (Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): Likewise. * layout.cc (Layout::remove_eh_frame_for_plt): New. * layout.h (Layout::remove_eh_frame_for_plt): Declare. * powerpc.cc (Target_powerpc::do_relax): Remove old eh_frame FDEs. (Stub_table::add_eh_frame): Delete eh_frame_added_ condition. Don't add eh_frame for empty stub section. (Stub_table::remove_eh_frame): New.
2017-08-01 12:38:53 +08:00
// Return the number of FDEs.
unsigned int
fde_count() const;
* 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
protected:
// Set the final data size.
void
set_final_data_size();
// Return the output address for an input address.
bool
do_output_offset(const Relobj*, unsigned int shndx,
section_offset_type offset,
section_offset_type* poutput) const;
// Write the data to the file.
void
do_write(Output_file*);
* 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
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** eh_frame")); }
private:
// The comparison routine for the CIE map.
struct Cie_less
{
bool
operator()(const Cie* cie1, const Cie* cie2) const
{ return *cie1 < *cie2; }
};
2008-02-02 14:50:45 +08:00
// A set of unique CIEs.
typedef std::set<Cie*, Cie_less> Cie_offsets;
2008-02-02 14:50:45 +08:00
// A list of unmergeable CIEs.
typedef std::vector<Cie*> Unmergeable_cie_offsets;
// A mapping from offsets to CIEs. This is used while reading an
// input section.
typedef std::map<uint64_t, Cie*> Offsets_to_cie;
// A list of CIEs, and a bool indicating whether the CIE is
// mergeable.
typedef std::vector<std::pair<Cie*, bool> > New_cies;
// Skip an LEB128.
static bool
skip_leb128(const unsigned char**, const unsigned char*);
// The implementation of add_ehframe_input_section.
template<int size, bool big_endian>
bool
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc info; adjust display of GOT entries. * incremental.cc (Sized_incremental_binary::setup_readers): Allocate vector of input objects; remove file_status_. (Sized_incremental_binary::do_reserve_layout): Remove file_status_. (Sized_incremental_binary::do_process_got_plt): Adjust calls to got_plt reader; call target hooks to reserve GOT entries. (Output_section_incremental_inputs::set_final_data_size): Adjust size of input file info header and GOT info entry. (Output_section_incremental_inputs::write_info_blocks): Write dynamic relocation info. (Got_plt_view_info::got_descriptor): Remove. (Got_plt_view_info::sym_index): New data member. (Got_plt_view_info::input_index): New data member. (Local_got_offset_visitor::visit): Write input file index. (Global_got_offset_visitor::visit): Write 0 for input file index. (Global_symbol_visitor_got_plt::operator()): Replace got_descriptor with sym_index and input_index. (Output_section_incremental_inputs::write_got_plt): Adjust size of incremental info GOT entry; replace got_descriptor with input_index. (Sized_relobj_incr::Sized_relobj_incr): Adjust initializers; record map from input file index to object. (Sized_relobj_incr::do_layout): Replace direct data member reference with accessor function. (Sized_relobj_incr::do_for_all_local_got_entries): Move to base class. * incremental.h (Incremental_input_entry_reader::get_symbol_offset): Adjust size of input file info header. (Incremental_input_entry_reader::get_first_dyn_reloc): New function. (Incremental_input_entry_reader::get_dyn_reloc_count): New function. (Incremental_input_entry_reader::get_input_section): Adjust size of input file info header. (Incremental_got_plt_reader::Incremental_got_plt_reader): Adjust size of incremental info GOT entry. (Incremental_got_plt_reader::get_got_desc): Remove. (Incremental_got_plt_reader::get_got_symndx): New function. (Incremental_got_plt_reader::get_got_input_index): New function. (Sized_incremental_binary::Sized_incremental_binary): Remove file_status_; add input_objects_. (Sized_incremental_binary::~Sized_incremental_binary): Remove. (Sized_incremental_binary::set_file_is_unchanged): Remove. (Sized_incremental_binary::file_is_unchanged): Remove. (Sized_incremental_binary::set_input_object): New function. (Sized_incremental_binary::input_object): New function. (Sized_incremental_binary::file_status_): Remove. (Sized_incremental_binary::input_objects_): New data member. (Sized_relobj_incr): Rename Sized_incr_relobj to this; adjust all references. (Sized_relobj_incr::invalid_address): Move to base class. (Sized_relobj_incr::is_output_section_offset_invalid): Move to base class. (Sized_relobj_incr::do_output_section_offset): Likewise. (Sized_relobj_incr::do_for_all_local_got_entries): Likewise. (Sized_relobj_incr::section_offsets_): Likewise. * object.cc (Sized_relobj::do_for_all_local_got_entries): New function. (Sized_relobj_file::Sized_relobj_file): Remove local_got_offsets_. (Sized_relobj_file::layout_section): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_layout): Likewise. (Sized_relobj_file::do_layout_deferred_sections): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Move to base class. (Sized_relobj_file::compute_final_local_value): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_finalize_local_symbols): Likewise. * object.h (Relobj::Relobj): Initialize new data members. (Relobj::add_dyn_reloc): New function. (Relobj::first_dyn_reloc): New function. (Relobj::dyn_reloc_count): New function. (Relobj::first_dyn_reloc_): New data member. (Relobj::dyn_reloc_count_): New data member. (Sized_relobj): Rename Sized_relobj_base to this; adjust all references. (Sized_relobj::Address): New typedef. (Sized_relobj::invalid_address): Move here from child class. (Sized_relobj::Sized_relobj): Initialize new data members. (Sized_relobj::sized_relobj): New function. (Sized_relobj::is_output_section_offset_invalid): Move here from child class. (Sized_relobj::get_output_section_offset): Likewise. (Sized_relobj::local_has_got_offset): Likewise. (Sized_relobj::local_got_offset): Likewise. (Sized_relobj::set_local_got_offset): Likewise. (Sized_relobj::do_for_all_local_got_entries): Likewise. (Sized_relobj::clear_got_offsets): New function. (Sized_relobj::section_offsets): Move here from child class. (Sized_relobj::do_output_section_offset): Likewise. (Sized_relobj::do_set_section_offset): Likewise. (Sized_relobj::Local_got_offsets): Likewise. (Sized_relobj::local_got_offsets_): Likewise. (Sized_relobj::section_offsets_): Likewise. (Sized_relobj_file): Rename Sized_relobj to this; adjust all references. (Sized_relobj_file::is_output_section_offset_invalid): Move to base class. (Sized_relobj_file::sized_relobj): New function (Sized_relobj_file::local_has_got_offset): Move to base class. (Sized_relobj_file::local_got_offset): Likewise. (Sized_relobj_file::set_local_got_offset): Likewise. (Sized_relobj_file::get_output_section_offset): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Likewise. (Sized_relobj_file::do_output_section_offset): Likewise. (Sized_relobj_file::do_set_section_offset): Likewise. (Sized_relobj_file::Local_got_offsets): Likewise. (Sized_relobj_file::local_got_offsets_): Likewise. (Sized_relobj_file::section_offsets_): Likewise. * output.cc (Output_reloc::Output_reloc): Adjust type of relobj (all constructors). (set_needs_dynsym_index): Convert relobj to derived class pointer. (Output_reloc::get_symbol_index): Likewise. (Output_reloc::local_section_offset): Likewise. (Output_reloc::get_address): Likewise. (Output_reloc::symbol_value): Likewise. (Output_data_got::reserve_slot): Move to class definition. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_slot_for_global): Remove. (Output_data_got::reserve_global): New function. * output.h (Output_reloc::Output_reloc): Adjust type of relobj (all constructors, two instantiations). (Output_reloc::get_relobj): New function (two instantiations). (Output_reloc::u1_.relobj, Output_reloc::u2_.relobj): Adjust type. (Output_data_reloc_base::add): Convert relobj to derived class pointer. (Output_data_reloc::add_global): Adjust type of relobj. (Output_data_reloc::add_global_relative): Likewise. (Output_data_reloc::add_symbolless_global_addend): Likewise. (Output_data_reloc::add_local): Likewise. (Output_data_reloc::add_local_relative): Likewise. (Output_data_reloc::add_symbolless_local_addend): Likewise. (Output_data_reloc::add_local_section): Likewise. (Output_data_reloc::add_output_section): Likewise. (Output_data_reloc::add_absolute): Likewise. (Output_data_reloc::add_target_specific): Likewise. (Output_data_got::reserve_slot): Move definition here. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_global): New function. * reloc.cc (Sized_relobj_file::do_read_relocs): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::write_sections): Likewise. (Sized_relobj_file::do_relocate_sections): Likewise. * target.h (Sized_target::reserve_local_got_entry): New function. (Sized_target::reserve_global_got_entry): New function. * x86_64.cc (Target_x86_64::reserve_local_got_entry): New function. (Target_x86_64::reserve_global_got_entry): New function. (Target_x86_64::init_got_plt_for_update): Create rela_dyn section.
2011-05-25 05:41:10 +08:00
do_add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
const unsigned char* symbols,
section_size_type symbols_size,
const unsigned char* symbol_names,
section_size_type symbol_names_size,
unsigned int shndx,
unsigned int reloc_shndx,
unsigned int reloc_type,
const unsigned char* pcontents,
section_size_type contents_len,
New_cies*);
// Read a CIE.
template<int size, bool big_endian>
bool
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc info; adjust display of GOT entries. * incremental.cc (Sized_incremental_binary::setup_readers): Allocate vector of input objects; remove file_status_. (Sized_incremental_binary::do_reserve_layout): Remove file_status_. (Sized_incremental_binary::do_process_got_plt): Adjust calls to got_plt reader; call target hooks to reserve GOT entries. (Output_section_incremental_inputs::set_final_data_size): Adjust size of input file info header and GOT info entry. (Output_section_incremental_inputs::write_info_blocks): Write dynamic relocation info. (Got_plt_view_info::got_descriptor): Remove. (Got_plt_view_info::sym_index): New data member. (Got_plt_view_info::input_index): New data member. (Local_got_offset_visitor::visit): Write input file index. (Global_got_offset_visitor::visit): Write 0 for input file index. (Global_symbol_visitor_got_plt::operator()): Replace got_descriptor with sym_index and input_index. (Output_section_incremental_inputs::write_got_plt): Adjust size of incremental info GOT entry; replace got_descriptor with input_index. (Sized_relobj_incr::Sized_relobj_incr): Adjust initializers; record map from input file index to object. (Sized_relobj_incr::do_layout): Replace direct data member reference with accessor function. (Sized_relobj_incr::do_for_all_local_got_entries): Move to base class. * incremental.h (Incremental_input_entry_reader::get_symbol_offset): Adjust size of input file info header. (Incremental_input_entry_reader::get_first_dyn_reloc): New function. (Incremental_input_entry_reader::get_dyn_reloc_count): New function. (Incremental_input_entry_reader::get_input_section): Adjust size of input file info header. (Incremental_got_plt_reader::Incremental_got_plt_reader): Adjust size of incremental info GOT entry. (Incremental_got_plt_reader::get_got_desc): Remove. (Incremental_got_plt_reader::get_got_symndx): New function. (Incremental_got_plt_reader::get_got_input_index): New function. (Sized_incremental_binary::Sized_incremental_binary): Remove file_status_; add input_objects_. (Sized_incremental_binary::~Sized_incremental_binary): Remove. (Sized_incremental_binary::set_file_is_unchanged): Remove. (Sized_incremental_binary::file_is_unchanged): Remove. (Sized_incremental_binary::set_input_object): New function. (Sized_incremental_binary::input_object): New function. (Sized_incremental_binary::file_status_): Remove. (Sized_incremental_binary::input_objects_): New data member. (Sized_relobj_incr): Rename Sized_incr_relobj to this; adjust all references. (Sized_relobj_incr::invalid_address): Move to base class. (Sized_relobj_incr::is_output_section_offset_invalid): Move to base class. (Sized_relobj_incr::do_output_section_offset): Likewise. (Sized_relobj_incr::do_for_all_local_got_entries): Likewise. (Sized_relobj_incr::section_offsets_): Likewise. * object.cc (Sized_relobj::do_for_all_local_got_entries): New function. (Sized_relobj_file::Sized_relobj_file): Remove local_got_offsets_. (Sized_relobj_file::layout_section): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_layout): Likewise. (Sized_relobj_file::do_layout_deferred_sections): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Move to base class. (Sized_relobj_file::compute_final_local_value): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_finalize_local_symbols): Likewise. * object.h (Relobj::Relobj): Initialize new data members. (Relobj::add_dyn_reloc): New function. (Relobj::first_dyn_reloc): New function. (Relobj::dyn_reloc_count): New function. (Relobj::first_dyn_reloc_): New data member. (Relobj::dyn_reloc_count_): New data member. (Sized_relobj): Rename Sized_relobj_base to this; adjust all references. (Sized_relobj::Address): New typedef. (Sized_relobj::invalid_address): Move here from child class. (Sized_relobj::Sized_relobj): Initialize new data members. (Sized_relobj::sized_relobj): New function. (Sized_relobj::is_output_section_offset_invalid): Move here from child class. (Sized_relobj::get_output_section_offset): Likewise. (Sized_relobj::local_has_got_offset): Likewise. (Sized_relobj::local_got_offset): Likewise. (Sized_relobj::set_local_got_offset): Likewise. (Sized_relobj::do_for_all_local_got_entries): Likewise. (Sized_relobj::clear_got_offsets): New function. (Sized_relobj::section_offsets): Move here from child class. (Sized_relobj::do_output_section_offset): Likewise. (Sized_relobj::do_set_section_offset): Likewise. (Sized_relobj::Local_got_offsets): Likewise. (Sized_relobj::local_got_offsets_): Likewise. (Sized_relobj::section_offsets_): Likewise. (Sized_relobj_file): Rename Sized_relobj to this; adjust all references. (Sized_relobj_file::is_output_section_offset_invalid): Move to base class. (Sized_relobj_file::sized_relobj): New function (Sized_relobj_file::local_has_got_offset): Move to base class. (Sized_relobj_file::local_got_offset): Likewise. (Sized_relobj_file::set_local_got_offset): Likewise. (Sized_relobj_file::get_output_section_offset): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Likewise. (Sized_relobj_file::do_output_section_offset): Likewise. (Sized_relobj_file::do_set_section_offset): Likewise. (Sized_relobj_file::Local_got_offsets): Likewise. (Sized_relobj_file::local_got_offsets_): Likewise. (Sized_relobj_file::section_offsets_): Likewise. * output.cc (Output_reloc::Output_reloc): Adjust type of relobj (all constructors). (set_needs_dynsym_index): Convert relobj to derived class pointer. (Output_reloc::get_symbol_index): Likewise. (Output_reloc::local_section_offset): Likewise. (Output_reloc::get_address): Likewise. (Output_reloc::symbol_value): Likewise. (Output_data_got::reserve_slot): Move to class definition. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_slot_for_global): Remove. (Output_data_got::reserve_global): New function. * output.h (Output_reloc::Output_reloc): Adjust type of relobj (all constructors, two instantiations). (Output_reloc::get_relobj): New function (two instantiations). (Output_reloc::u1_.relobj, Output_reloc::u2_.relobj): Adjust type. (Output_data_reloc_base::add): Convert relobj to derived class pointer. (Output_data_reloc::add_global): Adjust type of relobj. (Output_data_reloc::add_global_relative): Likewise. (Output_data_reloc::add_symbolless_global_addend): Likewise. (Output_data_reloc::add_local): Likewise. (Output_data_reloc::add_local_relative): Likewise. (Output_data_reloc::add_symbolless_local_addend): Likewise. (Output_data_reloc::add_local_section): Likewise. (Output_data_reloc::add_output_section): Likewise. (Output_data_reloc::add_absolute): Likewise. (Output_data_reloc::add_target_specific): Likewise. (Output_data_got::reserve_slot): Move definition here. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_global): New function. * reloc.cc (Sized_relobj_file::do_read_relocs): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::write_sections): Likewise. (Sized_relobj_file::do_relocate_sections): Likewise. * target.h (Sized_target::reserve_local_got_entry): New function. (Sized_target::reserve_global_got_entry): New function. * x86_64.cc (Target_x86_64::reserve_local_got_entry): New function. (Target_x86_64::reserve_global_got_entry): New function. (Target_x86_64::init_got_plt_for_update): Create rela_dyn section.
2011-05-25 05:41:10 +08:00
read_cie(Sized_relobj_file<size, big_endian>* object,
unsigned int shndx,
const unsigned char* symbols,
section_size_type symbols_size,
const unsigned char* symbol_names,
section_size_type symbol_names_size,
const unsigned char* pcontents,
const unsigned char* pcie,
const unsigned char* pcieend,
Track_relocs<size, big_endian>* relocs,
Offsets_to_cie* cies,
New_cies* new_cies);
// Read an FDE.
template<int size, bool big_endian>
bool
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc info; adjust display of GOT entries. * incremental.cc (Sized_incremental_binary::setup_readers): Allocate vector of input objects; remove file_status_. (Sized_incremental_binary::do_reserve_layout): Remove file_status_. (Sized_incremental_binary::do_process_got_plt): Adjust calls to got_plt reader; call target hooks to reserve GOT entries. (Output_section_incremental_inputs::set_final_data_size): Adjust size of input file info header and GOT info entry. (Output_section_incremental_inputs::write_info_blocks): Write dynamic relocation info. (Got_plt_view_info::got_descriptor): Remove. (Got_plt_view_info::sym_index): New data member. (Got_plt_view_info::input_index): New data member. (Local_got_offset_visitor::visit): Write input file index. (Global_got_offset_visitor::visit): Write 0 for input file index. (Global_symbol_visitor_got_plt::operator()): Replace got_descriptor with sym_index and input_index. (Output_section_incremental_inputs::write_got_plt): Adjust size of incremental info GOT entry; replace got_descriptor with input_index. (Sized_relobj_incr::Sized_relobj_incr): Adjust initializers; record map from input file index to object. (Sized_relobj_incr::do_layout): Replace direct data member reference with accessor function. (Sized_relobj_incr::do_for_all_local_got_entries): Move to base class. * incremental.h (Incremental_input_entry_reader::get_symbol_offset): Adjust size of input file info header. (Incremental_input_entry_reader::get_first_dyn_reloc): New function. (Incremental_input_entry_reader::get_dyn_reloc_count): New function. (Incremental_input_entry_reader::get_input_section): Adjust size of input file info header. (Incremental_got_plt_reader::Incremental_got_plt_reader): Adjust size of incremental info GOT entry. (Incremental_got_plt_reader::get_got_desc): Remove. (Incremental_got_plt_reader::get_got_symndx): New function. (Incremental_got_plt_reader::get_got_input_index): New function. (Sized_incremental_binary::Sized_incremental_binary): Remove file_status_; add input_objects_. (Sized_incremental_binary::~Sized_incremental_binary): Remove. (Sized_incremental_binary::set_file_is_unchanged): Remove. (Sized_incremental_binary::file_is_unchanged): Remove. (Sized_incremental_binary::set_input_object): New function. (Sized_incremental_binary::input_object): New function. (Sized_incremental_binary::file_status_): Remove. (Sized_incremental_binary::input_objects_): New data member. (Sized_relobj_incr): Rename Sized_incr_relobj to this; adjust all references. (Sized_relobj_incr::invalid_address): Move to base class. (Sized_relobj_incr::is_output_section_offset_invalid): Move to base class. (Sized_relobj_incr::do_output_section_offset): Likewise. (Sized_relobj_incr::do_for_all_local_got_entries): Likewise. (Sized_relobj_incr::section_offsets_): Likewise. * object.cc (Sized_relobj::do_for_all_local_got_entries): New function. (Sized_relobj_file::Sized_relobj_file): Remove local_got_offsets_. (Sized_relobj_file::layout_section): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_layout): Likewise. (Sized_relobj_file::do_layout_deferred_sections): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Move to base class. (Sized_relobj_file::compute_final_local_value): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::do_finalize_local_symbols): Likewise. * object.h (Relobj::Relobj): Initialize new data members. (Relobj::add_dyn_reloc): New function. (Relobj::first_dyn_reloc): New function. (Relobj::dyn_reloc_count): New function. (Relobj::first_dyn_reloc_): New data member. (Relobj::dyn_reloc_count_): New data member. (Sized_relobj): Rename Sized_relobj_base to this; adjust all references. (Sized_relobj::Address): New typedef. (Sized_relobj::invalid_address): Move here from child class. (Sized_relobj::Sized_relobj): Initialize new data members. (Sized_relobj::sized_relobj): New function. (Sized_relobj::is_output_section_offset_invalid): Move here from child class. (Sized_relobj::get_output_section_offset): Likewise. (Sized_relobj::local_has_got_offset): Likewise. (Sized_relobj::local_got_offset): Likewise. (Sized_relobj::set_local_got_offset): Likewise. (Sized_relobj::do_for_all_local_got_entries): Likewise. (Sized_relobj::clear_got_offsets): New function. (Sized_relobj::section_offsets): Move here from child class. (Sized_relobj::do_output_section_offset): Likewise. (Sized_relobj::do_set_section_offset): Likewise. (Sized_relobj::Local_got_offsets): Likewise. (Sized_relobj::local_got_offsets_): Likewise. (Sized_relobj::section_offsets_): Likewise. (Sized_relobj_file): Rename Sized_relobj to this; adjust all references. (Sized_relobj_file::is_output_section_offset_invalid): Move to base class. (Sized_relobj_file::sized_relobj): New function (Sized_relobj_file::local_has_got_offset): Move to base class. (Sized_relobj_file::local_got_offset): Likewise. (Sized_relobj_file::set_local_got_offset): Likewise. (Sized_relobj_file::get_output_section_offset): Likewise. (Sized_relobj_file::do_for_all_local_got_entries): Likewise. (Sized_relobj_file::do_output_section_offset): Likewise. (Sized_relobj_file::do_set_section_offset): Likewise. (Sized_relobj_file::Local_got_offsets): Likewise. (Sized_relobj_file::local_got_offsets_): Likewise. (Sized_relobj_file::section_offsets_): Likewise. * output.cc (Output_reloc::Output_reloc): Adjust type of relobj (all constructors). (set_needs_dynsym_index): Convert relobj to derived class pointer. (Output_reloc::get_symbol_index): Likewise. (Output_reloc::local_section_offset): Likewise. (Output_reloc::get_address): Likewise. (Output_reloc::symbol_value): Likewise. (Output_data_got::reserve_slot): Move to class definition. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_slot_for_global): Remove. (Output_data_got::reserve_global): New function. * output.h (Output_reloc::Output_reloc): Adjust type of relobj (all constructors, two instantiations). (Output_reloc::get_relobj): New function (two instantiations). (Output_reloc::u1_.relobj, Output_reloc::u2_.relobj): Adjust type. (Output_data_reloc_base::add): Convert relobj to derived class pointer. (Output_data_reloc::add_global): Adjust type of relobj. (Output_data_reloc::add_global_relative): Likewise. (Output_data_reloc::add_symbolless_global_addend): Likewise. (Output_data_reloc::add_local): Likewise. (Output_data_reloc::add_local_relative): Likewise. (Output_data_reloc::add_symbolless_local_addend): Likewise. (Output_data_reloc::add_local_section): Likewise. (Output_data_reloc::add_output_section): Likewise. (Output_data_reloc::add_absolute): Likewise. (Output_data_reloc::add_target_specific): Likewise. (Output_data_got::reserve_slot): Move definition here. (Output_data_got::reserve_local): New function. (Output_data_got::reserve_global): New function. * reloc.cc (Sized_relobj_file::do_read_relocs): Replace refs to section_offsets_ with accessor function. (Sized_relobj_file::write_sections): Likewise. (Sized_relobj_file::do_relocate_sections): Likewise. * target.h (Sized_target::reserve_local_got_entry): New function. (Sized_target::reserve_global_got_entry): New function. * x86_64.cc (Target_x86_64::reserve_local_got_entry): New function. (Target_x86_64::reserve_global_got_entry): New function. (Target_x86_64::init_got_plt_for_update): Create rela_dyn section.
2011-05-25 05:41:10 +08:00
read_fde(Sized_relobj_file<size, big_endian>* object,
unsigned int shndx,
const unsigned char* symbols,
section_size_type symbols_size,
const unsigned char* pcontents,
unsigned int offset,
const unsigned char* pfde,
const unsigned char* pfdeend,
Track_relocs<size, big_endian>* relocs,
Offsets_to_cie* cies);
// Template version of write function.
template<int size, bool big_endian>
void
do_sized_write(unsigned char* oview);
// The exception frame header, if any.
Eh_frame_hdr* eh_frame_hdr_;
// A mapping from all unique CIEs to their offset in the output
// file.
Cie_offsets cie_offsets_;
// A mapping from unmergeable CIEs to their offset in the output
// file.
Unmergeable_cie_offsets unmergeable_cie_offsets_;
// Whether we have created the mappings to the output section.
bool mappings_are_done_;
// The final data size. This is only set if mappings_are_done_ is
// true.
section_size_type final_data_size_;
};
} // End namespace gold.
#endif // !defined(GOLD_EHFRAME_H)