Blob Blame History Raw
From e81f1faca4382ed5c8f15fec84fb7c900a5468f9 Mon Sep 17 00:00:00 2001
From: Glenn Morris <rgm@gnu.org>
Date: Mon, 11 Oct 2021 14:03:26 +0200
Subject: Make the installed pmdp file use a fingerprint

* Makefile.in (EMACS_PDMP): Use --fingerprint.

* doc/emacs/cmdargs.texi (Action Arguments): Document --fingerprint.

* src/emacs.c (load_pdump): Load the fingerprinted version of the
pdmp file (bug#42790).
(main): Support --fingerprint.

* src/pdumper.c (dump_fingerprint): Make non-static.

* src/pdumper.h: Declare dump_fingerprint.
---
 Makefile.in            |  3 ++-
 doc/emacs/cmdargs.texi |  5 +++++
 src/emacs.c            | 31 +++++++++++++++++++++++++++++--
 src/pdumper.c          |  2 +-
 src/pdumper.h          |  3 +++
 5 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 5fc1edc..c6c507f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -313,6 +313,7 @@ TRANSFORM = @program_transform_name@
 EMACS_NAME = `echo emacs | sed '$(TRANSFORM)'`
 EMACS = ${EMACS_NAME}${EXEEXT}
 EMACSFULL = `echo emacs-${version} | sed '$(TRANSFORM)'`${EXEEXT}
+EMACS_PDMP = `./src/emacs${EXEEXT} --fingerprint 2>&1 | sed 's/.* //'`.pdmp
 
 # Subdirectories to make recursively.
 SUBDIR = $(NTDIR) lib lib-src src lisp
@@ -521,7 +522,7 @@ install-arch-dep: src install-arch-indep install-etcdoc install-$(NTDIR)
 ifeq (${ns_self_contained},no)
 	${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs${EXEEXT} "$(DESTDIR)${bindir}/$(EMACSFULL)"
 ifeq (${DUMPING},pdumper)
-	${INSTALL_DATA} src/emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/emacs.pdmp
+	${INSTALL_DATA} src/emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/emacs-${EMACS_PDMP}
 endif
 	-chmod 755 "$(DESTDIR)${bindir}/$(EMACSFULL)"
 ifndef NO_BIN_LINK
diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index d5177fa..313682b 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -185,6 +185,11 @@ successfully.
 @item --version
 @opindex --version
 Print Emacs version, then exit successfully.
+
+@item --fingerprint
+@opindex --fingerprint
+Print the Emacs ``fingerprint'', which is used to uniquely identify
+the compiled version of Emacs.
 @end table
 
 @node Initial Options
diff --git a/src/emacs.c b/src/emacs.c
index 866e43f..cda7a9b 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -133,6 +133,7 @@ extern char etext;
 #endif
 
 #include "pdumper.h"
+#include "fingerprint.h"
 #include "epaths.h"
 
 static const char emacs_version[] = PACKAGE_VERSION;
@@ -255,6 +256,7 @@ Initialization options:\n\
 #ifdef HAVE_PDUMPER
     "\
 --dump-file FILE            read dumped state from FILE\n\
+--fingerprint               output fingerprint and exit\n\
 ",
 #endif
 #if SECCOMP_USABLE
@@ -830,6 +832,8 @@ load_pdump (int argc, char **argv)
   const char *const suffix = ".pdmp";
   int result;
   char *emacs_executable = argv[0];
+  ptrdiff_t hexbuf_size;
+  char *hexbuf;
   const char *strip_suffix =
 #if defined DOS_NT || defined CYGWIN
     ".exe"
@@ -927,9 +931,15 @@ load_pdump (int argc, char **argv)
   /* Look for "emacs.pdmp" in PATH_EXEC.  We hardcode "emacs" in
      "emacs.pdmp" so that the Emacs binary still works if the user
      copies and renames it.  */
+  hexbuf_size = 2 * sizeof fingerprint;
+  hexbuf = xmalloc (hexbuf_size + 1);
+  hexbuf_digest (hexbuf, (char *)fingerprint, sizeof fingerprint);
+  hexbuf[hexbuf_size] = '\0';
   needed = (strlen (path_exec)
 	    + 1
 	    + strlen (argv0_base)
+	    + 1
+	    + strlen (hexbuf)
 	    + strlen (suffix)
 	    + 1);
   if (bufsize < needed)
@@ -937,8 +947,8 @@ load_pdump (int argc, char **argv)
       xfree (dump_file);
       dump_file = xpalloc (NULL, &bufsize, needed - bufsize, -1, 1);
     }
-  sprintf (dump_file, "%s%c%s%s",
-           path_exec, DIRECTORY_SEP, argv0_base, suffix);
+  sprintf (dump_file, "%s%c%s-%s%s",
+           path_exec, DIRECTORY_SEP, argv0_base, hexbuf, suffix);
 #if !defined (NS_SELF_CONTAINED)
   /* Assume the Emacs binary lives in a sibling directory as set up by
      the default installation configuration.  */
@@ -1387,6 +1397,23 @@ main (int argc, char **argv)
       exit (0);
     }
 
+#ifdef HAVE_PDUMPER
+  if (argmatch (argv, argc, "-fingerprint", "--fingerprint", 4,
+		NULL, &skip_args))
+    {
+      if (initialized)
+        {
+          dump_fingerprint ("fingerprint", (unsigned char *)fingerprint);
+          exit (0);
+        }
+      else
+        {
+          fputs ("Not initialized\n", stderr);
+          exit (1);
+        }
+    }
+#endif
+
   emacs_wd = emacs_get_current_dir_name ();
 #ifdef HAVE_PDUMPER
   if (dumped_with_pdumper_p ())
diff --git a/src/pdumper.c b/src/pdumper.c
index 11c680d..977f4fb 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -312,7 +312,7 @@ dump_reloc_set_offset (struct dump_reloc *reloc, dump_off offset)
     error ("dump relocation out of range");
 }
 
-static void
+void
 dump_fingerprint (char const *label,
 		  unsigned char const xfingerprint[sizeof fingerprint])
 {
diff --git a/src/pdumper.h b/src/pdumper.h
index deec9af..bc339c4 100644
--- a/src/pdumper.h
+++ b/src/pdumper.h
@@ -50,6 +50,9 @@ enum { PDUMPER_NO_OBJECT = -1 };
 #define PDUMPER_REMEMBER_SCALAR(thing)                  \
   pdumper_remember_scalar (&(thing), sizeof (thing))
 
+extern void dump_fingerprint (const char *label,
+                              const unsigned char *xfingerprint);
+
 extern void pdumper_remember_scalar_impl (void *data, ptrdiff_t nbytes);
 
 INLINE void
-- 
cgit v1.1