binutils-gdb/gold/ehframe.h

452 lines
14 KiB
C
Raw Normal View History

// ehframe.h -- handle exception frame sections for gold -*- C++ -*-
// Copyright 2006, 2007, 2008 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.
// FIXME: gcc supports using storing a sorted lookup table for the
// FDEs in the PT_GNU_EH_FRAME segment, but we do not yet generate
// that.
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)
: object_(object), shndx_(shndx), input_offset_(input_offset),
contents_(reinterpret_cast<const char*>(contents), length)
{ }
// 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; }
// Add a mapping for this FDE to MERGE_MAP.
void
add_mapping(section_offset_type output_offset, Merge_map* merge_map) const
{
merge_map->add_mapping(this->object_, this->shndx_,
this->input_offset_, this->length(),
output_offset);
}
// 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
// necessary. Record the FDE in EH_FRAME_HDR. Return the new
// offset.
template<int size, bool big_endian>
section_offset_type
write(unsigned char* oview, section_offset_type offset,
2008-02-14 10:40:15 +08:00
unsigned int addralign, section_offset_type cie_offset,
unsigned char fde_encoding, Eh_frame_hdr* eh_frame_hdr);
private:
// The object in which this FDE was seen.
Relobj* object_;
// Input section index for this FDE.
unsigned int shndx_;
// Offset within the input section for this FDE.
section_offset_type input_offset_;
// FDE data.
std::string contents_;
};
// 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); }
// 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,
Merge_map*);
// Write the CIE to OVIEW starting at OFFSET. EH_FRAME_HDR is the
2008-02-14 10:40:15 +08:00
// exception frame header for FDE recording. Round up the bytes to
// ADDRALIGN. Return the new offset.
template<int size, bool big_endian>
section_offset_type
write(unsigned char* oview, section_offset_type offset,
2008-02-14 10:40:15 +08:00
unsigned int addralign, Eh_frame_hdr* eh_frame_hdr);
friend bool operator<(const Cie&, const Cie&);
friend bool operator==(const Cie&, const Cie&);
private:
// The class is not assignable.
Cie& operator=(const Cie&);
// The object in which this CIE was first seen.
Relobj* object_;
// Input section index for this CIE.
unsigned int shndx_;
// Offset within the input section for this 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:
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>
bool
add_ehframe_input_section(Sized_relobj<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);
// 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;
// Return whether this is the merge section for an input section.
bool
do_is_merge_section_for(const Relobj*, unsigned int shndx) 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
do_add_ehframe_input_section(Sized_relobj<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
read_cie(Sized_relobj<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
read_fde(Sized_relobj<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_;
// A mapping from input sections to the output section.
Merge_map merge_map_;
// 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)