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

Subversion Repositories open8_urisc

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

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

Rev 148 Rev 159
Line 34... Line 34...
#include <sys/mman.h>
#include <sys/mman.h>
#endif
#endif
 
 
#include "libiberty.h"
#include "libiberty.h"
 
 
 
#include "dwarf.h"
#include "parameters.h"
#include "parameters.h"
#include "object.h"
#include "object.h"
#include "symtab.h"
#include "symtab.h"
#include "reloc.h"
#include "reloc.h"
#include "merge.h"
#include "merge.h"
#include "descriptors.h"
#include "descriptors.h"
 
#include "layout.h"
#include "output.h"
#include "output.h"
 
 
// For systems without mmap support.
// For systems without mmap support.
#ifndef HAVE_MMAP
#ifndef HAVE_MMAP
# define mmap gold_mmap
# define mmap gold_mmap
Line 1344... Line 1346...
        // If the symbol is resolved locally, we need to write out the
        // If the symbol is resolved locally, we need to write out the
        // link-time value, which will be relocated dynamically by a
        // link-time value, which will be relocated dynamically by a
        // RELATIVE relocation.
        // RELATIVE relocation.
        Symbol* gsym = this->u_.gsym;
        Symbol* gsym = this->u_.gsym;
        if (this->use_plt_offset_ && gsym->has_plt_offset())
        if (this->use_plt_offset_ && gsym->has_plt_offset())
          val = (parameters->target().plt_section_for_global(gsym)->address()
          val = (parameters->target().plt_address_for_global(gsym)
                 + gsym->plt_offset());
                 + gsym->plt_offset());
        else
        else
          {
          {
            Sized_symbol<size>* sgsym;
            Sized_symbol<size>* sgsym;
            // This cast is a bit ugly.  We don't want to put a
            // This cast is a bit ugly.  We don't want to put a
Line 1378... Line 1380...
        const Symbol_value<size>* symval = object->local_symbol(lsi);
        const Symbol_value<size>* symval = object->local_symbol(lsi);
        if (!this->use_plt_offset_)
        if (!this->use_plt_offset_)
          val = symval->value(this->u_.object, 0);
          val = symval->value(this->u_.object, 0);
        else
        else
          {
          {
            const Output_data* plt =
            uint64_t plt_address =
              parameters->target().plt_section_for_local(object, lsi);
              parameters->target().plt_address_for_local(object, lsi);
            val = plt->address() + object->local_plt_offset(lsi);
            val = plt_address + object->local_plt_offset(lsi);
          }
          }
      }
      }
      break;
      break;
    }
    }
 
 
Line 1923... Line 1925...
      gold_assert(symndx * 4 < this->data_size());
      gold_assert(symndx * 4 < this->data_size());
      elfcpp::Swap<32, big_endian>::writeval(oview + symndx * 4, p->second);
      elfcpp::Swap<32, big_endian>::writeval(oview + symndx * 4, p->second);
    }
    }
}
}
 
 
 
// Output_fill_debug_info methods.
 
 
 
// Return the minimum size needed for a dummy compilation unit header.
 
 
 
size_t
 
Output_fill_debug_info::do_minimum_hole_size() const
 
{
 
  // Compile unit header fields: unit_length, version, debug_abbrev_offset,
 
  // address_size.
 
  const size_t len = 4 + 2 + 4 + 1;
 
  // For type units, add type_signature, type_offset.
 
  if (this->is_debug_types_)
 
    return len + 8 + 4;
 
  return len;
 
}
 
 
 
// Write a dummy compilation unit header to fill a hole in the
 
// .debug_info or .debug_types section.
 
 
 
void
 
Output_fill_debug_info::do_write(Output_file* of, off_t off, size_t len) const
 
