OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [ehframe.cc] - Diff between revs 27 and 159

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 27 Rev 159
Line 1... Line 1...
// ehframe.cc -- handle exception frame sections for gold
// ehframe.cc -- handle exception frame sections for gold
 
 
// Copyright 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
// Copyright 2006, 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// Written by Ian Lance Taylor <iant@google.com>.
 
 
// This file is part of gold.
// This file is part of gold.
 
 
// This program is free software; you can redistribute it and/or modify
// This program is free software; you can redistribute it and/or modify
Line 264... Line 264...
    default:
    default:
      // All other cases were rejected in Eh_frame::read_cie.
      // All other cases were rejected in Eh_frame::read_cie.
      gold_unreachable();
      gold_unreachable();
    }
    }
 
 
  switch (fde_encoding & 0xf0)
  switch (fde_encoding & 0x70)
    {
    {
    case 0:
    case 0:
      break;
      break;
 
 
    case elfcpp::DW_EH_PE_pcrel:
    case elfcpp::DW_EH_PE_pcrel:
      pc += eh_frame_address + fde_offset + 8;
      pc += eh_frame_address + fde_offset + 8;
      break;
      break;
 
 
 
    case elfcpp::DW_EH_PE_datarel:
 
      pc += parameters->target().ehframe_datarel_base();
 
      break;
 
 
    default:
    default:
      // If other cases arise, then we have to handle them, or we have
      // If other cases arise, then we have to handle them, or we have
      // to reject them by returning false in Eh_frame::read_cie.
      // to reject them by returning false in Eh_frame::read_cie.
      gold_unreachable();
      gold_unreachable();
    }
    }
 
 
 
  gold_assert((fde_encoding & elfcpp::DW_EH_PE_indirect) == 0);
 
 
  return pc;
  return pc;
}
}
 
 
// Given an array of FDE offsets in the .eh_frame section, return an
// Given an array of FDE offsets in the .eh_frame section, return an
// array of offsets from the exception frame header to the FDE's
// array of offsets from the exception frame header to the FDE's
Line 319... Line 325...
 
 
// Class Fde.
// Class Fde.
 
 
// Write the FDE to OVIEW starting at OFFSET.  CIE_OFFSET is the
// Write the FDE to OVIEW starting at OFFSET.  CIE_OFFSET is the
// offset of the CIE in OVIEW.  FDE_ENCODING is the encoding, from the
// offset of the CIE in OVIEW.  FDE_ENCODING is the encoding, from the
// CIE.  ADDRALIGN is the required alignment.  Record the FDE pc for
// CIE.  ADDRALIGN is the required alignment.  ADDRESS is the virtual
// EH_FRAME_HDR.  Return the new offset.
// address of OVIEW.  Record the FDE pc for EH_FRAME_HDR.  Return the
 
