/* Precompiled header implementation for the C languages.
   Copyright (C) 2000-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option)
any later version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "c-common.h"
#include "timevar.h"
#include "flags.h"
#include "debug.h"
#include "c-pragma.h"
#include "langhooks.h"
#include "hosthooks.h"

/* This is a list of flag variables that must match exactly, and their
   names for the error message.  The possible values for *flag_var must
   fit in a 'signed char'.  */

static const struct c_pch_matching
{
  int *flag_var;
  const char *flag_name;
} pch_matching[] = {
  { &flag_exceptions, "-fexceptions" },
};

enum {
  MATCH_SIZE = ARRAY_SIZE (pch_matching)
};

/* Information about flags and suchlike that affect PCH validity.

   Before this structure is read, both an initial 8-character identification
   string, and a 16-byte checksum, have been read and validated.  */

struct c_pch_validity
{
  uint32_t pch_write_symbols;
  signed char match[MATCH_SIZE];
  void (*pch_init) (void);
  size_t target_data_length;
};

#define IDENT_LENGTH 8

/* The file we'll be writing the PCH to.  */
static FILE *pch_outfile;

static const char *get_ident (void);

/* Compute an appropriate 8-byte magic number for the PCH file, so that
   utilities like file(1) can identify it, and so that GCC can quickly
   ignore non-PCH files and PCH files that are of a completely different
   format.  */

static const char *
get_ident (void)
{
  static char result[IDENT_LENGTH];
  static const char templ[] = "gpch.014";
  static const char c_language_chars[] = "Co+O";

  memcpy (result, templ, IDENT_LENGTH);
  result[4] = c_language_chars[c_language];

  return result;
}

/* Whether preprocessor state should be saved by pch_init.  */

static bool pch_ready_to_save_cpp_state = false;

/* Prepare to write a PCH file, if one is being written.  This is
   called at the start of compilation.  */

void
pch_init (void)
{
  FILE *f;
  struct c_pch_validity v;
  void *target_validity;
  static const char partial_pch[] = "gpcWrite";

  if (!pch_file)
    return;

  f = fopen (pch_file, "w+b");
  if (f == NULL)
    fatal_error (input_location, "cannot create precompiled header %s: %m",
		 pch_file);
  pch_outfile = f;

  memset (&v, '\0', sizeof (v));
  v.pch_write_symbols = write_symbols;
  {
    size_t i;
    for (i = 0; i < MATCH_SIZE; i++)
      {
	v.match[i] = *pch_matching[i].flag_var;
	gcc_assert (v.match[i] == *pch_matching[i].flag_var);
      }
  }
  v.pch_init = &pch_init;
  target_validity = targetm.get_pch_validity (&v.target_data_length);

  if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
      || fwrite (executable_checksum, 16, 1, f) != 1
      || fwrite (&v, sizeof (v), 1, f) != 1
      || fwrite (target_validity, v.target_data_length, 1, f) != 1)
    fatal_error (input_location, "cannot write to %s: %m", pch_file);

  /* Let the debugging format deal with the PCHness.  */
  (*debug_hooks->handle_pch) (0);

  if (pch_ready_to_save_cpp_state)
    pch_cpp_save_state ();

  XDELETE (target_validity);
}

/* Whether preprocessor state has been saved in a PCH file.  */

static bool pch_cpp_state_saved = false;

/* Save preprocessor state in a PCH file, after implicitly included
   headers have been read.  If the PCH file has not yet been opened,
   record that state should be saved when it is opened.  */

void
pch_cpp_save_state (void)
{
  if (!pch_cpp_state_saved)
    {
      if (pch_outfile)
	{
	  cpp_save_state (parse_in, pch_outfile);
	  pch_cpp_state_saved = true;
	}
      else
	pch_ready_to_save_cpp_state = true;
    }
}

/* Write the PCH file.  This is called at the end of a compilation which
   will produce a PCH file.  */

