/* Core file generic interface routines for BFD.
   Copyright (C) 1990-2021 Free Software Foundation, Inc.
   Written by Cygnus Support.

   This file is part of BFD, the Binary File Descriptor library.

   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.  */

/*
SECTION
	Core files

SUBSECTION
	Core file functions

DESCRIPTION
	These are functions pertaining to core files.
*/

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"

/*
FUNCTION
	bfd_core_file_failing_command

SYNOPSIS
	const char *bfd_core_file_failing_command (bfd *abfd);

DESCRIPTION
	Return a read-only string explaining which program was running
	when it failed and produced the core file @var{abfd}.

*/

const char *
bfd_core_file_failing_command (bfd *abfd)
{
  if (abfd->format != bfd_core)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return NULL;
    }
  return BFD_SEND (abfd, _core_file_failing_command, (abfd));
}

/*
FUNCTION
	bfd_core_file_failing_signal

SYNOPSIS
	int bfd_core_file_failing_signal (bfd *abfd);

DESCRIPTION
	Returns the signal number which caused the core dump which
	generated the file the BFD @var{abfd} is attached to.
*/

int
bfd_core_file_failing_signal (bfd *abfd)
{
  if (abfd->format != bfd_core)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return 0;
    }
  return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
}

/*
FUNCTION
	bfd_core_file_pid

SYNOPSIS
	int bfd_core_file_pid (bfd *abfd);

DESCRIPTION

	Returns the PID of the process the core dump the BFD
	@var{abfd} is attached to was generated from.
*/

int
bfd_core_file_pid (bfd *abfd)
{
  if (abfd->format != bfd_core)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return 0;
    }
  return BFD_SEND (abfd, _core_file_pid, (abfd));
}


/*
FUNCTION
	core_file_matches_executable_p

SYNOPSIS
	bool core_file_matches_executable_p
	  (bfd *core_bfd, bfd *exec_bfd);

DESCRIPTION
	Return <<TRUE>> if the core file attached to @var{core_bfd}
	was generated by a run of the executable file attached to
	@var{exec_bfd}, <<FALSE>> otherwise.
*/

bool
core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
{
  if (core_bfd->format != bfd_core || exec_bfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_wrong_format);
      return false;
    }

  return BFD_SEND (core_bfd, _core_file_matches_executable_p,
		   (core_bfd, exec_bfd));
}

/*
FUNCTION
	generic_core_file_matches_executable_p

SYNOPSIS
	bool generic_core_file_matches_executable_p
	  (bfd *core_bfd, bfd *exec_bfd);

DESCRIPTION
	Return TRUE if the core file attached to @var{core_bfd}
	was generated by a run of the executable file attached
	to @var{exec_bfd}.  The match is based on executable
	basenames only.

	Note: When not able to determine the core file failing
	command or the executable name, we still return TRUE even
	though we're not sure that core file and executable match.
	This is to avoid generating a false warning in situations
	where we really don't know whether they match or not.
*/

bool
generic_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
{
  const char *exec;
  const char *core;
  const char *last_slash;

  if (exec_bfd == NULL || core_bfd == NULL)
    return true;

  /* The cast below is to avoid a compiler warning due to the assignment
     of the const char * returned by bfd_core_file_failing_command to a
     non-const char *.  In this case, the assignement does not lead to
     breaking the const, as we're only reading the string.  */

  core = bfd_core_file_failing_command (core_bfd);
  if (core == NULL)
    return true;

  exec = bfd_get_filename (exec_bfd);
  if (exec == NULL)
    return true;

  last_slash = strrchr (core, '/');
  if (last_slash != NULL)
    core = last_slash + 1;

  last_slash = strrchr (exec, '/');
  if (last_slash != NULL)
    exec = last_slash + 1;

  return filename_cmp (exec, core) == 0;
}