// new offset.
 
 
template<int size, bool big_endian>
template<int size, bool big_endian>
section_offset_type
section_offset_type
Fde::write(unsigned char* oview, section_offset_type offset,
Fde::write(unsigned char* oview, section_offset_type offset,
           unsigned int addralign, section_offset_type cie_offset,
           uint64_t address, unsigned int addralign,
           unsigned char fde_encoding, Eh_frame_hdr* eh_frame_hdr)
           section_offset_type cie_offset, unsigned char fde_encoding,
 
           Eh_frame_hdr* eh_frame_hdr)
{
{
  gold_assert((offset & (addralign - 1)) == 0);
  gold_assert((offset & (addralign - 1)) == 0);
 
 
  size_t length = this->contents_.length();
  size_t length = this->contents_.length();
 
 
Line 353... Line 361...
  // Copy the rest of the FDE.  Note that this is run before
  // Copy the rest of the FDE.  Note that this is run before
  // relocation processing is done on this section, so the relocations
  // relocation processing is done on this section, so the relocations
  // will later be applied to the FDE data.
  // will later be applied to the FDE data.
  memcpy(oview + offset + 8, this->contents_.data(), length);
  memcpy(oview + offset + 8, this->contents_.data(), length);
 
 
 
  // If this FDE is associated with a PLT, fill in the PLT's address
 
  // and size.
 
  if (this->object_ == NULL)
 
    {
 
      gold_assert(memcmp(oview + offset + 8, "\0\0\0\0\0\0\0\0", 8) == 0);
 
      Output_data* plt = this->u_.from_linker.plt;
 
      uint64_t poffset = plt->address() - (address + offset + 8);
 
      int32_t spoffset = static_cast<int32_t>(poffset);
 
      off_t psize = plt->data_size();
 
      uint32_t upsize = static_cast<uint32_t>(psize);
 
      if (static_cast<uint64_t>(static_cast<int64_t>(spoffset)) != poffset
 
          || static_cast<off_t>(upsize) != psize)
 
        gold_warning(_("overflow in PLT unwind data; "
 
                       "unwinding through PLT may fail"));
 
      elfcpp::Swap<32, big_endian>::writeval(oview + offset + 8, spoffset);
 
      elfcpp::Swap<32, big_endian>::writeval(oview + offset + 12, upsize);
 
    }
 
 
  if (aligned_full_length > length + 8)
  if (aligned_full_length > length + 8)
    memset(oview + offset + length + 8, 0, aligned_full_length - (length + 8));
    memset(oview + offset + length + 8, 0, aligned_full_length - (length + 8));
 
 
  // Tell the exception frame header about this FDE.
  // Tell the exception frame header about this FDE.
  if (eh_frame_hdr != NULL)
  if (eh_frame_hdr != NULL)
Line 387... Line 413...
  size_t length = this->contents_.length();
  size_t length = this->contents_.length();
 
 
  // Add 4 for length and 4 for zero CIE identifier tag.
  // Add 4 for length and 4 for zero CIE identifier tag.
  length += 8;
  length += 8;
 
 
 
  if (this->object_ != NULL)
 
    {
 
      // Add a mapping so that relocations are applied correctly.
  merge_map->add_mapping(this->object_, this->shndx_, this->input_offset_,
  merge_map->add_mapping(this->object_, this->shndx_, this->input_offset_,
                         length, output_offset);
                         length, output_offset);
 
    }
 
 
  length = align_address(length, addralign);
  length = align_address(length, addralign);
 
 
  for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
  for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
       p != this->fdes_.end();
       p != this->fdes_.end();
Line 413... Line 443...
// offset.
// offset.
 
 
template<int size, bool big_endian>
template<int size, bool big_endian>
section_offset_type
section_offset_type
Cie::write(unsigned char* oview, section_offset_type offset,
Cie::write(unsigned char* oview, section_offset_type offset,
           unsigned int addralign, Eh_frame_hdr* eh_frame_hdr)
           uint64_t address, unsigned int addralign,
 
           Eh_frame_hdr* eh_frame_hdr)
{
{
  gold_assert((offset & (addralign - 1)) == 0);
  gold_assert((offset & (addralign - 1)) == 0);
 
 
  section_offset_type cie_offset = offset;
  section_offset_type cie_offset = offset;
 
 
Line 446... Line 477...
  // Write out the associated FDEs.
  // Write out the associated FDEs.
  unsigned char fde_encoding = this->fde_encoding_;
  unsigned char fde_encoding = this->fde_encoding_;
  for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
  for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
       p != this->fdes_.end();
       p != this->fdes_.end();
       ++p)
       ++p)
    offset = (*p)->write<size, big_endian>(oview, offset, addralign,
    offset = (*p)->write<size, big_endian>(oview, offset, address, addralign,
                                           cie_offset, fde_encoding,
                                           cie_offset, fde_encoding,
                                           eh_frame_hdr);
                                           eh_frame_hdr);
 
 
  return offset;
  return offset;
}
}
Line 992... Line 1023...
                       pfde, pfdeend - pfde));
                       pfde, pfdeend - pfde));
 
 
  return true;
  return true;
}
}
 
 
 
// Add unwind information for a PLT.
 
 
 
void
 
Eh_frame::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)
 
{
 
  Cie cie(NULL, 0, 0, elfcpp::DW_EH_PE_pcrel | elfcpp::DW_EH_PE_sdata4, "",
 
          cie_data, cie_length);
 
  Cie_offsets::iterator find_cie = this->cie_offsets_.find(&cie);
 
  Cie* pcie;
 
  if (find_cie != this->cie_offsets_.end())
 
    pcie = *find_cie;
 
  else
 
    {
 
      pcie = new Cie(cie);
 
      this->cie_offsets_.insert(pcie);
 
    }
 
 
 
  Fde* fde = new Fde(plt, fde_data, fde_length);
 
  pcie->add_fde(fde);
 
}
 
 
// Return the number of FDEs.
// Return the number of FDEs.
 
 
unsigned int
unsigned int
Eh_frame::fde_count() const
Eh_frame::fde_count() const
{
{
Line 1111... Line 1165...
 
 
template<int size, bool big_endian>
template<int size, bool big_endian>
void
void
Eh_frame::do_sized_write(unsigned char* oview)
Eh_frame::do_sized_write(unsigned char* oview)
{
{
 
  uint64_t address = this->address();
  unsigned int addralign = this->addralign();
  unsigned int addralign = this->addralign();
  section_offset_type o = 0;
  section_offset_type o = 0;
  for (Unmergeable_cie_offsets::iterator p =
  for (Unmergeable_cie_offsets::iterator p =
         this->unmergeable_cie_offsets_.begin();
         this->unmergeable_cie_offsets_.begin();
       p != this->unmergeable_cie_offsets_.end();
       p != this->unmergeable_cie_offsets_.end();
       ++p)
       ++p)
    o = (*p)->write<size, big_endian>(oview, o, addralign,
    o = (*p)->write<size, big_endian>(oview, o, address, addralign,
                                      this->eh_frame_hdr_);
                                      this->eh_frame_hdr_);
  for (Cie_offsets::iterator p = this->cie_offsets_.begin();
  for (Cie_offsets::iterator p = this->cie_offsets_.begin();
       p != this->cie_offsets_.end();
       p != this->cie_offsets_.end();
       ++p)
       ++p)
    o = (*p)->write<size, big_endian>(oview, o, addralign,
    o = (*p)->write<size, big_endian>(oview, o, address, addralign,
                                      this->eh_frame_hdr_);
                                      this->eh_frame_hdr_);
}
}
 
 
#ifdef HAVE_TARGET_32_LITTLE
#ifdef HAVE_TARGET_32_LITTLE
template
template

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.