void
c_common_write_pch (void)
{
  timevar_push (TV_PCH_SAVE);

  targetm.prepare_pch_save ();

  (*debug_hooks->handle_pch) (1);

  prepare_target_option_nodes_for_pch ();

  cpp_write_pch_deps (parse_in, pch_outfile);

  gt_pch_save (pch_outfile);

  timevar_push (TV_PCH_CPP_SAVE);
  cpp_write_pch_state (parse_in, pch_outfile);
  timevar_pop (TV_PCH_CPP_SAVE);

  if (fseek (pch_outfile, 0, SEEK_SET) != 0
      || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
    fatal_error (input_location, "cannot write %s: %m", pch_file);

  fclose (pch_outfile);

  timevar_pop (TV_PCH_SAVE);
}

/* Check the PCH file called NAME, open on FD, to see if it can be
   used in this compilation.  Return 1 if valid, 0 if the file can't
   be used now but might be if it's seen later in the compilation, and
   2 if this file could never be used in the compilation.  */

int
c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
{
  int sizeread;
  int result;
  char ident[IDENT_LENGTH + 16];
  const char *pch_ident;
  struct c_pch_validity v;

  /* Perform a quick test of whether this is a valid
     precompiled header for the current language.  */

  /* C++ modules and PCH don't play together.  */
  if (flag_modules)
    return 2;

  sizeread = read (fd, ident, IDENT_LENGTH + 16);
  if (sizeread == -1)
    fatal_error (input_location, "cannot read %s: %m", name);
  else if (sizeread != IDENT_LENGTH + 16)
    {
      cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: too short to be a PCH file",
		   name);
      return 2;
    }

  pch_ident = get_ident();
  if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
    {
	if (memcmp (ident, pch_ident, 5) == 0)
	  /* It's a PCH, for the right language, but has the wrong version.  */
	  cpp_warning (pfile, CPP_W_INVALID_PCH,
		       "%s: not compatible with this GCC version", name);
	else if (memcmp (ident, pch_ident, 4) == 0)
	  /* It's a PCH for the wrong language.  */
	  cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not for %s", name,
		       lang_hooks.name);
	else
	  /* Not any kind of PCH.  */
	  cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not a PCH file", name);
      return 2;
    }
  if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
    {
      cpp_warning (pfile, CPP_W_INVALID_PCH,
		   "%s: created by a different GCC executable", name);
      return 2;
    }

  /* At this point, we know it's a PCH file created by this
     executable, so it ought to be long enough that we can read a
     c_pch_validity structure.  */
  if (read (fd, &v, sizeof (v)) != sizeof (v))
    fatal_error (input_location, "cannot read %s: %m", name);

  /* The allowable debug info combinations are that either the PCH file
     was built with the same as is being used now, or the PCH file was
     built for some kind of debug info but now none is in use.  */
  if (v.pch_write_symbols != write_symbols
      && write_symbols != NO_DEBUG)
    {
      char *created_str = xstrdup (debug_set_names (v.pch_write_symbols));
      char *used_str = xstrdup (debug_set_names (write_symbols));
      cpp_warning (pfile, CPP_W_INVALID_PCH,
		   "%s: created with '%s' debug info, but used with '%s'", name,
		   created_str, used_str);
      free (created_str);
      free (used_str);
      return 2;
    }

  /* Check flags that must match exactly.  */
  {
    size_t i;
    for (i = 0; i < MATCH_SIZE; i++)
      if (*pch_matching[i].flag_var != v.match[i])
	{
	  cpp_warning (pfile, CPP_W_INVALID_PCH,
		       "%s: settings for %s do not match", name,
		       pch_matching[i].flag_name);
	  return 2;
	}
  }

  /* If the text segment was not loaded at the same address as it was
     when the PCH file was created, function pointers loaded from the
     PCH will not be valid.  We could in theory remap all the function
     pointers, but no support for that exists at present.
     Since we have the same executable, it should only be necessary to
     check one function.  */
  if (v.pch_init != &pch_init)
    {
      cpp_warning (pfile, CPP_W_INVALID_PCH,
		   "%s: had text segment at different address", name);
      return 2;
    }

  /* Check the target-specific validity data.  */
  {
    void *this_file_data = xmalloc (v.target_data_length);
    const char *msg;

    if ((size_t) read (fd, this_file_data, v.target_data_length)
	!= v.target_data_length)
      fatal_error (input_location, "cannot read %s: %m", name);
    msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
    free (this_file_data);
    if (msg != NULL)
      {
	cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: %s", name, msg);
	return 2;
      }
  }

  /* Check the preprocessor macros are the same as when the PCH was
     generated.  */

  result = cpp_valid_state (pfile, name, fd);
  if (result == -1)
    return 2;
  else
    return result == 0;
}