{
 
  gold_debug(DEBUG_INCREMENTAL, "fill_debug_info(%08lx, %08lx)", off, len);
 
 
 
  gold_assert(len >= this->do_minimum_hole_size());
 
 
 
  unsigned char* const oview = of->get_output_view(off, len);
 
  unsigned char* pov = oview;
 
 
 
  // Write header fields: unit_length, version, debug_abbrev_offset,
 
  // address_size.
 
  if (this->is_big_endian())
 
    {
 
      elfcpp::Swap<32, true>::writeval(pov, len - 4);
 
      elfcpp::Swap<16, true>::writeval(pov + 4, this->version);
 
      elfcpp::Swap<32, true>::writeval(pov + 6, 0);
 
    }
 
  else
 
    {
 
      elfcpp::Swap<32, false>::writeval(pov, len - 4);
 
      elfcpp::Swap<16, false>::writeval(pov + 4, this->version);
 
      elfcpp::Swap<32, false>::writeval(pov + 6, 0);
 
    }
 
  pov += 4 + 2 + 4;
 
  *pov++ = 4;
 
 
 
  // For type units, the additional header fields -- type_signature,
 
  // type_offset -- can be filled with zeroes.
 
 
 
  // Fill the remainder of the free space with zeroes.  The first
 
  // zero should tell the consumer there are no DIEs to read in this
 
  // compilation unit.
 
  if (pov < oview + len)
 
    memset(pov, 0, oview + len - pov);
 
 
 
  of->write_output_view(off, len, oview);
 
}
 
 
 
// Output_fill_debug_line methods.
 
 
 
// Return the minimum size needed for a dummy line number program header.
 
 
 
size_t
 
Output_fill_debug_line::do_minimum_hole_size() const
 
{
 
  // Line number program header fields: unit_length, version, header_length,
 
  // minimum_instruction_length, default_is_stmt, line_base, line_range,
 
  // opcode_base, standard_opcode_lengths[], include_directories, filenames.
 
  const size_t len = 4 + 2 + 4 + this->header_length;
 
  return len;
 
}
 
 
 
// Write a dummy line number program header to fill a hole in the
 
// .debug_line section.
 
 
 
void
 
Output_fill_debug_line::do_write(Output_file* of, off_t off, size_t len) const
 
