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

Subversion Repositories open8_urisc

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

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

Rev 27 Rev 148
Line 20... Line 20...
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
// MA 02110-1301, USA.
 
 
#include "gold.h"
#include "gold.h"
 
 
 
#include <set>
#include <cstdarg>
#include <cstdarg>
#include "libiberty.h"
#include "libiberty.h"
 
 
#include "elfcpp.h"
#include "elfcpp.h"
#include "options.h"
#include "options.h"
Line 516... Line 517...
template<int size, bool big_endian>
template<int size, bool big_endian>
void
void
Sized_incremental_binary<size, big_endian>::do_reserve_layout(
Sized_incremental_binary<size, big_endian>::do_reserve_layout(
    unsigned int input_file_index)
    unsigned int input_file_index)
{
{
 
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
 
 
  Input_entry_reader input_file =
  Input_entry_reader input_file =
      this->inputs_reader_.input_file(input_file_index);
      this->inputs_reader_.input_file(input_file_index);
 
 
  if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY)
  if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY)
 
    {
 
      // Reserve the BSS space used for COPY relocations.
 
      unsigned int nsyms = input_file.get_global_symbol_count();
 
      Incremental_binary::View symtab_view(NULL);
 
      unsigned int symtab_count;
 
      elfcpp::Elf_strtab strtab(NULL, 0);
 
      this->get_symtab_view(&symtab_view, &symtab_count, &strtab);
 
      for (unsigned int i = 0; i < nsyms; ++i)
 
        {
 
          bool is_def;
 
          bool is_copy;
 
          unsigned int output_symndx =
 
              input_file.get_output_symbol_index(i, &is_def, &is_copy);
 
          if (is_copy)
 
            {
 
              const unsigned char* sym_p = (symtab_view.data()
 
                                            + output_symndx * sym_size);
 
              elfcpp::Sym<size, big_endian> gsym(sym_p);
 
              unsigned int shndx = gsym.get_st_shndx();
 
              if (shndx < 1 || shndx >= this->section_map_.size())
 
                continue;
 
              Output_section* os = this->section_map_[shndx];
 
              off_t offset = gsym.get_st_value() - os->address();
 
              os->reserve(offset, gsym.get_st_size());
 
              gold_debug(DEBUG_INCREMENTAL,
 
                         "Reserve for COPY reloc: %s, off %d, size %d",
 
                         os->name(),
 
                         static_cast<int>(offset),
 
                         static_cast<int>(gsym.get_st_size()));
 
            }
 
        }
    return;
    return;
 
    }
 
 
  unsigned int shnum = input_file.get_input_section_count();
  unsigned int shnum = input_file.get_input_section_count();
  for (unsigned int i = 0; i < shnum; i++)
  for (unsigned int i = 0; i < shnum; i++)
    {
    {
      typename Input_entry_reader::Input_section_info sect =
      typename Input_entry_reader::Input_section_info sect =
Line 593... Line 628...
          // This is an entry for a global symbol.  GOT_DESC is the symbol
          // This is an entry for a global symbol.  GOT_DESC is the symbol
          // table index.
          // table index.
          // FIXME: This should really be a fatal error (corrupt input).
          // FIXME: This should really be a fatal error (corrupt input).
          gold_assert(symndx >= first_global && symndx < symtab_count);
          gold_assert(symndx >= first_global && symndx < symtab_count);
          Symbol* sym = this->global_symbol(symndx - first_global);
          Symbol* sym = this->global_symbol(symndx - first_global);
 
          // Add the GOT entry only if the symbol is still referenced.
 
          if (sym != NULL && sym->in_reg())
 
            {
          gold_debug(DEBUG_INCREMENTAL,
          gold_debug(DEBUG_INCREMENTAL,
                     "GOT entry %d, type %02x: %s",
                     "GOT entry %d, type %02x: %s",
                     i, got_type, sym->name());
                     i, got_type, sym->name());
          target->reserve_global_got_entry(i, sym, got_type);
          target->reserve_global_got_entry(i, sym, got_type);
        }
        }
    }
    }
 
    }
 
 
  // Read the PLT entries from the base file and pass each to the target.
  // Read the PLT entries from the base file and pass each to the target.
  for (unsigned int i = 0; i < plt_count; ++i)
  for (unsigned int i = 0; i < plt_count; ++i)
    {
    {
      unsigned int plt_desc = got_plt_reader.get_plt_desc(i);
      unsigned int plt_desc = got_plt_reader.get_plt_desc(i);
      // FIXME: This should really be a fatal error (corrupt input).
      // FIXME: This should really be a fatal error (corrupt input).
      gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
      gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
      Symbol* sym = this->global_symbol(plt_desc - first_global);
      Symbol* sym = this->global_symbol(plt_desc - first_global);
 
      // Add the PLT entry only if the symbol is still referenced.
 
      if (sym->in_reg())
 
        {
      gold_debug(DEBUG_INCREMENTAL,
      gold_debug(DEBUG_INCREMENTAL,
                 "PLT entry %d: %s",
                 "PLT entry %d: %s",
                 i, sym->name());
                 i, sym->name());
      target->register_global_plt_entry(i, sym);
      target->register_global_plt_entry(i, sym);
    }
    }
}
}
 
}
 
 
 
