// mapfile.cc -- map file generation for gold

// Copyright 2008 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@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.

#include "gold.h"

#include <cerrno>
#include <cstdio>
#include <cstring>

#include "archive.h"
#include "symtab.h"
#include "output.h"
#include "mapfile.h"

// This file holds the code for printing information to the map file.
// In general we try to produce pretty much the same format as GNU ld.

namespace gold
{

// Mapfile constructor.

Mapfile::Mapfile()
  : map_file_(NULL),
    printed_archive_header_(false),
    printed_common_header_(false),
    printed_memory_map_header_(false)
{
}

// Mapfile destructor.

Mapfile::~Mapfile()
{
  if (this->map_file_ != NULL)
    this->close();
}

// Open the map file.

bool
Mapfile::open(const char* map_filename)
{
  if (strcmp(map_filename, "-") == 0)
    this->map_file_ = stdout;
  else
    {
      this->map_file_ = ::fopen(map_filename, "w");
      if (this->map_file_ == NULL)
	{
	  gold_error(_("cannot open map file %s: %s"), map_filename,
		     strerror(errno));
	  return false;
	}
    }
  return true;
}

// Close the map file.

void
Mapfile::close()
{
  if (fclose(this->map_file_) != 0)
    gold_error(_("cannot close map file: %s"), strerror(errno));
  this->map_file_ = NULL;
}

// Advance to a column.

void
Mapfile::advance_to_column(size_t from, size_t to)
{
  if (from >= to - 1)
    {
      putc('\n', this->map_file_);
      from = 0;
    }
  while (from < to)
    {
      putc(' ', this->map_file_);
      ++from;
    }
}

// Report about including a member from an archive.

void
Mapfile::report_include_archive_member(const std::string& member_name,
				       const Symbol* sym, const char* why)
{
  // We print a header before the list of archive members, mainly for
  // GNU ld compatibility.
  if (!this->printed_archive_header_)
    {
      fprintf(this->map_file_,
	      _("Archive member included because of file (symbol)\n\n"));
      this->printed_archive_header_ = true;
    }

  fprintf(this->map_file_, "%s", member_name.c_str());

  this->advance_to_column(member_name.length(), 30);

  if (sym == NULL)
    fprintf(this->map_file_, "%s", why);
  else
    {
      switch (sym->source())
	{
	case Symbol::FROM_OBJECT:
	  fprintf(this->map_file_, "%s", sym->object()->name().c_str());
	  break;

	case Symbol::IS_UNDEFINED:
	  fprintf(this->map_file_, "-u");
	  break;

	default:
	case Symbol::IN_OUTPUT_DATA:
	case Symbol::IN_OUTPUT_SEGMENT:
	case Symbol::IS_CONSTANT:
	  // We should only see an undefined symbol here.
	  gold_unreachable();
	}

      fprintf(this->map_file_, " (%s)", sym->name());
    }

  putc('\n', this->map_file_);
}

// Report allocating a common symbol.

void
Mapfile::report_allocate_common(const Symbol* sym, uint64_t symsize)
{
  if (!this->printed_common_header_)
    {
      fprintf(this->map_file_, _("\nAllocating common symbols\n"));
      fprintf(this->map_file_,
	      _("Common symbol       size              file\n\n"));
      this->printed_common_header_ = true;
    }

  std::string demangled_name = sym->demangled_name();
  fprintf(this->map_file_, "%s", demangled_name.c_str());

  this->advance_to_column(demangled_name.length(), 20);

  char buf[50];
  snprintf(buf, sizeof buf, "0x%llx", static_cast<unsigned long long>(symsize));
  fprintf(this->map_file_, "%s", buf);

  size_t len = strlen(buf);
  while (len < 18)
    {
      putc(' ', this->map_file_);
      ++len;
    }

  fprintf(this->map_file_, "%s\n", sym->object()->name().c_str());
}

// The space we make for a section name.

const size_t Mapfile::section_name_map_length = 16;

// Print the memory map header if necessary.

void
Mapfile::print_memory_map_header()
{
  if (!this->printed_memory_map_header_)
    {
      fprintf(this->map_file_, _("\nMemory map\n\n"));
      this->printed_memory_map_header_ = true;
    }
}

// Print the symbols associated with an input section.

template<int size, bool big_endian>
void
Mapfile::print_input_section_symbols(
    const Sized_relobj<size, big_endian>* relobj,
    unsigned int shndx)
{
  unsigned int symcount = relobj->symbol_count();
  for (unsigned int i = relobj->local_symbol_count(); i < symcount; ++i)
    {
      const Symbol* sym = relobj->global_symbol(i);
      bool is_ordinary;
      if (sym != NULL
	  && sym->source() == Symbol::FROM_OBJECT
	  && sym->object() == relobj
	  && sym->shndx(&is_ordinary) == shndx
	  && is_ordinary
	  && sym->is_defined())
	{
	  for (size_t i = 0; i < Mapfile::section_name_map_length; ++i)
	    putc(' ', this->map_file_);
	  const Sized_symbol<size>* ssym =
	    static_cast<const Sized_symbol<size>*>(sym);
	  fprintf(this->map_file_,
		  "0x%0*llx                %s\n",
		  size / 4,
		  static_cast<unsigned long long>(ssym->value()),
		  sym->demangled_name().c_str());
	}
    }
}

// Print an input section.

void
Mapfile::print_input_section(Relobj* relobj, unsigned int shndx)
{
  putc(' ', this->map_file_);

  std::string name = relobj->section_name(shndx);
  fprintf(this->map_file_, "%s", name.c_str());

  this->advance_to_column(name.length() + 1, Mapfile::section_name_map_length);

  Output_section* os;
  uint64_t addr;
  if (!relobj->is_section_included(shndx))
    {
      os = NULL;
      addr = 0;
    }
  else
    {
      os = relobj->output_section(shndx);
      addr = relobj->output_section_offset(shndx);
      if (addr != -1U)
	addr += os->address();
    }

  char sizebuf[50];
  snprintf(sizebuf, sizeof sizebuf, "0x%llx",
	   static_cast<unsigned long long>(relobj->section_size(shndx)));

  fprintf(this->map_file_, "0x%0*llx %10s %s\n",
	  parameters->target().get_size() / 4,
	  static_cast<unsigned long long>(addr), sizebuf,
	  relobj->name().c_str());

  if (os != NULL)
    {
      switch (parameters->size_and_endianness())
	{
#ifdef HAVE_TARGET_32_LITTLE
	case Parameters::TARGET_32_LITTLE:
	  {
	    const Sized_relobj<32, false>* sized_relobj =
	      static_cast<Sized_relobj<32, false>*>(relobj);
	    this->print_input_section_symbols(sized_relobj, shndx);
	  }
	  break;
#endif
#ifdef HAVE_TARGET_32_BIG
	case Parameters::TARGET_32_BIG:
	  {
	    const Sized_relobj<32, true>* sized_relobj =
	      static_cast<Sized_relobj<32, true>*>(relobj);
	    this->print_input_section_symbols(sized_relobj, shndx);
	  }
	  break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
	case Parameters::TARGET_64_LITTLE:
	  {
	    const Sized_relobj<64, false>* sized_relobj =
	      static_cast<Sized_relobj<64, false>*>(relobj);
	    this->print_input_section_symbols(sized_relobj, shndx);
	  }
	  break;
#endif
#ifdef HAVE_TARGET_64_BIG
	case Parameters::TARGET_64_BIG:
	  {
	    const Sized_relobj<64, true>* sized_relobj =
	      static_cast<Sized_relobj<64, true>*>(relobj);
	    this->print_input_section_symbols(sized_relobj, shndx);
	  }
	  break;
#endif
	default:
	  gold_unreachable();
	}
    }
}

// Print an Output_section_data.  This is printed to look like an
// input section.

void
Mapfile::print_output_data(const Output_data* od, const char* name)
{
  this->print_memory_map_header();

  putc(' ', this->map_file_);

  fprintf(this->map_file_, "%s", name);

  this->advance_to_column(strlen(name) + 1, Mapfile::section_name_map_length);

  char sizebuf[50];
  snprintf(sizebuf, sizeof sizebuf, "0x%llx",
	   static_cast<unsigned long long>(od->data_size()));

  fprintf(this->map_file_, "0x%0*llx %10s\n",
	  parameters->target().get_size() / 4,
	  static_cast<unsigned long long>(od->address()),
	  sizebuf);
}

// Print the discarded input sections.

void
Mapfile::print_discarded_sections(const Input_objects* input_objects)
{
  bool printed_header = false;
  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Relobj* relobj = *p;
      unsigned int shnum = relobj->shnum();
      for (unsigned int i = 0; i < shnum; ++i)
	{
	  unsigned int sh_type = relobj->section_type(i);
	  if ((sh_type == elfcpp::SHT_PROGBITS
	       || sh_type == elfcpp::SHT_NOBITS
	       || sh_type == elfcpp::SHT_GROUP)
	      && !relobj->is_section_included(i))
	    {
	      if (!printed_header)
		{
		  fprintf(this->map_file_, _("\nDiscarded input sections\n\n"));
		  printed_header = true;
		}

	      this->print_input_section(relobj, i);
	    }
	}
    }
}

// Print an output section.

void
Mapfile::print_output_section(const Output_section* os)
{
  this->print_memory_map_header();

  fprintf(this->map_file_, "\n%s", os->name());

  this->advance_to_column(strlen(os->name()), Mapfile::section_name_map_length);

  char sizebuf[50];
  snprintf(sizebuf, sizeof sizebuf, "0x%llx",
	   static_cast<unsigned long long>(os->data_size()));

  fprintf(this->map_file_, "0x%0*llx %10s",
	  parameters->target().get_size() / 4,
	  static_cast<unsigned long long>(os->address()), sizebuf);

  if (os->has_load_address())
    fprintf(this->map_file_, " load address 0x%-*llx",
	    parameters->target().get_size() / 4,
	    static_cast<unsigned long long>(os->load_address()));

  putc('\n', this->map_file_);
}

} // End namespace gold.