/* If non-NULL, this function is called after a precompile header file
   is loaded.  */
void (*lang_post_pch_load) (void);

/* Load in the PCH file NAME, open on FD.  It was originally searched for
   by ORIG_NAME.  */

void
c_common_read_pch (cpp_reader *pfile, const char *name,
		   int fd, const char *orig_name ATTRIBUTE_UNUSED)
{
  FILE *f;
  struct save_macro_data *smd;
  expanded_location saved_loc;
  bool saved_trace_includes;

  timevar_push (TV_PCH_RESTORE);

  f = fdopen (fd, "rb");
  if (f == NULL)
    {
      cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
      close (fd);
      goto end;
    }

  cpp_get_callbacks (parse_in)->valid_pch = NULL;

  /* Save the location and then restore it after reading the PCH.  */
  saved_loc = expand_location (line_table->highest_line);
  saved_trace_includes = line_table->trace_includes;

  timevar_push (TV_PCH_CPP_RESTORE);
  cpp_prepare_state (pfile, &smd);
  timevar_pop (TV_PCH_CPP_RESTORE);

  gt_pch_restore (f);
  cpp_set_line_map (pfile, line_table);
  rebuild_location_adhoc_htab (line_table);

  timevar_push (TV_PCH_CPP_RESTORE);
  if (cpp_read_state (pfile, name, f, smd) != 0)
    {
      fclose (f);
      timevar_pop (TV_PCH_CPP_RESTORE);
      goto end;
    }
  timevar_pop (TV_PCH_CPP_RESTORE);


  fclose (f);

  line_table->trace_includes = saved_trace_includes;
  linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line);

  /* Give the front end a chance to take action after a PCH file has
     been loaded.  */
  if (lang_post_pch_load)
    (*lang_post_pch_load) ();

end:
  timevar_pop (TV_PCH_RESTORE);
}

/* Indicate that no more PCH files should be read.  */

void
c_common_no_more_pch (void)
{
  if (cpp_get_callbacks (parse_in)->valid_pch)
    {
      cpp_get_callbacks (parse_in)->valid_pch = NULL;
      host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
    }
}

/* Handle #pragma GCC pch_preprocess, to load in the PCH file.  */

void
c_common_pch_pragma (cpp_reader *pfile, const char *name)
{
  int fd;

  if (!cpp_get_options (pfile)->preprocessed)
    {
      error ("%<pch_preprocess%> pragma should only be used "
	     "with %<-fpreprocessed%>");
      inform (input_location, "use %<#include%> instead");
      return;
    }

  fd = open (name, O_RDONLY | O_BINARY, 0666);
  if (fd == -1)
    fatal_error (input_location, "%s: couldn%'t open PCH file: %m", name);

  if (c_common_valid_pch (pfile, name, fd) != 1)
    {
      if (!cpp_get_options (pfile)->warn_invalid_pch)
	inform (input_location, "use %<-Winvalid-pch%> for more information");
      fatal_error (input_location, "%s: PCH file was invalid", name);
    }

  c_common_read_pch (pfile, name, fd, name);

  close (fd);
}

