// gc.h -- garbage collection of unused sections

// Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
// Written by Sriraman Tallam <tmsriram@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_GC_H
#define GOLD_GC_H

#include <queue>
#include <vector>

#include "elfcpp.h"
#include "symtab.h"
#include "object.h"
#include "icf.h"

namespace gold
{

class Object;

template<int size, bool big_endian>
class Sized_relobj_file;

template<int sh_type, int size, bool big_endian>
struct Reloc_types;

class Output_section;
class General_options;
class Layout;

class Garbage_collection
{
 public:

  typedef Unordered_set<Section_id, Section_id_hash> Sections_reachable;
  typedef std::map<Section_id, Sections_reachable> Section_ref;
  typedef std::queue<Section_id> Worklist_type;
  // This maps the name of the section which can be represented as a C
  // identifier (cident) to the list of sections that have that name.
  // Different object files can have cident sections with the same name.
  typedef std::map<std::string, Sections_reachable> Cident_section_map;

  Garbage_collection()
  : is_worklist_ready_(false)
  { }

  // Accessor methods for the private members.

  Sections_reachable&
  referenced_list()
  { return referenced_list_; }

  Section_ref&
  section_reloc_map()
  { return this->section_reloc_map_; }

  Worklist_type&
  worklist()
  { return this->work_list_; }

  bool
  is_worklist_ready()
  { return this->is_worklist_ready_; }

  void
  worklist_ready()
  { this->is_worklist_ready_ = true; }

  void
  do_transitive_closure();

  bool
  is_section_garbage(Object* obj, unsigned int shndx)
  { return (this->referenced_list().find(Section_id(obj, shndx))
            == this->referenced_list().end()); }

  Cident_section_map*
  cident_sections()
  { return &cident_sections_; }

  void
  add_cident_section(std::string section_name,
		     Section_id secn)
  { this->cident_sections_[section_name].insert(secn); }

  // Add a reference from the SRC_SHNDX-th section of SRC_OBJECT to
  // DST_SHNDX-th section of DST_OBJECT.
  void
  add_reference(Object* src_object, unsigned int src_shndx,
		Object* dst_object, unsigned int dst_shndx)
  {
    Section_id src_id(src_object, src_shndx);
    Section_id dst_id(dst_object, dst_shndx);
    Section_ref::iterator p = this->section_reloc_map_.find(src_id);
    if (p == this->section_reloc_map_.end())
      this->section_reloc_map_[src_id].insert(dst_id);
    else
      p->second.insert(dst_id);
  }

 private:

