]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix loading *.eln files when Emacs is installed via symlinks
authorEli Zaretskii <eliz@gnu.org>
Sat, 17 Apr 2021 13:49:16 +0000 (16:49 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 17 Apr 2021 13:49:16 +0000 (16:49 +0300)
* src/emacs.c (real_filename, set_invocation_vars)
(init_vars_for_load): Functions deleted; callers adjusted.
(init_cmdargs): Put back all the code which was extracted into
set_invocation_vars.
(load_pdump_find_executable): Make sure the return value has any
symlinks in it expanded.
(load_pdump): Accept only 2 arguments, not 3.  Determine both the
file name of the Emacs executable and of the dump file in
synchronized manner, so that if we decided to look for the dump
file in its hardcoded installation directory, the directory of the
Emacs executable will also be where we expect it to be installed.
Pass only 2 arguments to pdumper_load.  (Bug#47800)  (Bug#44128)
* src/pdumper.c (dump_do_dump_relocation): Use emacs_execdir
instead of Vinvocation_directory to produce absolute file names of
*.eln files that are recorded in the pdumper file.  Pass the full
.eln file name to fixup_eln_load_path.
(pdumper_set_emacs_execdir) [HAVE_NATIVE_COMP]: New function.
(pdumper_load) [HAVE_NATIVE_COMP]: Call pdumper_set_emacs_execdir.
* src/comp.c (fixup_eln_load_path): Use Fsubstring_no_properties
instead of Fsubstring.  No need to cons a file name, as the caller
already did that.  Use explicit const string to avoid "magic"
values.

* lisp/startup.el (normal-top-level): Use expand-file-name instead
of concat.  Decode comp-eln-load-path and expand-file-name its
members.

lisp/startup.el
src/comp.c
src/comp.h
src/emacs.c
src/lisp.h
src/pdumper.c
src/pdumper.h

index 6e0faf3f68a52d186d1b83a95921ad82aba60212..01d28141654a95b6a4291ff4b4098c9de61c6d4c 100644 (file)
@@ -544,7 +544,8 @@ It is the default value of the variable `top-level'."
           (dolist (path (split-string path-env path-separator))
             (unless (string= "" path)
               (push path comp-eln-load-path)))))
-      (push (concat user-emacs-directory "eln-cache/") comp-eln-load-path)
+      (push (expand-file-name "eln-cache/" user-emacs-directory)
+            comp-eln-load-path)
       ;; When $HOME is set to '/nonexistent' means we are running the
       ;; testsuite, add a temporary folder in front to produce there
       ;; new compilations.
@@ -636,6 +637,16 @@ It is the default value of the variable `top-level'."
                (set pathsym (mapcar (lambda (dir)
                                       (decode-coding-string dir coding t))
                                     path)))))
