Subject: Re: bug#42790: [PATH] 27.1; Add version info into file name "emacs.pdmp" to avoid mismatch pdmp file

From: Glenn Morris <[email-masked]>
Date: Sun, 15 Nov 2020 20:03:57 -0500

I have also had problems with configure's transform argument being
ignored for the pdmp file, and with the pdmp file not being found.

Here is a simple-minded proof-of-concept patch for installing the pdmp
file with the fingerprint in the name. It needs cleaning up (compilation
warnings; hexbuf stuff is awful; should look for FINGERPRINT.pdmp first,
then fall back to less specific names, finishing with emacs.pdmp; etc).
Hopefully people who know more about this stuff than me will feel like
finishing this off...

diff --git a/Makefile.in b/Makefile.in
index fbb1891ba7..d1c228c5f3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -309,6 +309,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
@@ -495,7 +496,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_PDMP}
 endif
 	-chmod 755 "$(DESTDIR)${bindir}/$(EMACSFULL)"
 ifndef NO_BIN_LINK
diff --git a/src/emacs.c b/src/emacs.c
index 172e460769..1743e1cc99 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -117,6 +117,7 @@ extern char etext;
 #endif
 
 #include "pdumper.h"
+#include "fingerprint.h"
 #include "epaths.h"
 
 static const char emacs_version[] = PACKAGE_VERSION;
@@ -238,6 +239,7 @@ Initialization options:\n\
 #ifdef HAVE_PDUMPER
     "\
 --dump-file FILE            read dumped state from FILE\n\
+--fingerprint               output fingerprint and exit\n\
 ",
 #endif
     "\
@@ -868,9 +870,15 @@ load_pdump (int argc, char **argv)
      "emacs.pdmp" so that the Emacs binary still works if the user
      copies and renames it.  */
   const char *argv0_base = "emacs";
+  enum { hexbuf_size = 2 * sizeof fingerprint };
+  char hexbuf[hexbuf_size];
+  hexbuf_digest (hexbuf, fingerprint, sizeof fingerprint);
+  char finger[hexbuf_size];
+  strcpy (finger, hexbuf);
+  finger[sizeof hexbuf] = '\0';
   ptrdiff_t needed = (strlen (path_exec)
                       + 1
-                      + strlen (argv0_base)
+                      + strlen (finger)
                       + strlen (suffix)
                       + 1);
   if (bufsize < needed)
@@ -879,7 +887,7 @@ load_pdump (int argc, char **argv)
       dump_file = xpalloc (NULL, &bufsize, needed - bufsize, -1, 1);
     }
   sprintf (dump_file, "%s%c%s%s",
-           path_exec, DIRECTORY_SEP, argv0_base, suffix);
+           path_exec, DIRECTORY_SEP, finger, suffix);
   result = pdumper_load (dump_file);
 
   if (result == PDUMPER_LOAD_FILE_NOT_FOUND)
@@ -1129,6 +1137,22 @@ 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", 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 b5b4050b93..c8d7378221 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -311,7 +311,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 c793fb4058..2028b44f81 100644
--- a/src/pdumper.h
+++ b/src/pdumper.h
@@ -50,6 +50,10 @@ 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