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

// Copyright (C) 2008-2021 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_file<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 != -1ULL)
	addr += os->address();
    }

  char sizebuf[50];
  section_size_type size;
  if (!relobj->section_is_compressed(shndx, &size))
    size = relobj->section_size(shndx);
  snprintf(sizebuf, sizeof sizebuf, "0x%llx",
	   static_cast<unsigned long long>(size));

  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_file<32, false>* sized_relobj =
	      static_cast<Sized_relobj_file<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_file<32, true>* sized_relobj =
	      static_cast<Sized_relobj_file<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_file<64, false>* sized_relobj =
	      static_cast<Sized_relobj_file<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_file<64, true>* sized_relobj =
	      static_cast<Sized_relobj_file<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->current_data_size()));

  fprintf(this->map_file_, "0x%0*llx %10s\n",
	  parameters->target().get_size() / 4,
	  (od->is_address_valid()
	   ? static_cast<unsigned long long>(od->address())
	   : 0),
	  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;
      // Lock the object so we can read from it.  This is only called
      // single-threaded from Layout_task_runner, so it is OK to lock.
      // Unfortunately we have no way to pass in a Task token.
      const Task* dummy_task = reinterpret_cast<const Task*>(-1);
      Task_lock_obj<Object> tl(dummy_task, relobj);

      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->current_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()));

  if (os->requires_postprocessing())
    fprintf(this->map_file_, " (before compression)");

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

} // End namespace gold.