  Worklist_type work_list_;
  bool is_worklist_ready_;
  Section_ref section_reloc_map_;
  Sections_reachable referenced_list_;
  Cident_section_map cident_sections_;
};

// Data to pass between successive invocations of do_layout
// in object.cc while garbage collecting.  This data structure
// is filled by using the data from Read_symbols_data.

struct Symbols_data
{
  // Section headers.
  unsigned char* section_headers_data;
  // Section names.
  unsigned char* section_names_data;
  // Size of section name data in bytes.
  section_size_type section_names_size;
  // Symbol data.
  unsigned char* symbols_data;
  // Size of symbol data in bytes.
  section_size_type symbols_size;
  // Offset of external symbols within symbol data.  This structure
  // sometimes contains only external symbols, in which case this will
  // be zero.  Sometimes it contains all symbols.
  section_offset_type external_symbols_offset;
  // Symbol names.
  unsigned char* symbol_names_data;
  // Size of symbol name data in bytes.
  section_size_type symbol_names_size;
};

// Relocations of type SHT_REL store the addend value in their bytes.
// This function returns the size of the embedded addend which is
// nothing but the size of the relocation.

template<typename Classify_reloc>
inline unsigned int
get_embedded_addend_size(int sh_type, int r_type, Relobj* obj)
{
  if (sh_type != elfcpp::SHT_REL)
    return 0;
  Classify_reloc classify_reloc;
  return classify_reloc.get_size_for_reloc(r_type, obj);
}

// This function implements the generic part of reloc
// processing to map a section to all the sections it
// references through relocs.  It is called only during
// garbage collection (--gc-sections) and identical code
// folding (--icf).

template<int size, bool big_endian, typename Target_type, int sh_type,
	 typename Scan, typename Classify_reloc>
inline void
gc_process_relocs(
    Symbol_table* symtab,
    Layout*,
    Target_type* target,
    Sized_relobj_file<size, big_endian>* src_obj,
    unsigned int src_indx,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section*,
    bool,
    size_t local_count,
    const unsigned char* plocal_syms)
{
  Scan scan;

  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;

  Icf::Sections_reachable_info* secvec = NULL;
  Icf::Symbol_info* symvec = NULL;
  Icf::Addend_info* addendvec = NULL;
  Icf::Offset_info* offsetvec = NULL;
  Icf::Reloc_addend_size_info* reloc_addend_size_vec = NULL;
  bool is_icf_tracked = false;
  const char* cident_section_name = NULL;

  std::string src_section_name = (parameters->options().icf_enabled()
                                  ? src_obj->section_name(src_indx)
                                  : "");

  bool check_section_for_function_pointers = false;

  if (parameters->options().icf_enabled()
      && is_section_foldable_candidate(src_section_name.c_str()))
    {
      is_icf_tracked = true;
      Section_id src_id(src_obj, src_indx);
      Icf::Reloc_info* reloc_info =
        &symtab->icf()->reloc_info_list()[src_id];
      secvec = &reloc_info->section_info;
      symvec = &reloc_info->symbol_info;
      addendvec = &reloc_info->addend_info;
      offsetvec = &reloc_info->offset_info;
      reloc_addend_size_vec = &reloc_info->reloc_addend_size_info;
    }

  check_section_for_function_pointers =
    symtab->icf()->check_section_for_function_pointers(src_section_name,
                                                       target);

  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Reltype reloc(prelocs);
      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
      typename elfcpp::Elf_types<size>::Elf_Swxword addend =
      Reloc_types<sh_type, size, big_endian>::get_reloc_addend_noerror(&reloc);
      Object* dst_obj;
      unsigned int dst_indx;
      typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
      Address dst_off;

      if (r_sym < local_count)
        {
          gold_assert(plocal_syms != NULL);
          typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
                                                      + r_sym * sym_size);
	  dst_indx = lsym.get_st_shndx();
          bool is_ordinary;
	  dst_indx = src_obj->adjust_sym_shndx(r_sym, dst_indx, &is_ordinary);
          dst_obj = src_obj;
	  dst_off = lsym.get_st_value() + addend;

          if (is_icf_tracked)
            {
	      Address symvalue = dst_off - addend;
	      if (is_ordinary) 
		(*secvec).push_back(Section_id(dst_obj, dst_indx));
	      else
                (*secvec).push_back(Section_id(NULL, 0));
              (*symvec).push_back(NULL);
	      (*addendvec).push_back(std::make_pair(
					static_cast<long long>(symvalue),
					static_cast<long long>(addend)));
              uint64_t reloc_offset =
                convert_to_section_size_type(reloc.get_r_offset());
	      (*offsetvec).push_back(reloc_offset);
              (*reloc_addend_size_vec).push_back(
                get_embedded_addend_size<Classify_reloc>(sh_type, r_type,
                                                         src_obj));
            }

	  // When doing safe folding, check to see if this relocation is that
	  // of a function pointer being taken.
	  if (is_ordinary
	      && check_section_for_function_pointers
              && lsym.get_st_type() != elfcpp::STT_OBJECT
 	      && scan.local_reloc_may_be_function_pointer(symtab, NULL, NULL,
							  src_obj, src_indx,
			                       		  NULL, reloc, r_type,
							  lsym))
            symtab->icf()->set_section_has_function_pointers(
              src_obj, lsym.get_st_shndx());

          if (!is_ordinary || dst_indx == src_indx)
            continue;
        }
      else
        {
          Symbol* gsym = src_obj->global_symbol(r_sym);
          gold_assert(gsym != NULL);
          if (gsym->is_forwarder())
            gsym = symtab->resolve_forwards(gsym);

          dst_obj = NULL;
          dst_indx = 0;
          bool is_ordinary = false;
          if (gsym->source() == Symbol::FROM_OBJECT)
            {
              dst_obj = gsym->object();
              dst_indx = gsym->shndx(&is_ordinary);
            }
	  dst_off = static_cast<const Sized_symbol<size>*>(gsym)->value();
	  dst_off += addend;

	  // When doing safe folding, check to see if this relocation is that
	  // of a function pointer being taken.
	  if (gsym->source() == Symbol::FROM_OBJECT
              && check_section_for_function_pointers
              && gsym->type() != elfcpp::STT_OBJECT
              && (!is_ordinary
                  || scan.global_reloc_may_be_function_pointer(
                       symtab, NULL, NULL, src_obj, src_indx, NULL, reloc,
                       r_type, gsym)))
            symtab->icf()->set_section_has_function_pointers(dst_obj, dst_indx);

          // If the symbol name matches '__start_XXX' then the section with
          // the C identifier like name 'XXX' should not be garbage collected.
          // A similar treatment to symbols with the name '__stop_XXX'.
          if (is_prefix_of(cident_section_start_prefix, gsym->name()))
            {
              cident_section_name = (gsym->name() 
                                     + strlen(cident_section_start_prefix));
            }
          else if (is_prefix_of(cident_section_stop_prefix, gsym->name()))
            {
              cident_section_name = (gsym->name() 
                                     + strlen(cident_section_stop_prefix));
            }
          if (is_icf_tracked)
            {
	      Address symvalue = dst_off - addend;
              if (is_ordinary && gsym->source() == Symbol::FROM_OBJECT)
		(*secvec).push_back(Section_id(dst_obj, dst_indx));
	      else
                (*secvec).push_back(Section_id(NULL, 0));
              (*symvec).push_back(gsym);
	      (*addendvec).push_back(std::make_pair(
					static_cast<long long>(symvalue),
					static_cast<long long>(addend)));
              uint64_t reloc_offset =
                convert_to_section_size_type(reloc.get_r_offset());
	      (*offsetvec).push_back(reloc_offset);
              (*reloc_addend_size_vec).push_back(
                get_embedded_addend_size<Classify_reloc>(sh_type, r_type,
                                                         src_obj));
	    }

          if (gsym->source() != Symbol::FROM_OBJECT)
            continue;
          if (!is_ordinary)
            continue;
        }
      if (parameters->options().gc_sections())
        {
	  symtab->gc()->add_reference(src_obj, src_indx, dst_obj, dst_indx);
	  parameters->sized_target<size, big_endian>()
	    ->gc_add_reference(symtab, src_obj, src_indx,
			       dst_obj, dst_indx, dst_off);
          if (cident_section_name != NULL)
            {
              Garbage_collection::Cident_section_map::iterator ele =
                symtab->gc()->cident_sections()->find(std::string(cident_section_name));
              if (ele == symtab->gc()->cident_sections()->end())
                continue;
	      Section_id src_id(src_obj, src_indx);
              Garbage_collection::Sections_reachable&
                v(symtab->gc()->section_reloc_map()[src_id]);
              Garbage_collection::Sections_reachable& cident_secn(ele->second);
              for (Garbage_collection::Sections_reachable::iterator it_v
                     = cident_secn.begin();
                   it_v != cident_secn.end();
                   ++it_v)
                {
                  v.insert(*it_v);
                }
            }
        }
    }
  return;
}

} // End of namespace gold.

#endif