{
 
  gold_debug(DEBUG_INCREMENTAL, "fill_debug_line(%08lx, %08lx)", off, len);
 
 
 
  gold_assert(len >= this->do_minimum_hole_size());
 
 
 
  unsigned char* const oview = of->get_output_view(off, len);
 
  unsigned char* pov = oview;
 
 
 
  // Write header fields: unit_length, version, header_length,
 
  // minimum_instruction_length, default_is_stmt, line_base, line_range,
 
  // opcode_base, standard_opcode_lengths[], include_directories, filenames.
 
  // We set the header_length field to cover the entire hole, so the
 
  // line number program is empty.
 
  if (this->is_big_endian())
 
    {
 
      elfcpp::Swap<32, true>::writeval(pov, len - 4);
 
      elfcpp::Swap<16, true>::writeval(pov + 4, this->version);
 
      elfcpp::Swap<32, true>::writeval(pov + 6, len - (4 + 2 + 4));
 
    }
 
  else
 
    {
 
      elfcpp::Swap<32, false>::writeval(pov, len - 4);
 
      elfcpp::Swap<16, false>::writeval(pov + 4, this->version);
 
      elfcpp::Swap<32, false>::writeval(pov + 6, len - (4 + 2 + 4));
 
    }
 
  pov += 4 + 2 + 4;
 
  *pov++ = 1;   // minimum_instruction_length
 
  *pov++ = 0;    // default_is_stmt
 
  *pov++ = 0;    // line_base
 
  *pov++ = 5;   // line_range
 
  *pov++ = 13;  // opcode_base
 
  *pov++ = 0;    // standard_opcode_lengths[1]
 
  *pov++ = 1;   // standard_opcode_lengths[2]
 
  *pov++ = 1;   // standard_opcode_lengths[3]
 
  *pov++ = 1;   // standard_opcode_lengths[4]
 
  *pov++ = 1;   // standard_opcode_lengths[5]
 
  *pov++ = 0;    // standard_opcode_lengths[6]
 
  *pov++ = 0;    // standard_opcode_lengths[7]
 
  *pov++ = 0;    // standard_opcode_lengths[8]
 
  *pov++ = 1;   // standard_opcode_lengths[9]
 
  *pov++ = 0;    // standard_opcode_lengths[10]
 
  *pov++ = 0;    // standard_opcode_lengths[11]
 
  *pov++ = 1;   // standard_opcode_lengths[12]
 
  *pov++ = 0;    // include_directories (empty)
 
  *pov++ = 0;    // filenames (empty)
 
 
 
  // Some consumers don't check the header_length field, and simply
 
  // start reading the line number program immediately following the
 
  // header.  For those consumers, we fill the remainder of the free
 
  // space with DW_LNS_set_basic_block opcodes.  These are effectively
 
  // no-ops: the resulting line table program will not create any rows.
 
  if (pov < oview + len)
 
    memset(pov, elfcpp::DW_LNS_set_basic_block, oview + len - pov);
 
 
 
  of->write_output_view(off, len, oview);
 
}
 
 
// Output_section::Input_section methods.
// Output_section::Input_section methods.
 
 
// Return the current data size.  For an input section we store the size here.
// Return the current data size.  For an input section we store the size here.
// For an Output_section_data, we have to ask it for the size.
// For an Output_section_data, we have to ask it for the size.
 
 
Line 2150... Line 2286...
    is_entsize_zero_(false),
    is_entsize_zero_(false),
    section_offsets_need_adjustment_(false),
    section_offsets_need_adjustment_(false),
    is_noload_(false),
    is_noload_(false),
    always_keeps_input_sections_(false),
    always_keeps_input_sections_(false),
    has_fixed_layout_(false),
    has_fixed_layout_(false),
 
    is_patch_space_allowed_(false),
    tls_offset_(0),
    tls_offset_(0),
    checkpoint_(NULL),
    checkpoint_(NULL),
    lookup_maps_(new Output_section_lookup_maps),
    lookup_maps_(new Output_section_lookup_maps),
    free_list_()
    free_list_(),
 
    free_space_fill_(NULL),
 
    patch_space_(0)
{
{
  // An unallocated section has no address.  Forcing this means that
  // An unallocated section has no address.  Forcing this means that
  // we don't need special treatment for symbols defined in debug
  // we don't need special treatment for symbols defined in debug
  // sections.
  // sections.
  if ((flags & elfcpp::SHF_ALLOC) == 0)
  if ((flags & elfcpp::SHF_ALLOC) == 0)
Line 2268... Line 2407...
    {
    {
      // For incremental updates, find a chunk of unused space in the section.
      // For incremental updates, find a chunk of unused space in the section.
      offset_in_section = this->free_list_.allocate(input_section_size,
      offset_in_section = this->free_list_.allocate(input_section_size,
                                                    addralign, 0);
                                                    addralign, 0);
      if (offset_in_section == -1)
      if (offset_in_section == -1)
        gold_fallback(_("out of patch space; relink with --incremental-full"));
        gold_fallback(_("out of patch space in section %s; "
 
                        "relink with --incremental-full"),
 
                      this->name());
      aligned_offset_in_section = offset_in_section;
      aligned_offset_in_section = offset_in_section;
    }
    }
  else
  else
    {
    {
      offset_in_section = this->current_data_size_for_child();
      offset_in_section = this->current_data_size_for_child();
Line 2289... Line 2430...
  if (!this->generate_code_fills_at_write_
  if (!this->generate_code_fills_at_write_
      && !have_sections_script
      && !have_sections_script
      && (sh_flags & elfcpp::SHF_EXECINSTR) != 0
      && (sh_flags & elfcpp::SHF_EXECINSTR) != 0
      && parameters->target().has_code_fill()
      && parameters->target().has_code_fill()
      && (parameters->target().may_relax()
      && (parameters->target().may_relax()
          || parameters->options().section_ordering_file()))
          || layout->is_section_ordering_specified()))
    {
    {
      gold_assert(this->fills_.empty());
      gold_assert(this->fills_.empty());
      this->generate_code_fills_at_write_ = true;
      this->generate_code_fills_at_write_ = true;
    }
    }
 
 
Line 2328... Line 2469...
      || !this->input_sections_.empty()
      || !this->input_sections_.empty()
      || this->may_sort_attached_input_sections()
      || this->may_sort_attached_input_sections()
      || this->must_sort_attached_input_sections()
      || this->must_sort_attached_input_sections()
      || parameters->options().user_set_Map()
      || parameters->options().user_set_Map()
      || parameters->target().may_relax()
      || parameters->target().may_relax()
      || parameters->options().section_ordering_file())
      || layout->is_section_ordering_specified())
    {
    {
      Input_section isecn(object, shndx, input_section_size, addralign);
      Input_section isecn(object, shndx, input_section_size, addralign);
      if (parameters->options().section_ordering_file())
      if (layout->is_section_ordering_specified())
        {
        {
          unsigned int section_order_index =
          unsigned int section_order_index =
            layout->find_section_order_index(std::string(secname));
            layout->find_section_order_index(std::string(secname));
          if (section_order_index != 0)
          if (section_order_index != 0)
            {
            {
Line 2372... Line 2513...
        {
        {
          // For incremental updates, find a chunk of unused space.
          // For incremental updates, find a chunk of unused space.
          offset_in_section = this->free_list_.allocate(posd->data_size(),
          offset_in_section = this->free_list_.allocate(posd->data_size(),
                                                        posd->addralign(), 0);
                                                        posd->addralign(), 0);
          if (offset_in_section == -1)
          if (offset_in_section == -1)
            gold_fallback(_("out of patch space; "
            gold_fallback(_("out of patch space in section %s; "
                            "relink with --incremental-full"));
                            "relink with --incremental-full"),
 
                          this->name());
          // Finalize the address and offset now.
          // Finalize the address and offset now.
          uint64_t addr = this->address();
          uint64_t addr = this->address();
          off_t offset = this->offset();
          off_t offset = this->offset();
          posd->set_address_and_file_offset(addr + offset_in_section,
          posd->set_address_and_file_offset(addr + offset_in_section,
                                            offset + offset_in_section);
                                            offset + offset_in_section);
Line 2413... Line 2555...
{
{
  Input_section inp(poris);
  Input_section inp(poris);
 
 
  // If the --section-ordering-file option is used to specify the order of
  // If the --section-ordering-file option is used to specify the order of
  // sections, we need to keep track of sections.
  // sections, we need to keep track of sections.
  if (parameters->options().section_ordering_file())
  if (layout->is_section_ordering_specified())
    {
    {
      unsigned int section_order_index =
      unsigned int section_order_index =
        layout->find_section_order_index(name);
        layout->find_section_order_index(name);
      if (section_order_index != 0)
      if (section_order_index != 0)
        {
        {
Line 2943... Line 3085...
// setting the addresses of any Output_section_data objects.
// setting the addresses of any Output_section_data objects.
 
 
void
void
Output_section::set_final_data_size()
Output_section::set_final_data_size()
{
{
 
  off_t data_size;
 
 
  if (this->input_sections_.empty())
  if (this->input_sections_.empty())
 
    data_size = this->current_data_size_for_child();
 
  else
    {
    {
      this->set_data_size(this->current_data_size_for_child());
 
      return;
 
    }
 
 
 
  if (this->must_sort_attached_input_sections()
  if (this->must_sort_attached_input_sections()
      || this->input_section_order_specified())
      || this->input_section_order_specified())
    this->sort_attached_input_sections();
    this->sort_attached_input_sections();
 
 
  uint64_t address = this->address();
  uint64_t address = this->address();
Line 2965... Line 3107...
      off = align_address(off, p->addralign());
      off = align_address(off, p->addralign());
      p->set_address_and_file_offset(address + (off - startoff), off,
      p->set_address_and_file_offset(address + (off - startoff), off,
                                     startoff);
                                     startoff);
      off += p->data_size();
      off += p->data_size();
    }
    }
 
      data_size = off - startoff;
 
    }
 
 
 
  // For full incremental links, we want to allocate some patch space
 
  // in most sections for subsequent incremental updates.
 
  if (this->is_patch_space_allowed_ && parameters->incremental_full())
 
    {
 
      double pct = parameters->options().incremental_patch();
 
      size_t extra = static_cast<size_t>(data_size * pct);
 
      if (this->free_space_fill_ != NULL
 
          && this->free_space_fill_->minimum_hole_size() > extra)
 
        extra = this->free_space_fill_->minimum_hole_size();
 
      off_t new_size = align_address(data_size + extra, this->addralign());
 
      this->patch_space_ = new_size - data_size;
 
      gold_debug(DEBUG_INCREMENTAL,
 
                 "set_final_data_size: %08lx + %08lx: section %s",
 
                 static_cast<long>(data_size),
 
                 static_cast<long>(this->patch_space_),
 
                 this->name());
 
      data_size = new_size;
 
    }
 
 
  this->set_data_size(off - startoff);
  this->set_data_size(data_size);
}
}
 
 
// Reset the address and file offset.
// Reset the address and file offset.
 
 
void
void
Line 2985... Line 3148...
 
 
  for (Input_section_list::iterator p = this->input_sections_.begin();
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       p != this->input_sections_.end();
       ++p)
       ++p)
    p->reset_address_and_file_offset();
    p->reset_address_and_file_offset();
 
 
 
  // Remove any patch space that was added in set_final_data_size.
 
  if (this->patch_space_ > 0)
 
    {
 
      this->set_current_data_size_for_child(this->current_data_size_for_child()
 
                                            - this->patch_space_);
 
      this->patch_space_ = 0;
 
    }
}
}
 
 
// Return true if address and file offset have the values after reset.
// Return true if address and file offset have the values after reset.
 
 
bool
bool
Line 3015... Line 3186...
// In a few cases we need to sort the input sections attached to an
// In a few cases we need to sort the input sections attached to an
// output section.  This is used to implement the type of constructor
// output section.  This is used to implement the type of constructor
// priority ordering implemented by the GNU linker, in which the
// priority ordering implemented by the GNU linker, in which the
// priority becomes part of the section name and the sections are
// priority becomes part of the section name and the sections are
// sorted by name.  We only do this for an output section if we see an
// sorted by name.  We only do this for an output section if we see an
// attached input section matching ".ctor.*", ".dtor.*",
// attached input section matching ".ctors.*", ".dtors.*",
// ".init_array.*" or ".fini_array.*".
// ".init_array.*" or ".fini_array.*".
 
 
class Output_section::Input_section_sort_entry
class Output_section::Input_section_sort_entry
{
{
 public:
 public:
Line 3090... Line 3261...
  {
  {
    gold_assert(this->section_has_name_);
    gold_assert(this->section_has_name_);
    return this->section_name_.find('.', 1) != std::string::npos;
    return this->section_name_.find('.', 1) != std::string::npos;
  }
  }
 
 
 
  // Return the priority.  Believe it or not, gcc encodes the priority
 
  // differently for .ctors/.dtors and .init_array/.fini_array
 
  // sections.
 
  unsigned int
 
  get_priority() const
 
  {
 
    gold_assert(this->section_has_name_);
 
    bool is_ctors;
 
    if (is_prefix_of(".ctors.", this->section_name_.c_str())
 
        || is_prefix_of(".dtors.", this->section_name_.c_str()))
 
      is_ctors = true;
 
    else if (is_prefix_of(".init_array.", this->section_name_.c_str())
 
             || is_prefix_of(".fini_array.", this->section_name_.c_str()))
 
      is_ctors = false;
 
    else
 
      return 0;
 
    char* end;
 
    unsigned long prio = strtoul((this->section_name_.c_str()
 
                                  + (is_ctors ? 7 : 12)),
 
                                 &end, 10);
 
    if (*end != '\0')
 
      return 0;
 
    else if (is_ctors)
 
      return 65535 - prio;
 
    else
 
      return prio;
 
  }
 
 
  // Return true if this an input file whose base name matches
  // Return true if this an input file whose base name matches
  // FILE_NAME.  The base name must have an extension of ".o", and
  // FILE_NAME.  The base name must have an extension of ".o", and
  // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o".
  // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o".
  // This is to match crtbegin.o as well as crtbeginS.o without
  // This is to match crtbegin.o as well as crtbeginS.o without
  // getting confused by other possibilities.  Overall matching the
  // getting confused by other possibilities.  Overall matching the
  // file name this way is a dreadful hack, but the GNU linker does it
  // file name this way is a dreadful hack, but the GNU linker does it
  // in order to better support gcc, and we need to be compatible.
  // in order to better support gcc, and we need to be compatible.
  bool
  bool
  match_file_name(const char* match_file_name) const
  match_file_name(const char* file_name) const
  {
  { return Layout::match_file_name(this->input_section_.relobj(), file_name); }
    const std::string& file_name(this->input_section_.relobj()->name());
 
    const char* base_name = lbasename(file_name.c_str());
 
    size_t match_len = strlen(match_file_name);
 
    if (strncmp(base_name, match_file_name, match_len) != 0)
 
      return false;
 
    size_t base_len = strlen(base_name);
 
    if (base_len != match_len + 2 && base_len != match_len + 3)
 
      return false;
 
    return memcmp(base_name + base_len - 2, ".o", 2) == 0;
 
  }
 
 
 
  // Returns 1 if THIS should appear before S in section order, -1 if S
  // Returns 1 if THIS should appear before S in section order, -1 if S
  // appears before THIS and 0 if they are not comparable.
  // appears before THIS and 0 if they are not comparable.
  int
  int
  compare_section_ordering(const Input_section_sort_entry& s) const
  compare_section_ordering(const Input_section_sort_entry& s) const
Line 3231... Line 3420...
  if (s1_has_priority && !s2_has_priority)
  if (s1_has_priority && !s2_has_priority)
    return true;
    return true;
  if (!s1_has_priority && s2_has_priority)
  if (!s1_has_priority && s2_has_priority)
    return false;
    return false;
 
 
 
  // .ctors and .dtors sections without priority come after
 
  // .init_array and .fini_array sections without priority.
 
  if (!s1_has_priority
 
      && (s1.section_name() == ".ctors" || s1.section_name() == ".dtors")
 
      && s1.section_name() != s2.section_name())
 
    return false;
 
  if (!s2_has_priority
 
      && (s2.section_name() == ".ctors" || s2.section_name() == ".dtors")
 
      && s2.section_name() != s1.section_name())
 
    return true;
 
 
 
  // Sort by priority if we can.
 
  if (s1_has_priority)
 
    {
 
      unsigned int s1_prio = s1.get_priority();
 
      unsigned int s2_prio = s2.get_priority();
 
      if (s1_prio < s2_prio)
 
        return true;
 
      else if (s1_prio > s2_prio)
 
        return false;
 
    }
 
 
  // Check if a section order exists for these sections through a section
  // Check if a section order exists for these sections through a section
  // ordering file.  If sequence_num is 0, an order does not exist.
  // ordering file.  If sequence_num is 0, an order does not exist.
  int sequence_num = s1.compare_section_ordering(s2);
  int sequence_num = s1.compare_section_ordering(s2);
  if (sequence_num != 0)
  if (sequence_num != 0)
    return sequence_num == 1;
    return sequence_num == 1;
Line 3265... Line 3476...
    return s1.index() < s2.index();
    return s1.index() < s2.index();
 
 
  return s1_secn_index < s2_secn_index;
  return s1_secn_index < s2_secn_index;
}
}
 
 
 
// This updates the section order index of input sections according to the
 
// the order specified in the mapping from Section id to order index.
 
 
 
void
 
Output_section::update_section_layout(
 
  const Section_layout_order& order_map)
 
{
 
  for (Input_section_list::iterator p = this->input_sections_.begin();
 
       p != this->input_sections_.end();
 
       ++p)
 
    {
 
      if (p->is_input_section()
 
          || p->is_relaxed_input_section())
 
        {
 
          Object* obj = (p->is_input_section()
 
                         ? p->relobj()
 
                         : p->relaxed_input_section()->relobj());
 
          unsigned int shndx = p->shndx();
 
          Section_layout_order::const_iterator it
 
            = order_map.find(Section_id(obj, shndx));
 
          if (it == order_map.end())
 
            continue;
 
          unsigned int section_order_index = it->second;
 
          if (section_order_index != 0)
 
            {
 
              p->set_section_order_index(section_order_index);
 
              this->set_input_section_order_specified();
 
            }
 
        }
 
    }
 
}
 
 
// Sort the input sections attached to an output section.
// Sort the input sections attached to an output section.
 
 
void
void
Output_section::sort_attached_input_sections()
Output_section::sort_attached_input_sections()
{
{
Line 3307... Line 3550...
        std::sort(sort_list.begin(), sort_list.end(),
        std::sort(sort_list.begin(), sort_list.end(),
                  Input_section_sort_compare());
                  Input_section_sort_compare());
    }
    }
  else
  else
    {
    {
      gold_assert(parameters->options().section_ordering_file());
      gold_assert(this->input_section_order_specified());
      std::sort(sort_list.begin(), sort_list.end(),
      std::sort(sort_list.begin(), sort_list.end(),
                Input_section_sort_section_order_index_compare());
                Input_section_sort_section_order_index_compare());
    }
    }
 
 
  // Copy the sorted input sections back to our list.
  // Copy the sorted input sections back to our list.
Line 3347... Line 3590...
  oshdr->put_sh_offset(this->offset());
  oshdr->put_sh_offset(this->offset());
  oshdr->put_sh_size(this->data_size());
  oshdr->put_sh_size(this->data_size());
  if (this->link_section_ != NULL)
  if (this->link_section_ != NULL)
    oshdr->put_sh_link(this->link_section_->out_shndx());
    oshdr->put_sh_link(this->link_section_->out_shndx());
  else if (this->should_link_to_symtab_)
  else if (this->should_link_to_symtab_)
    oshdr->put_sh_link(layout->symtab_section()->out_shndx());
    oshdr->put_sh_link(layout->symtab_section_shndx());
  else if (this->should_link_to_dynsym_)
  else if (this->should_link_to_dynsym_)
    oshdr->put_sh_link(layout->dynsym_section()->out_shndx());
    oshdr->put_sh_link(layout->dynsym_section()->out_shndx());
  else
  else
    oshdr->put_sh_link(this->link_);
    oshdr->put_sh_link(this->link_);
 
 
Line 3409... Line 3652...
        }
        }
 
 
      p->write(of);
      p->write(of);
      off = aligned_off + p->data_size();
      off = aligned_off + p->data_size();
    }
    }
 
 
 
  // For incremental links, fill in unused chunks in debug sections
 
  // with dummy compilation unit headers.
 
  if (this->free_space_fill_ != NULL)
 
    {
 
      for (Free_list::Const_iterator p = this->free_list_.begin();
 
           p != this->free_list_.end();
 
           ++p)
 
        {
 
          off_t off = p->start_;
 
          size_t len = p->end_ - off;
 
          this->free_space_fill_->write(of, this->offset() + off, len);
 
        }
 
      if (this->patch_space_ > 0)
 
        {
 
          off_t off = this->current_data_size_for_child() - this->patch_space_;
 
          this->free_space_fill_->write(of, this->offset() + off,
 
                                        this->patch_space_);
 
        }
 
    }
}
}
 
 
// If a section requires postprocessing, create the buffer to use.
// If a section requires postprocessing, create the buffer to use.
 
 
void
void
Line 4222... Line 4485...
            }
            }
          (*p)->set_file_offset(off);
          (*p)->set_file_offset(off);
          (*p)->finalize_data_size();
          (*p)->finalize_data_size();
        }
        }
 
 
 
      if (parameters->incremental_update())
      gold_debug(DEBUG_INCREMENTAL,
      gold_debug(DEBUG_INCREMENTAL,
                 "set_section_list_addresses: %08lx %08lx %s",
                 "set_section_list_addresses: %08lx %08lx %s",
                 static_cast<long>(off),
                 static_cast<long>(off),
                 static_cast<long>((*p)->data_size()),
                 static_cast<long>((*p)->data_size()),
                 ((*p)->output_section() != NULL
                 ((*p)->output_section() != NULL
                  ? (*p)->output_section()->name() : "(special)"));
                  ? (*p)->output_section()->name() : "(special)"));
 
 
      // We want to ignore the size of a SHF_TLS or SHT_NOBITS
      // We want to ignore the size of a SHF_TLS SHT_NOBITS
      // section.  Such a section does not affect the size of a
      // section.  Such a section does not affect the size of a
      // PT_LOAD segment.
      // PT_LOAD segment.
      if (!(*p)->is_section_flag_set(elfcpp::SHF_TLS)
      if (!(*p)->is_section_flag_set(elfcpp::SHF_TLS)
          || !(*p)->is_section_type(elfcpp::SHT_NOBITS))
          || !(*p)->is_section_type(elfcpp::SHT_NOBITS))
        off += (*p)->data_size();
        off += (*p)->data_size();

powered by: WebSVN 2.1.0

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