+        (when (featurep 'nativecomp)
+          (let ((npath (symbol-value 'comp-eln-load-path)))
+            (set 'comp-eln-load-path
+                 (mapcar (lambda (dir)
+                           ;; Call expand-file-name to remove all the
+                           ;; pesky ".." from the directyory names in
+                           ;; comp-eln-load-path.
+                           (expand-file-name
+                            (decode-coding-string dir coding t)))
+                         npath))))
        (dolist (filesym '(data-directory doc-directory exec-directory
                                          installation-directory
                                          invocation-directory invocation-name
index c4b9b4b6c10d3ebe9f44b11505b128ca0024c021..50947316df8f3ad1b9151f9b2731c9a5062f8a46 100644 (file)
@@ -4749,29 +4749,30 @@ maybe_defer_native_compilation (Lisp_Object function_name,
 /* Functions used to load eln files.  */
 /**************************************/
 
-/* Fixup the system eln-cache dir.  This is the last entry in
-   `comp-eln-load-path'.  */
+/* Fixup the system eln-cache directory, which is the last entry in
+   `comp-eln-load-path'.  Argument is a .eln file in that directory.  */
 void
 fixup_eln_load_path (Lisp_Object eln_filename)
 {
   Lisp_Object last_cell = Qnil;
-  Lisp_Object tmp = Vcomp_eln_load_path;
-  FOR_EACH_TAIL (tmp)
-    if (CONSP (tmp))
-      last_cell = tmp;
-
-  Lisp_Object eln_cache_sys =
-    Ffile_name_directory (concat2 (Vinvocation_directory,
-                                  eln_filename));
-  bool preloaded =
-    !NILP (Fequal (Fsubstring (eln_cache_sys, make_fixnum (-10),
-                              make_fixnum (-1)),
-                  build_string ("preloaded")));
+  Lisp_Object tem = Vcomp_eln_load_path;
+  FOR_EACH_TAIL (tem)
+    if (CONSP (tem))
+      last_cell = tem;
+
+  const char preloaded[] = "preloaded";
+  ptrdiff_t preloaded_len = sizeof (preloaded) - 1;
+  Lisp_Object eln_cache_sys = Ffile_name_directory (eln_filename);
+  bool preloaded_p =
+    !NILP (Fequal (Fsubstring_no_properties (eln_cache_sys,
+                                            make_fixnum (-preloaded_len - 1),
+                                            make_fixnum (-1)),
+                  build_string (preloaded)));
   /* One or two directories up...  */
-  for (int i = 0; i < (preloaded ? 2 : 1); i++)
+  for (int i = 0; i < (preloaded_p ? 2 : 1); i++)
     eln_cache_sys =
-      Ffile_name_directory (Fsubstring (eln_cache_sys, Qnil,
-                                       make_fixnum (-1)));
+      Ffile_name_directory (Fsubstring_no_properties (eln_cache_sys, Qnil,
+                                                     make_fixnum (-1)));
   Fsetcar (last_cell, eln_cache_sys);
 }
 
index e17b843d139cbee902c5a89e46cef7a34e426822..03d22dfaa0ebb801360354974c854dd8c4967440 100644 (file)
@@ -34,7 +34,11 @@ enum {
 struct Lisp_Native_Comp_Unit
 {
   union vectorlike_header header;
-  /* Original eln file loaded. */
+  /* The original eln file loaded.  In the pdumper file this is stored
+     as a cons cell of 2 alternative file names: the car is the
+     filename relative to the directory of an installed binary, the
+     cdr is the filename relative to the directory of an uninstalled
+     binary.  This is arranged in loadup.el.  */
   Lisp_Object file;
   Lisp_Object optimize_qualities;
   /* Guard anonymous lambdas against Garbage Collection and serve
index a2565645c6ce9deea701548aa9f444dd63755498..d27b1c1351d620280ccf135f3bac79240dd7cc12 100644 (file)
@@ -440,53 +440,33 @@ terminate_due_to_signal (int sig, int backtrace_limit)
   exit (1);
 }
 
-/* Return the real filename following symlinks in case.
-   The caller should deallocate the returned buffer.  */
-
-static char *
-real_filename (char *filename)
-{
-  char *real_name;
-#ifdef WINDOWSNT
-  /* w32_my_exename resolves symlinks internally, so no need to
-     call realpath.  */
-  real_name = xstrdup (filename);
-#else
-  real_name = realpath (filename, NULL);
-  if (!real_name)
-    fatal ("could not resolve realpath of \"%s\": %s",
-          filename, strerror (errno));
-#endif
-  return real_name;
-}
-
-/* Set `invocation-name' `invocation-directory'.  */
-
+\f
+/* Code for dealing with Lisp access to the Unix command line.  */
 static void
-set_invocation_vars (char *argv0, char const *original_pwd)
+init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
 {
-  Lisp_Object raw_name, handler;
+  int i;
+  Lisp_Object name, dir, handler;
+  ptrdiff_t count = SPECPDL_INDEX ();
+  Lisp_Object raw_name;
   AUTO_STRING (slash_colon, "/:");
 
+  initial_argv = argv;
+  initial_argc = argc;
+
 #ifdef WINDOWSNT
-  /* Must use argv0 converted to UTF-8, as it begets many standard
+  /* Must use argv[0] converted to UTF-8, as it begets many standard
      file and directory names.  */
   {
-    char argv0_1[MAX_UTF8_PATH];
+    char argv0[MAX_UTF8_PATH];
 
-    /* Avoid calling 'openp' below, as we aren't ready for that yet:
-       emacs_dir is not yet defined in the environment, and therefore
-       emacs_root_dir, called by expand-file-name, will abort.  */
-    if (!IS_ABSOLUTE_FILE_NAME (argv0))
-      argv0 = w32_my_exename ();
-
-    if (filename_from_ansi (argv0, argv0_1) == 0)
-      raw_name = build_unibyte_string (argv0_1);
-    else
+    if (filename_from_ansi (argv[0], argv0) == 0)
       raw_name = build_unibyte_string (argv0);
+    else
+      raw_name = build_unibyte_string (argv[0]);
   }
 #else
-  raw_name = build_unibyte_string (argv0);
+  raw_name = build_unibyte_string (argv[0]);
 #endif
 
   /* Add /: to the front of the name
@@ -495,26 +475,16 @@ set_invocation_vars (char *argv0, char const *original_pwd)
   if (! NILP (handler))
     raw_name = concat2 (slash_colon, raw_name);
 
-  char *filename = real_filename (SSDATA (raw_name));
-  raw_name = build_unibyte_string (filename);
-  xfree (filename);
-
   Vinvocation_name = Ffile_name_nondirectory (raw_name);
   Vinvocation_directory = Ffile_name_directory (raw_name);
 
-#ifdef WINDOWSNT
-  eassert (!NILP (Vinvocation_directory)
-          && !NILP (Ffile_name_absolute_p (Vinvocation_directory)));
-#endif
-
-  /* If we got no directory in argv0, search PATH to find where
+  /* If we got no directory in argv[0], search PATH to find where
      Emacs actually came from.  */
   if (NILP (Vinvocation_directory))
     {
       Lisp_Object found;
-      int yes =
-       openp (Vexec_path, Vinvocation_name, Vexec_suffixes, &found,
-              make_fixnum (X_OK), false, false);
+      int yes = openp (Vexec_path, Vinvocation_name, Vexec_suffixes,
+                      &found, make_fixnum (X_OK), false, false);
       if (yes == 1)
        {
          /* Add /: to the front of the name
@@ -536,38 +506,6 @@ set_invocation_vars (char *argv0, char const *original_pwd)
 
       Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir);
     }
-}
-
-/* Initialize a number of variables (ultimately
-   'Vinvocation_directory') needed by pdumper to complete native code
-   load.  */
-
-void
-init_vars_for_load (char *argv0, char const *original_pwd)
-{
-  /* This function is called from within pdumper while loading (as
-     soon as we are able to allocate) or later during boot if pdumper
-     is not used.  No need to run it twice.  */
-  static bool double_run_guard;
-  if (double_run_guard)
-    return;
-  double_run_guard = true;
-
-  init_callproc_1 ();  /* Must precede init_cmdargs and init_sys_modes.  */
-  set_invocation_vars (argv0, original_pwd);
-}
-
-\f
-/* Code for dealing with Lisp access to the Unix command line.  */
-static void
-init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
-{
-  int i;
-  Lisp_Object name, dir;
-  ptrdiff_t count = SPECPDL_INDEX ();
-
-  initial_argv = argv;
-  initial_argc = argc;
 
   Vinstallation_directory = Qnil;
 
@@ -801,6 +739,8 @@ load_pdump_find_executable (char const *argv0, ptrdiff_t *candidate_size)
      implementation of malloc, since the caller calls our free.  */
 #ifdef WINDOWSNT
   char *prog_fname = w32_my_exename ();
+  if (prog_fname)
+    *candidate_size = strlen (prog_fname) + 1;
   return prog_fname ? xstrdup (prog_fname) : NULL;
 #else  /* !WINDOWSNT */
   char *candidate = NULL;
@@ -846,7 +786,19 @@ load_pdump_find_executable (char const *argv0, ptrdiff_t *candidate_size)
       struct stat st;
       if (file_access_p (candidate, X_OK)
          && stat (candidate, &st) == 0 && S_ISREG (st.st_mode))
-       return candidate;
+       {
+         /* People put on PATH a symlink to the real Emacs
+            executable, with all the auxiliary files where the real
+            executable lives.  Support that.  */
+         if (lstat (candidate, &st) == 0 && S_ISLNK (st.st_mode))
+           {
+             char *real_name = realpath (candidate, NULL);
+
+             if (real_name)
+               return real_name;
+           }
+         return candidate;
+       }
       *candidate = '\0';
     }
   while (*path++ != '\0');
@@ -856,10 +808,11 @@ load_pdump_find_executable (char const *argv0, ptrdiff_t *candidate_size)
 }
 
 static void
-load_pdump (int argc, char **argv, char const *original_pwd)
+load_pdump (int argc, char **argv)
 {
   const char *const suffix = ".pdmp";
   int result;
+  char *emacs_executable = argv[0];
   const char *strip_suffix =
 #if defined DOS_NT || defined CYGWIN
     ".exe"
@@ -889,9 +842,19 @@ load_pdump (int argc, char **argv, char const *original_pwd)
       skip_args++;
     }
 
+  /* Where's our executable?  */
+  ptrdiff_t bufsize, exec_bufsize;
+  emacs_executable = load_pdump_find_executable (argv[0], &bufsize);
+  exec_bufsize = bufsize;
+
+  /* If we couldn't find our executable, go straight to looking for
+     the dump in the hardcoded location.  */
+  if (!(emacs_executable && *emacs_executable))
+    goto hardcoded;
+
   if (dump_file)
     {
-      result = pdumper_load (dump_file, argv[0], original_pwd);
+      result = pdumper_load (dump_file, emacs_executable);
 
       if (result != PDUMPER_LOAD_SUCCESS)
         fatal ("could not load dump file \"%s\": %s",
@@ -905,42 +868,29 @@ load_pdump (int argc, char **argv, char const *original_pwd)
      so we can't use decode_env_path.  We're working in whatever
      encoding the system natively uses for filesystem access, so
      there's no need for character set conversion.  */
-  ptrdiff_t bufsize;
-  dump_file = load_pdump_find_executable (argv[0], &bufsize);
-
-  /* If we couldn't find our executable, go straight to looking for
-     the dump in the hardcoded location.  */
-  if (dump_file && *dump_file)
-    {
-      char *real_exename = real_filename (dump_file);
-      xfree (dump_file);
-      dump_file = real_exename;
-      ptrdiff_t exenamelen = strlen (dump_file);
-#ifndef WINDOWSNT
-      bufsize = exenamelen + 1;
-#endif
-      if (strip_suffix)
-        {
-         ptrdiff_t strip_suffix_length = strlen (strip_suffix);
-         ptrdiff_t prefix_length = exenamelen - strip_suffix_length;
-         if (0 <= prefix_length
-             && !memcmp (&dump_file[prefix_length], strip_suffix,
-                         strip_suffix_length))
-           exenamelen = prefix_length;
-        }
-      ptrdiff_t needed = exenamelen + strlen (suffix) + 1;
-      if (bufsize < needed)
-       dump_file = xpalloc (dump_file, &bufsize, needed - bufsize, -1, 1);
-      strcpy (dump_file + exenamelen, suffix);
-      result = pdumper_load (dump_file, argv[0], original_pwd);
-      if (result == PDUMPER_LOAD_SUCCESS)
-        goto out;
-
-      if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
-        fatal ("could not load dump file \"%s\": %s",
-               dump_file, dump_error_to_string (result));
-    }
-
+  ptrdiff_t exenamelen = strlen (emacs_executable);
+  if (strip_suffix)
+    {
+      ptrdiff_t strip_suffix_length = strlen (strip_suffix);
+      ptrdiff_t prefix_length = exenamelen - strip_suffix_length;
+      if (0 <= prefix_length
+         && !memcmp (&emacs_executable[prefix_length], strip_suffix,
+                     strip_suffix_length))
+       exenamelen = prefix_length;
+    }
+  ptrdiff_t needed = exenamelen + strlen (suffix) + 1;
+  dump_file = xpalloc (NULL, &bufsize, needed - bufsize, -1, 1);
+  memcpy (dump_file, emacs_executable, exenamelen);
+  strcpy (dump_file + exenamelen, suffix);
+  result = pdumper_load (dump_file, emacs_executable);
+  if (result == PDUMPER_LOAD_SUCCESS)
+    goto out;
+
+  if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
+    fatal ("could not load dump file \"%s\": %s",
+          dump_file, dump_error_to_string (result));
+
+ hardcoded:
 #ifdef WINDOWSNT
   /* On MS-Windows, PATH_EXEC normally starts with a literal
      "%emacs_dir%", so it will never work without some tweaking.  */
@@ -951,11 +901,11 @@ load_pdump (int argc, char **argv, char const *original_pwd)
      "emacs.pdmp" so that the Emacs binary still works if the user
      copies and renames it.  */
   const char *argv0_base = "emacs";
-  ptrdiff_t needed = (strlen (path_exec)
-                      + 1
-                      + strlen (argv0_base)
-                      + strlen (suffix)
-                      + 1);
+  needed = (strlen (path_exec)
+           + 1
+           + strlen (argv0_base)
+           + strlen (suffix)
+           + 1);
   if (bufsize < needed)
     {
       xfree (dump_file);
@@ -963,7 +913,19 @@ load_pdump (int argc, char **argv, char const *original_pwd)
     }
   sprintf (dump_file, "%s%c%s%s",
            path_exec, DIRECTORY_SEP, argv0_base, suffix);
-  result = pdumper_load (dump_file, argv[0], original_pwd);
+  /* Assume the Emacs binary lives in a sibling directory as set up by
+     the default installation configuration.  */
+  const char *go_up = "../../../../bin/";
+  needed += strlen (strip_suffix) - strlen (suffix) + strlen (go_up);
+  if (exec_bufsize < needed)
+    {
+      xfree (emacs_executable);
+      emacs_executable = xpalloc (NULL, &exec_bufsize, needed - exec_bufsize,
+                                 -1, 1);
+    }
+  sprintf (emacs_executable, "%s%c%s%s%s",
+          path_exec, DIRECTORY_SEP, go_up, argv0_base, strip_suffix);
+  result = pdumper_load (dump_file, emacs_executable);
 
   if (result == PDUMPER_LOAD_FILE_NOT_FOUND)
     {
@@ -998,7 +960,7 @@ load_pdump (int argc, char **argv, char const *original_pwd)
 #endif
       sprintf (dump_file, "%s%c%s%s",
               path_exec, DIRECTORY_SEP, argv0_base, suffix);
-      result = pdumper_load (dump_file, argv[0], original_pwd);
+      result = pdumper_load (dump_file, emacs_executable);
     }
 
   if (result != PDUMPER_LOAD_SUCCESS)
@@ -1010,6 +972,7 @@ load_pdump (int argc, char **argv, char const *original_pwd)
 
  out:
   xfree (dump_file);
+  xfree (emacs_executable);
 }
 #endif /* HAVE_PDUMPER */
 
@@ -1320,10 +1283,9 @@ main (int argc, char **argv)
   w32_init_main_thread ();
 #endif
 
-  emacs_wd = emacs_get_current_dir_name ();
 #ifdef HAVE_PDUMPER
   if (attempt_load_pdump)
-    load_pdump (argc, argv, emacs_wd);
+    load_pdump (argc, argv);
 #endif
 
   argc = maybe_disable_address_randomization (argc, argv);
@@ -1395,6 +1357,7 @@ main (int argc, char **argv)
       exit (0);
     }
 
+  emacs_wd = emacs_get_current_dir_name ();
 #ifdef HAVE_PDUMPER
   if (dumped_with_pdumper_p ())
     pdumper_record_wd (emacs_wd);
@@ -2038,8 +2001,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
   /* Init buffer storage and default directory of main buffer.  */
   init_buffer ();
 
-  init_vars_for_load (argv[0], original_pwd);
-
   /* Must precede init_lread.  */
   init_cmdargs (argc, argv, skip_args, original_pwd);
 
index 474e49c8e1eac249f2812c1e8a85f16ee6d44ad1..f83c55f827da3585a31e4baba39ae2dd9d4cc28b 100644 (file)
@@ -4450,7 +4450,6 @@ extern bool display_arg;
 extern Lisp_Object decode_env_path (const char *, const char *, bool);
 extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
 extern AVOID terminate_due_to_signal (int, int);
-extern void init_vars_for_load (char *, char const *);
 #ifdef WINDOWSNT
 extern Lisp_Object Vlibrary_cache;
 #endif
index dc893c59bfab3402236cb623653f782b226d089b..c9285ddbc78cf55569fce3853eb8981a8d423689 100644 (file)
@@ -4356,6 +4356,16 @@ pdumper_remember_lv_ptr_raw_impl (void *ptr, enum Lisp_Type type)
 }
 
 \f
+#ifdef HAVE_NATIVE_COMP
+/* This records the directory where the Emacs executable lives, to be
+   used for locating the native-lisp directory from which we need to
+   load the preloaded *.eln files.  See pdumper_set_emacs_execdir
+   below.  */
+static char *emacs_execdir;
+static ptrdiff_t execdir_size;
+static ptrdiff_t execdir_len;
+#endif
+
 /* Dump runtime */
 enum dump_memory_protection
 {
@@ -5269,35 +5279,54 @@ dump_do_dump_relocation (const uintptr_t dump_base,
        struct Lisp_Native_Comp_Unit *comp_u =
          dump_ptr (dump_base, reloc_offset);
        comp_u->lambda_gc_guard_h = CALLN (Fmake_hash_table, QCtest, Qeq);
-       if (!CONSP (comp_u->file))
+       if (STRINGP (comp_u->file))
          error ("Trying to load incoherent dumped eln file %s",
                 SSDATA (comp_u->file));
 
+       /* emacs_execdir is always unibyte, but the file names in
+          comp_u->file could be multibyte, so we need to encode
+          them.  */
+       Lisp_Object cu_file1 = ENCODE_FILE (XCAR (comp_u->file));
+       Lisp_Object cu_file2 = ENCODE_FILE (XCDR (comp_u->file));
+       ptrdiff_t fn1_len = SBYTES (cu_file1), fn2_len = SBYTES (cu_file2);
+       Lisp_Object eln_fname;
+       char *fndata;
+
        /* Check just once if this is a local build or Emacs was installed.  */
+       /* Can't use expand-file-name here, because we are too early
+          in the startup, and we will crash at least on WINDOWSNT.  */
        if (installation_state == UNKNOWN)
          {
-           /* Can't use expand-file-name here, because we are too
-              early in the startup, and we will crash at least on
-              WINDOWSNT.  */
-           Lisp_Object fname =
-             concat2 (Vinvocation_directory, XCAR (comp_u->file));
-           if (file_access_p (SSDATA (ENCODE_FILE (fname)), F_OK))
-             {
-               installation_state = INSTALLED;
-               fixup_eln_load_path (XCAR (comp_u->file));
-             }
+           eln_fname = make_uninit_string (execdir_len + fn1_len);
+           fndata = SSDATA (eln_fname);
+           memcpy (fndata, emacs_execdir, execdir_len);
+           memcpy (fndata + execdir_len, SSDATA (cu_file1), fn1_len);
+           if (file_access_p (fndata, F_OK))
+             installation_state = INSTALLED;
            else
              {
+               eln_fname = make_uninit_string (execdir_len + fn2_len);
+               fndata = SSDATA (eln_fname);
+               memcpy (fndata, emacs_execdir, execdir_len);
+               memcpy (fndata + execdir_len, SSDATA (cu_file2), fn2_len);
                installation_state = LOCAL_BUILD;
-               fixup_eln_load_path (XCDR (comp_u->file));
              }
+           fixup_eln_load_path (eln_fname);
+         }
+       else
+         {
+           ptrdiff_t fn_len =
+             installation_state == INSTALLED ? fn1_len : fn2_len;
+           Lisp_Object cu_file =
+             installation_state == INSTALLED ? cu_file1 : cu_file2;
+           eln_fname = make_uninit_string (execdir_len + fn_len);
+           fndata = SSDATA (eln_fname);
+           memcpy (fndata, emacs_execdir, execdir_len);
+           memcpy (fndata + execdir_len, SSDATA (cu_file), fn_len);
          }
 
-       comp_u->file =
-         concat2 (Vinvocation_directory,
-                  installation_state == INSTALLED
-                  ? XCAR (comp_u->file) : XCDR (comp_u->file));
-       comp_u->handle = dynlib_open (SSDATA (ENCODE_FILE (comp_u->file)));
+       comp_u->file = eln_fname;
+       comp_u->handle = dynlib_open (SSDATA (eln_fname));
        if (!comp_u->handle)
          error ("%s", dynlib_error ());
        load_comp_unit (comp_u, true, false);
@@ -5435,6 +5464,26 @@ dump_do_all_emacs_relocations (const struct dump_header *const header,
     dump_do_emacs_relocation (dump_base, r[i]);
 }
 
+#ifdef HAVE_NATIVE_COMP
+/* Compute and record the directory of the Emacs executable given the
+   file name of that executable.  */
+static void
+pdumper_set_emacs_execdir (char *emacs_executable)
+{
+  char *p = emacs_executable + strlen (emacs_executable);
+
+  while (p > emacs_executable
+        && !IS_DIRECTORY_SEP (p[-1]))
+    --p;
+  eassert (p > emacs_executable);
+  emacs_execdir = xpalloc (emacs_execdir, &execdir_size,
+                          p - emacs_executable + 1 - execdir_size, -1, 1);
+  memcpy (emacs_execdir, emacs_executable, p - emacs_executable);
+  execdir_len = p - emacs_executable;
+  emacs_execdir[execdir_len] = '\0';
+}
+#endif
+
 enum dump_section
   {
    DS_HOT,
@@ -5451,7 +5500,7 @@ static Lisp_Object *pdumper_hashes = &zero_vector;
    N.B. We run very early in initialization, so we can't use lisp,
    unwinding, xmalloc, and so on.  */
 int
-pdumper_load (const char *dump_filename, char *argv0, char const *original_pwd)
+pdumper_load (const char *dump_filename, char *argv0)
 {
   intptr_t dump_size;
   struct stat stat;
@@ -5607,9 +5656,11 @@ pdumper_load (const char *dump_filename, char *argv0, char const *original_pwd)
   for (int i = 0; i < nr_dump_hooks; ++i)
     dump_hooks[i] ();
 
-  /* Once we can allocate and before loading .eln files we must set
-     Vinvocation_directory (.eln paths are relative to it). */
-  init_vars_for_load (argv0, original_pwd);
+#ifdef HAVE_NATIVE_COMP
+  pdumper_set_emacs_execdir (argv0);
+#else
+  (void) argv0;
+#endif
 
   dump_do_all_dump_reloc_for_phase (header, dump_base, LATE_RELOCS);
   dump_do_all_dump_reloc_for_phase (header, dump_base, VERY_LATE_RELOCS);
index 49e6739b0dced0a576dfb59398b3223a6b7ace24..deec9af046d9970a72f345c0e8920255d13855db 100644 (file)
@@ -140,8 +140,7 @@ enum pdumper_load_result
     PDUMPER_LOAD_ERROR /* Must be last, as errno may be added.  */
   };
 
-int pdumper_load (const char *dump_filename, char *argv0,
-                 char const *original_pwd);
+int pdumper_load (const char *dump_filename, char *argv0);
 
 struct pdumper_loaded_dump
 {