OSDN Git Service

daily update
[pf3gnuchains/pf3gnuchains3x.git] / gold / ehframe.h
index 12c8c16..4726ffc 100644 (file)
@@ -1,6 +1,6 @@
 // ehframe.h -- handle exception frame sections for gold  -*- C++ -*-
 
-// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
 #ifndef GOLD_EHFRAME_H
 #define GOLD_EHFRAME_H
 
+#include <map>
+#include <set>
+#include <vector>
+
 #include "output.h"
 #include "merge.h"
 
@@ -57,12 +61,13 @@ class Eh_frame_hdr : public Output_section_data
 
   // Record an FDE.
   void
-  record_fde(off_t fde_offset, unsigned char fde_encoding)
+  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));
   }
 
+ protected:
   // Set the final data size.
   void
   set_final_data_size();
@@ -71,6 +76,11 @@ class Eh_frame_hdr : public Output_section_data
   void
   do_write(Output_file*);
 
+  // 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>
@@ -79,7 +89,7 @@ class Eh_frame_hdr : public Output_section_data
 
   // The data we record for one FDE: the offset of the FDE within the
   // .eh_frame section, and the FDE encoding.
-  typedef std::pair<off_t, unsigned char> Fde_offset;
+  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;
@@ -131,8 +141,9 @@ class Eh_frame_hdr : public Output_section_data
   // Return the PC to which an FDE refers.
   template<int size, bool big_endian>
   typename elfcpp::Elf_types<size>::Elf_Addr
-  get_fde_pc(const unsigned char* eh_frame_contents,
-            off_t fde_offset, unsigned char fde_encoding);
+  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>
@@ -157,7 +168,7 @@ class Eh_frame_hdr : public Output_section_data
 class Fde
 {
  public:
-  Fde(Relobj* object, unsigned int shndx, off_t input_offset,
+  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)
@@ -171,7 +182,7 @@ class Fde
 
   // Add a mapping for this FDE to MERGE_MAP.
   void
-  add_mapping(off_t output_offset, Merge_map* merge_map) const
+  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(),
@@ -179,12 +190,14 @@ class Fde
   }
 
   // Write the FDE to OVIEW starting at OFFSET.  FDE_ENCODING is the
-  // encoding, from the CIE.  Record the FDE in EH_FRAME_HDR.  Return
-  // the new offset.
+  // 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>
-  off_t
-  write(unsigned char* oview, off_t offset, off_t cie_offset,
-       unsigned char fde_encoding, Eh_frame_hdr* eh_frame_hdr);
+  section_offset_type
+  write(unsigned char* oview, section_offset_type offset,
+       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.
@@ -192,7 +205,7 @@ class Fde
   // Input section index for this FDE.
   unsigned int shndx_;
   // Offset within the input section for this FDE.
-  off_t input_offset_;
+  section_offset_type input_offset_;
   // FDE data.
   std::string contents_;
 };
@@ -202,7 +215,7 @@ class Fde
 class Cie
 {
  public:
-  Cie(Relobj* object, unsigned int shndx, off_t input_offset,
+  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),
@@ -242,14 +255,17 @@ class Cie
   // 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.
-  off_t
-  set_output_offset(off_t output_offset, unsigned int addralign, Merge_map*);
+  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
-  // exception frame header for FDE recording.  Return the new offset.
+  // exception frame header for FDE recording.  Round up the bytes to
+  // ADDRALIGN.  Return the new offset.
   template<int size, bool big_endian>
-  off_t
-  write(unsigned char* oview, off_t offset, Eh_frame_hdr* eh_frame_hdr);
+  section_offset_type
+  write(unsigned char* oview, section_offset_type offset,
+       unsigned int addralign, Eh_frame_hdr* eh_frame_hdr);
 
   friend bool operator<(const Cie&, const Cie&);
   friend bool operator==(const Cie&, const Cie&);
@@ -263,7 +279,7 @@ class Cie
   // Input section index for this CIE.
   unsigned int shndx_;
   // Offset within the input section for this CIE.
-  off_t input_offset_;
+  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
@@ -302,9 +318,9 @@ class Eh_frame : public Output_section_data
   bool
   add_ehframe_input_section(Sized_relobj<size, big_endian>* object,
                            const unsigned char* symbols,
-                           off_t symbols_size,
+                           section_size_type symbols_size,
                            const unsigned char* symbol_names,
-                           off_t symbol_names_size,
+                           section_size_type symbol_names_size,
                            unsigned int shndx, unsigned int reloc_shndx,
                            unsigned int reloc_type);
 
@@ -312,19 +328,30 @@ class Eh_frame : public Output_section_data
   unsigned int
   fde_count() const;
 
+ 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, off_t offset,
-                  off_t* poutput) const;
+  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*);
 
+  // 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
@@ -334,11 +361,11 @@ class Eh_frame : public Output_section_data
     { return *cie1 < *cie2; }
   };
 
-  // A mapping from unique CIEs to their offset in the output file.
-  typedef std::map<Cie*, uint64_t, Cie_less> Cie_offsets;
+  // A set of unique CIEs.
+  typedef std::set<Cie*, Cie_less> Cie_offsets;
 
-  // A list of unmergeable CIEs with their offsets.
-  typedef std::vector<std::pair<Cie*, uint64_t> > Unmergeable_cie_offsets;
+  // 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.
@@ -357,14 +384,14 @@ class Eh_frame : public Output_section_data
   bool
   do_add_ehframe_input_section(Sized_relobj<size, big_endian>* object,
                               const unsigned char* symbols,
-                              off_t symbols_size,
+                              section_size_type symbols_size,
                               const unsigned char* symbol_names,
-                              off_t symbol_names_size,
+                              section_size_type symbol_names_size,
                               unsigned int shndx,
                               unsigned int reloc_shndx,
                               unsigned int reloc_type,
                               const unsigned char* pcontents,
-                              off_t contents_len,
+                              section_size_type contents_len,
                               New_cies*);
 
   // Read a CIE.
@@ -373,9 +400,9 @@ class Eh_frame : public Output_section_data
   read_cie(Sized_relobj<size, big_endian>* object,
           unsigned int shndx,
           const unsigned char* symbols,
-          off_t symbols_size,
+          section_size_type symbols_size,
           const unsigned char* symbol_names,
-          off_t symbol_names_size,
+          section_size_type symbol_names_size,
           const unsigned char* pcontents,
           const unsigned char* pcie,
           const unsigned char *pcieend,
@@ -389,7 +416,7 @@ class Eh_frame : public Output_section_data
   read_fde(Sized_relobj<size, big_endian>* object,
           unsigned int shndx,
           const unsigned char* symbols,
-          off_t symbols_size,
+          section_size_type symbols_size,
           const unsigned char* pcontents,
           unsigned int offset,
           const unsigned char* pfde,
@@ -412,6 +439,11 @@ class Eh_frame : public Output_section_data
   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.