// Emit COPY relocations from the existing output file.
 
 
 
template<int size, bool big_endian>
 
void
 
Sized_incremental_binary<size, big_endian>::do_emit_copy_relocs(
 
    Symbol_table* symtab)
 
{
 
  Sized_target<size, big_endian>* target =
 
      parameters->sized_target<size, big_endian>();
 
 
 
  for (typename Copy_relocs::iterator p = this->copy_relocs_.begin();
 
       p != this->copy_relocs_.end();
 
       ++p)
 
    {
 
      if (!(*p).symbol->is_copied_from_dynobj())
 
        target->emit_copy_reloc(symtab, (*p).symbol, (*p).output_section,
 
                                (*p).offset);
 
    }
 
}
 
 
// Apply incremental relocations for symbols whose values have changed.
// Apply incremental relocations for symbols whose values have changed.
 
 
template<int size, bool big_endian>
template<int size, bool big_endian>
void
void
Line 1491... Line 1554...
              {
              {
                const Symbol* sym = (*syms)[i];
                const Symbol* sym = (*syms)[i];
                if (sym->is_forwarder())
                if (sym->is_forwarder())
                  sym = this->symtab_->resolve_forwards(sym);
                  sym = this->symtab_->resolve_forwards(sym);
                unsigned int shndx = 0;
                unsigned int shndx = 0;
                if (sym->source() == Symbol::FROM_OBJECT
                if (sym->source() != Symbol::FROM_OBJECT)
                    && sym->object() == obj
                  {
                    && sym->is_defined())
                    // The symbol was defined by the linker (e.g., common).
 
                    // We mark these symbols with a special SHNDX of -1,
 
                    // but exclude linker-predefined symbols and symbols
 
                    // copied from shared objects.
 
                    if (!sym->is_predefined()
 
                        && !sym->is_copied_from_dynobj())
 
                      shndx = -1U;
 
                  }
 
                else if (sym->object() == obj && sym->is_defined())
                  {
                  {
                    bool is_ordinary;
                    bool is_ordinary;
                    unsigned int orig_shndx = sym->shndx(&is_ordinary);
                    unsigned int orig_shndx = sym->shndx(&is_ordinary);
                    if (is_ordinary)
                    if (is_ordinary)
                      shndx = index_map[orig_shndx];
                      shndx = index_map[orig_shndx];
 
                    else
 
                      shndx = 1;
                  }
                  }
                unsigned int symtab_index = sym->symtab_index();
                unsigned int symtab_index = sym->symtab_index();
                unsigned int chain = 0;
                unsigned int chain = 0;
                unsigned int first_reloc = 0;
                unsigned int first_reloc = 0;
                unsigned int nrelocs = obj->get_incremental_reloc_count(i);
                unsigned int nrelocs = obj->get_incremental_reloc_count(i);
Line 1543... Line 1616...
          {
          {
            gold_assert(static_cast<unsigned int>(pov - oview)
            gold_assert(static_cast<unsigned int>(pov - oview)
                        == (*p)->get_info_offset());
                        == (*p)->get_info_offset());
            Incremental_dynobj_entry* entry = (*p)->dynobj_entry();
            Incremental_dynobj_entry* entry = (*p)->dynobj_entry();
            gold_assert(entry != NULL);
            gold_assert(entry != NULL);
            const Object* obj = entry->object();
            Object* obj = entry->object();
 
            Dynobj* dynobj = obj->dynobj();
 
            gold_assert(dynobj != NULL);
            const Object::Symbols* syms = obj->get_global_symbols();
            const Object::Symbols* syms = obj->get_global_symbols();
 
 
            // Write the soname string table index.
            // Write the soname string table index.
            section_offset_type soname_offset =
            section_offset_type soname_offset =
                strtab->get_offset_from_key(entry->get_soname_key());
                strtab->get_offset_from_key(entry->get_soname_key());
Line 1568... Line 1643...
                  continue;
                  continue;
                if (sym->is_forwarder())
                if (sym->is_forwarder())
                  sym = this->symtab_->resolve_forwards(sym);
                  sym = this->symtab_->resolve_forwards(sym);
                if (sym->symtab_index() == -1U)
                if (sym->symtab_index() == -1U)
                  continue;
                  continue;
                unsigned int def_flag = 0;
                unsigned int flags = 0;
                if (sym->source() == Symbol::FROM_OBJECT
                if (sym->source() == Symbol::FROM_OBJECT
                    && sym->object() == obj
                    && sym->object() == obj
                    && sym->is_defined())
                    && sym->is_defined())
                  def_flag = 1U << 31;
                  flags = INCREMENTAL_SHLIB_SYM_DEF;
                Swap32::writeval(pov, sym->symtab_index() | def_flag);
                else if (sym->is_copied_from_dynobj()
 
                         && this->symtab_->get_copy_source(sym) == dynobj)
 
                  flags = INCREMENTAL_SHLIB_SYM_COPY;
 
                flags <<= INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT;
 
                Swap32::writeval(pov, sym->symtab_index() | flags);
                pov += 4;
                pov += 4;
                ++nsyms_out;
                ++nsyms_out;
              }
              }
 
 
            // Now write the global symbol count.
            // Now write the global symbol count.
Line 1963... Line 2042...
      // to local during output.
      // to local during output.
      if (st_bind == elfcpp::STB_LOCAL)
      if (st_bind == elfcpp::STB_LOCAL)
        st_bind = elfcpp::STB_GLOBAL;
        st_bind = elfcpp::STB_GLOBAL;
 
 
      unsigned int input_shndx = info.shndx();
      unsigned int input_shndx = info.shndx();
      if (input_shndx == 0)
      if (input_shndx == 0 || input_shndx == -1U)
        {
        {
          shndx = elfcpp::SHN_UNDEF;
          shndx = elfcpp::SHN_UNDEF;
          v = 0;
          v = 0;
        }
        }
      else if (shndx != elfcpp::SHN_ABS)
      else if (shndx != elfcpp::SHN_ABS)
Line 1990... Line 2069...
      osym.put_st_size(gsym.get_st_size());
      osym.put_st_size(gsym.get_st_size());
      osym.put_st_info(st_bind, st_type);
      osym.put_st_info(st_bind, st_type);
      osym.put_st_other(gsym.get_st_other());
      osym.put_st_other(gsym.get_st_other());
      osym.put_st_shndx(shndx);
      osym.put_st_shndx(shndx);
 
 
      this->symbols_[i] =
      Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym);
        symtab->add_from_incrobj(this, name, NULL, &sym);
 
      this->ibase_->add_global_symbol(output_symndx - first_global,
      // If this is a linker-defined symbol that hasn't yet been defined,
                                      this->symbols_[i]);
      // define it now.
 
      if (input_shndx == -1U && !res->is_defined())
 
        {
 
          shndx = gsym.get_st_shndx();
 
          v = gsym.get_st_value();
 
          Elf_size_type symsize = gsym.get_st_size();
 
          if (shndx == elfcpp::SHN_ABS)
 
            {
 
              symtab->define_as_constant(name, NULL,
 
                                         Symbol_table::INCREMENTAL_BASE,
 
                                         v, symsize, st_type, st_bind,
 
                                         gsym.get_st_visibility(), 0,
 
                                         false, false);
 
            }
 
          else
 
            {
 
              Output_section* os = this->ibase_->output_section(shndx);
 
              gold_assert(os != NULL && os->has_fixed_layout());
 
              v -= os->address();
 
              if (symsize > 0)
 
                os->reserve(v, symsize);
 
              symtab->define_in_output_data(name, NULL,
 
                                            Symbol_table::INCREMENTAL_BASE,
 
                                            os, v, symsize, st_type, st_bind,
 
                                            gsym.get_st_visibility(), 0,
 
                                            false, false);
 
            }
 
        }
 
 
 
      this->symbols_[i] = res;
 
      this->ibase_->add_global_symbol(output_symndx - first_global, res);
    }
    }
}
}
 
 
// Return TRUE if we should include this object from an archive library.
// Return TRUE if we should include this object from an archive library.
 
 
Line 2479... Line 2588...
 
 
  Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
  Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
  unsigned int isym_count = isymtab.symbol_count();
  unsigned int isym_count = isymtab.symbol_count();
  unsigned int first_global = symtab_count - isym_count;
  unsigned int first_global = symtab_count - isym_count;
 
 
 
  // We keep a set of symbols that we have generated COPY relocations
 
  // for, indexed by the symbol value. We do not need more than one
 
  // COPY relocation per address.
 
  typedef typename std::set<Address> Copied_symbols;
 
  Copied_symbols copied_symbols;
 
 
  const unsigned char* sym_p;
  const unsigned char* sym_p;
  for (unsigned int i = 0; i < nsyms; ++i)
  for (unsigned int i = 0; i < nsyms; ++i)
    {
    {
      bool is_def;
      bool is_def;
 
      bool is_copy;
      unsigned int output_symndx =
      unsigned int output_symndx =
          this->input_reader_.get_output_symbol_index(i, &is_def);
          this->input_reader_.get_output_symbol_index(i, &is_def, &is_copy);
      sym_p = symtab_view.data() + output_symndx * sym_size;
      sym_p = symtab_view.data() + output_symndx * sym_size;
      elfcpp::Sym<size, big_endian> gsym(sym_p);
      elfcpp::Sym<size, big_endian> gsym(sym_p);
      const char* name;
      const char* name;
      if (!strtab.get_c_string(gsym.get_st_name(), &name))
      if (!strtab.get_c_string(gsym.get_st_name(), &name))
        name = "";
        name = "";
 
 
      typename elfcpp::Elf_types<size>::Elf_Addr v;
      Address v;
      unsigned int shndx;
      unsigned int shndx;
      elfcpp::STB st_bind = gsym.get_st_bind();
      elfcpp::STB st_bind = gsym.get_st_bind();
      elfcpp::STT st_type = gsym.get_st_type();
      elfcpp::STT st_type = gsym.get_st_type();
 
 
      // Local hidden symbols start out as globals, but get converted to
      // Local hidden symbols start out as globals, but get converted to
Line 2521... Line 2637...
      osym.put_st_size(gsym.get_st_size());
      osym.put_st_size(gsym.get_st_size());
      osym.put_st_info(st_bind, st_type);
      osym.put_st_info(st_bind, st_type);
      osym.put_st_other(gsym.get_st_other());
      osym.put_st_other(gsym.get_st_other());
      osym.put_st_shndx(shndx);
      osym.put_st_shndx(shndx);
 
 
      this->symbols_[i] =
      Sized_symbol<size>* res =
        symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
        symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
 
      this->symbols_[i] = res;
      this->ibase_->add_global_symbol(output_symndx - first_global,
      this->ibase_->add_global_symbol(output_symndx - first_global,
                                      this->symbols_[i]);
                                      this->symbols_[i]);
 
 
 
      if (is_copy)
 
        {
 
          std::pair<typename Copied_symbols::iterator, bool> ins =
 
              copied_symbols.insert(v);
 
          if (ins.second)
 
            {
 
              unsigned int shndx = gsym.get_st_shndx();
 
              Output_section* os = this->ibase_->output_section(shndx);
 
              off_t offset = v - os->address();
 
              this->ibase_->add_copy_reloc(this->symbols_[i], os, offset);
 
            }
 
        }
    }
    }
}
}
 
 
// Return TRUE if we should include this object from an archive library.
// Return TRUE if we should include this object from an archive library.
 
 

powered by: WebSVN 2.1.0

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