diff options
| -rw-r--r-- | doc/lispref/internals.texi | 34 | ||||
| -rw-r--r-- | etc/NEWS | 14 | ||||
| -rw-r--r-- | etc/TODO | 6 | ||||
| -rw-r--r-- | lib/fingerprint.h | 3 | ||||
| -rw-r--r-- | lisp/startup.el | 4 | ||||
| -rw-r--r-- | src/alloc.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 6 | ||||
| -rw-r--r-- | src/minibuf.c | 2 | ||||
| -rw-r--r-- | src/pdumper.c | 10 | ||||
| -rw-r--r-- | src/pdumper.h | 4 | ||||
| -rw-r--r-- | src/unexaix.c | 2 |
11 files changed, 47 insertions, 42 deletions
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 72066d34f44..f85c266edef 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi | |||
| @@ -61,10 +61,10 @@ can be one of the following: | |||
| 61 | 61 | ||
| 62 | @table @samp | 62 | @table @samp |
| 63 | @item pdump | 63 | @item pdump |
| 64 | @cindex portable dump file | 64 | @cindex dump file |
| 65 | Record the preloaded Lisp data in a @dfn{portable dump} file. This | 65 | Record the preloaded Lisp data in a @dfn{dump file}. This |
| 66 | method produces an additional data file which Emacs will load at | 66 | method produces an additional data file which Emacs will load at |
| 67 | startup. The portable dump file is usually called @file{emacs.pdmp}, | 67 | startup. The produced dump file is usually called @file{emacs.pdmp}, |
| 68 | and is installed in the Emacs @code{exec-directory} (@pxref{Help | 68 | and is installed in the Emacs @code{exec-directory} (@pxref{Help |
| 69 | Functions}). This method is the most preferred one, as it does not | 69 | Functions}). This method is the most preferred one, as it does not |
| 70 | require Emacs to employ any special techniques of memory allocation, | 70 | require Emacs to employ any special techniques of memory allocation, |
| @@ -75,7 +75,7 @@ modern systems to enhance security and privacy. | |||
| 75 | @cindex bootstrapping Emacs | 75 | @cindex bootstrapping Emacs |
| 76 | Like @samp{pdump}, but used while @dfn{bootstrapping} Emacs, when no | 76 | Like @samp{pdump}, but used while @dfn{bootstrapping} Emacs, when no |
| 77 | previous Emacs binary and no @file{*.elc} byte-compiled Lisp files are | 77 | previous Emacs binary and no @file{*.elc} byte-compiled Lisp files are |
| 78 | available. The produced portable dump file is usually named | 78 | available. The produced dump file is usually named |
| 79 | @file{bootstrap-emacs.pdmp} in this case. | 79 | @file{bootstrap-emacs.pdmp} in this case. |
| 80 | 80 | ||
| 81 | @item dump | 81 | @item dump |
| @@ -88,6 +88,8 @@ terminal, so that the tables of terminal information are empty in the | |||
| 88 | dumped Emacs.) This method is also known as @dfn{unexec}, because it | 88 | dumped Emacs.) This method is also known as @dfn{unexec}, because it |
| 89 | produces a program file from a running process, and thus is in some | 89 | produces a program file from a running process, and thus is in some |
| 90 | sense the opposite of executing a program to start a process. | 90 | sense the opposite of executing a program to start a process. |
| 91 | Although this method was the way that Emacs traditionally saved its | ||
| 92 | state, it is now deprecated. | ||
| 91 | 93 | ||
| 92 | @item bootstrap | 94 | @item bootstrap |
| 93 | Like @samp{dump}, but used when bootstrapping Emacs with the | 95 | Like @samp{dump}, but used when bootstrapping Emacs with the |
| @@ -97,11 +99,11 @@ Like @samp{dump}, but used when bootstrapping Emacs with the | |||
| 97 | @cindex preloaded Lisp files | 99 | @cindex preloaded Lisp files |
| 98 | @vindex preloaded-file-list | 100 | @vindex preloaded-file-list |
| 99 | The dumped @file{emacs} executable (also called a @dfn{pure} Emacs) | 101 | The dumped @file{emacs} executable (also called a @dfn{pure} Emacs) |
| 100 | is the one which is installed. If the portable dumping was used to | 102 | is the one which is installed. If the portable dumper was used to |
| 101 | build Emacs, the @file{emacs} executable is actually an exact copy of | 103 | build Emacs, the @file{emacs} executable is actually an exact copy of |
| 102 | @file{temacs}, and the corresponding @file{emacs.pdmp} file is | 104 | @file{temacs}, and the corresponding @file{emacs.pdmp} file is |
| 103 | installed as well. The variable @code{preloaded-file-list} stores a | 105 | installed as well. The variable @code{preloaded-file-list} stores a |
| 104 | list of the preloaded Lisp files recorded in the portable dump file or | 106 | list of the preloaded Lisp files recorded in the dump file or |
| 105 | in the dumped Emacs executable. If you port Emacs to a new operating | 107 | in the dumped Emacs executable. If you port Emacs to a new operating |
| 106 | system, and are not able to implement dumping of any kind, then Emacs | 108 | system, and are not able to implement dumping of any kind, then Emacs |
| 107 | must load @file{loadup.el} each time it starts. | 109 | must load @file{loadup.el} each time it starts. |
| @@ -201,15 +203,19 @@ In the unlikely event that you need a more general functionality than | |||
| 201 | @code{before-init-hook} (@pxref{Startup Summary}). | 203 | @code{before-init-hook} (@pxref{Startup Summary}). |
| 202 | 204 | ||
| 203 | @defun dump-emacs-portable to-file &optional track-referrers | 205 | @defun dump-emacs-portable to-file &optional track-referrers |
| 204 | This function dumps the current state of Emacs into a portable dump | 206 | This function dumps the current state of Emacs into a dump |
| 205 | file @var{to-file}, using the @code{pdump} method. Normally, the | 207 | file @var{to-file}, using the @code{pdump} method. Normally, the |
| 206 | portable dump file is called @file{@var{emacs-name}.dmp}, where | 208 | dump file is called @file{@var{emacs-name}.dmp}, where |
| 207 | @var{emacs-name} is the name of the Emacs executable file. The | 209 | @var{emacs-name} is the name of the Emacs executable file. The |
| 208 | optional argument @var{track-referrers}, if non-@code{nil}, causes the | 210 | optional argument @var{track-referrers}, if non-@code{nil}, causes the |
| 209 | portable dumping process keep additional information to help track | 211 | portable dumper to keep additional information to help track |
| 210 | down the provenance of object types that are not yet supported by the | 212 | down the provenance of object types that are not yet supported by the |
| 211 | @code{pdump} method. | 213 | @code{pdump} method. |
| 212 | 214 | ||
| 215 | Although the portable dumper code can run on many platforms, the dump | ||
| 216 | files that it produces are not portable---they can be loaded only by | ||
| 217 | the Emacs executable that dumped them. | ||
| 218 | |||
| 213 | If you want to use this function in an Emacs that was already dumped, | 219 | If you want to use this function in an Emacs that was already dumped, |
| 214 | you must run Emacs with the @samp{-batch} option. | 220 | you must run Emacs with the @samp{-batch} option. |
| 215 | @end defun | 221 | @end defun |
| @@ -220,20 +226,20 @@ This function dumps the current state of Emacs into an executable file | |||
| 220 | @var{to-file}, using the @code{unexec} method. It takes symbols from | 226 | @var{to-file}, using the @code{unexec} method. It takes symbols from |
| 221 | @var{from-file} (this is normally the executable file @file{temacs}). | 227 | @var{from-file} (this is normally the executable file @file{temacs}). |
| 222 | 228 | ||
| 223 | This function cannot be used in an Emacs that was already dumped. If | 229 | This function cannot be used in an Emacs that was already dumped. |
| 224 | Emacs was built without @code{unexec} support, this function will not | 230 | This function is deprecated, and by default Emacs is built without |
| 225 | be available. | 231 | @code{unexec} support so this function is not available. |
| 226 | @end defun | 232 | @end defun |
| 227 | 233 | ||
| 228 | @defun pdumper-stats | 234 | @defun pdumper-stats |
| 229 | If the current Emacs session restored its state from a portable dump | 235 | If the current Emacs session restored its state from a dump |
| 230 | file, this function returns information about the dump file and the | 236 | file, this function returns information about the dump file and the |
| 231 | time it took to restore the Emacs state. The value is an alist | 237 | time it took to restore the Emacs state. The value is an alist |
| 232 | @w{@code{((dumped-with-pdumper . t) (load-time . @var{time}) | 238 | @w{@code{((dumped-with-pdumper . t) (load-time . @var{time}) |
| 233 | (dump-file-name . @var{file}))}}, | 239 | (dump-file-name . @var{file}))}}, |
| 234 | where @var{file} is the name of the dump file, and @var{time} is the | 240 | where @var{file} is the name of the dump file, and @var{time} is the |
| 235 | time in seconds it took to restore the state from the dump file. | 241 | time in seconds it took to restore the state from the dump file. |
| 236 | If the current session was not restored from a portable dump file, the | 242 | If the current session was not restored from a dump file, the |
| 237 | value is nil. | 243 | value is nil. |
| 238 | @end defun | 244 | @end defun |
| 239 | 245 | ||
| @@ -92,11 +92,6 @@ and in particular better supports the Address Space Layout | |||
| 92 | Randomization (ASLR) feature, a security technique used by most modern | 92 | Randomization (ASLR) feature, a security technique used by most modern |
| 93 | operating systems. | 93 | operating systems. |
| 94 | 94 | ||
| 95 | Portable dumping can be disabled at configure time via the configure | ||
| 96 | option '--with-dumping=unexec' (but we don't recommend that, unless | ||
| 97 | the portable dumping doesn't work on your system for some | ||
| 98 | reason---please report such systems to the Emacs developers as bugs). | ||
| 99 | |||
| 100 | When built with the portable dumping support (which is the default), | 95 | When built with the portable dumping support (which is the default), |
| 101 | Emacs looks for the 'emacs.pdmp' file, generated during the build, in | 96 | Emacs looks for the 'emacs.pdmp' file, generated during the build, in |
| 102 | its data directory at startup, and loads the dumped state from there. | 97 | its data directory at startup, and loads the dumped state from there. |
| @@ -104,6 +99,15 @@ The new command-line argument '--dump-file=FILE' allows to specify a | |||
| 104 | non-default '.pdmp' file to load the state from; see the node "Initial | 99 | non-default '.pdmp' file to load the state from; see the node "Initial |
| 105 | Options" in the Emacs manual for more information. | 100 | Options" in the Emacs manual for more information. |
| 106 | 101 | ||
| 102 | An Emacs started via a dump file can create a new dump file only if it | ||
| 103 | was invoked with the -batch option. | ||
| 104 | |||
| 105 | Although the portable dumper has been tested, it may have a bug on | ||
| 106 | unusual platforms. If you require traditional unexec dumping you can | ||
| 107 | use the configure-time option '--with-dumping=unexec'; however, please | ||
| 108 | file a bug report describing the situation, as unexec dumping is | ||
| 109 | deprecated. | ||
| 110 | |||
| 107 | +++ | 111 | +++ |
| 108 | ** The new configure option '--enable-checking=structs' attempts to | 112 | ** The new configure option '--enable-checking=structs' attempts to |
| 109 | check that the portable dumper code has been updated to match the last | 113 | check that the portable dumper code has been updated to match the last |
| @@ -297,11 +297,7 @@ One way of doing this is to start with fx's dynamic loading, and use it | |||
| 297 | to implement things like auto-loaded buffer parsers and database | 297 | to implement things like auto-loaded buffer parsers and database |
| 298 | access in cases which need more than Lisp. | 298 | access in cases which need more than Lisp. |
| 299 | 299 | ||
| 300 | ** Replace unexec with a more portable form of dumping | 300 | ** Fix portable dumping so that you can redump without using -batch. |
| 301 | See eg https://lists.gnu.org/r/emacs-devel/2014-01/msg01034.html | ||
| 302 | https://lists.gnu.org/r/emacs-devel/2014-06/msg00452.html | ||
| 303 | |||
| 304 | One way is to provide portable undumping using mmap (per gerd design). | ||
| 305 | 301 | ||
| 306 | ** Imenu could be extended into a file-structure browsing mechanism | 302 | ** Imenu could be extended into a file-structure browsing mechanism |
| 307 | using code like that of customize-groups. | 303 | using code like that of customize-groups. |
diff --git a/lib/fingerprint.h b/lib/fingerprint.h index ba2e740cd9e..7d2160c9882 100644 --- a/lib/fingerprint.h +++ b/lib/fingerprint.h | |||
| @@ -22,8 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 22 | 22 | ||
| 23 | /* We generate fingerprint.c and fingerprint.o from all the sources in | 23 | /* We generate fingerprint.c and fingerprint.o from all the sources in |
| 24 | Emacs. This way, we have a unique value that we can use to pair | 24 | Emacs. This way, we have a unique value that we can use to pair |
| 25 | data files (like a portable dump image) with a specific build of | 25 | data files (like a dump file) with a specific build of Emacs. */ |
| 26 | Emacs. */ | ||
| 27 | extern volatile unsigned char fingerprint[32]; | 26 | extern volatile unsigned char fingerprint[32]; |
| 28 | 27 | ||
| 29 | #endif | 28 | #endif |
diff --git a/lisp/startup.el b/lisp/startup.el index 7759ed5aed3..564428580b1 100644 --- a/lisp/startup.el +++ b/lisp/startup.el | |||
| @@ -354,8 +354,8 @@ Setting `init-file-user' does not prevent Emacs from loading | |||
| 354 | "File containing site-wide run-time initializations. | 354 | "File containing site-wide run-time initializations. |
| 355 | This file is loaded at run-time before `~/.emacs'. It contains inits | 355 | This file is loaded at run-time before `~/.emacs'. It contains inits |
| 356 | that need to be in place for the entire site, but which, due to their | 356 | that need to be in place for the entire site, but which, due to their |
| 357 | higher incidence of change, don't make sense to load into Emacs's | 357 | higher incidence of change, don't make sense to put into Emacs's |
| 358 | dumped image. Thus, the run-time load order is: 1. file described in | 358 | dump file. Thus, the run-time load order is: 1. file described in |
| 359 | this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'. | 359 | this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'. |
| 360 | 360 | ||
| 361 | Don't use the `site-start.el' file for things some users may not like. | 361 | Don't use the `site-start.el' file for things some users may not like. |
diff --git a/src/alloc.c b/src/alloc.c index 5d8003ffb5c..f256ff71b07 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4531,9 +4531,9 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4531 | 4531 | ||
| 4532 | void *po = XPNTR (obj); | 4532 | void *po = XPNTR (obj); |
| 4533 | 4533 | ||
| 4534 | /* If the pointer is in the dumped image and the dump has a record | 4534 | /* If the pointer is in the dump image and the dump has a record |
| 4535 | of the object starting at the place where the pointer points, we | 4535 | of the object starting at the place where the pointer points, we |
| 4536 | definitely have an object. If the pointer is in the dumped image | 4536 | definitely have an object. If the pointer is in the dump image |
| 4537 | and the dump has no idea what the pointer is pointing at, we | 4537 | and the dump has no idea what the pointer is pointing at, we |
| 4538 | definitely _don't_ have an object. */ | 4538 | definitely _don't_ have an object. */ |
| 4539 | if (pdumper_object_p (po)) | 4539 | if (pdumper_object_p (po)) |
diff --git a/src/emacs.c b/src/emacs.c index ad661a081b5..cc5818393a3 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -686,7 +686,7 @@ dump_error_to_string (enum pdumper_load_result result) | |||
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | /* Find a path (absolute or relative) to the Emacs executable. | 688 | /* Find a path (absolute or relative) to the Emacs executable. |
| 689 | Called early in initialization by portable dump loading code, so we | 689 | Called early in initialization by portable dumper loading code, so we |
| 690 | can't use lisp and associated machinery. On success, *EXENAME is | 690 | can't use lisp and associated machinery. On success, *EXENAME is |
| 691 | set to a heap-allocated string giving a path to the Emacs | 691 | set to a heap-allocated string giving a path to the Emacs |
| 692 | executable or to NULL if we can't determine the path immediately. | 692 | executable or to NULL if we can't determine the path immediately. |
| @@ -801,12 +801,12 @@ load_pdump (int argc, char **argv) | |||
| 801 | ; | 801 | ; |
| 802 | 802 | ||
| 803 | /* TODO: maybe more thoroughly scrub process environment in order to | 803 | /* TODO: maybe more thoroughly scrub process environment in order to |
| 804 | make this use case (loading a pdumper image in an unexeced emacs) | 804 | make this use case (loading a dump file in an unexeced emacs) |
| 805 | possible? Right now, we assume that things we don't touch are | 805 | possible? Right now, we assume that things we don't touch are |
| 806 | zero-initialized, and in an unexeced Emacs, this assumption | 806 | zero-initialized, and in an unexeced Emacs, this assumption |
| 807 | doesn't hold. */ | 807 | doesn't hold. */ |
| 808 | if (initialized) | 808 | if (initialized) |
| 809 | fatal ("cannot load pdumper image in unexeced Emacs"); | 809 | fatal ("cannot load dump file in unexeced Emacs"); |
| 810 | 810 | ||
| 811 | /* Look for an explicitly-specified dump file. */ | 811 | /* Look for an explicitly-specified dump file. */ |
| 812 | const char *path_exec = PATH_EXEC; | 812 | const char *path_exec = PATH_EXEC; |
diff --git a/src/minibuf.c b/src/minibuf.c index d9a6e15b05d..8920f37827d 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1885,7 +1885,7 @@ init_minibuf_once_for_pdumper (void) | |||
| 1885 | PDUMPER_IGNORE (minibuf_prompt_width); | 1885 | PDUMPER_IGNORE (minibuf_prompt_width); |
| 1886 | 1886 | ||
| 1887 | /* We run this function on first initialization and whenever we | 1887 | /* We run this function on first initialization and whenever we |
| 1888 | restore from a pdumper image. pdumper doesn't try to preserve | 1888 | restore from a dump file. pdumper doesn't try to preserve |
| 1889 | frames, windows, and so on, so reset everything related here. */ | 1889 | frames, windows, and so on, so reset everything related here. */ |
| 1890 | Vminibuffer_list = Qnil; | 1890 | Vminibuffer_list = Qnil; |
| 1891 | minibuf_level = 0; | 1891 | minibuf_level = 0; |
diff --git a/src/pdumper.c b/src/pdumper.c index cda8b40be4c..84147353e85 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -333,8 +333,8 @@ dump_fingerprint (char const *label, | |||
| 333 | fprintf (stderr, "%s: %.*s\n", label, hexbuf_size, hexbuf); | 333 | fprintf (stderr, "%s: %.*s\n", label, hexbuf_size, hexbuf); |
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | /* Format of an Emacs portable dump file. All offsets are relative to | 336 | /* Format of an Emacs dump file. All offsets are relative to |
| 337 | the beginning of the file. An Emacs portable dump file is coupled | 337 | the beginning of the file. An Emacs dump file is coupled |
| 338 | to exactly the Emacs binary that produced it, so details of | 338 | to exactly the Emacs binary that produced it, so details of |
| 339 | alignment and endianness are unimportant. | 339 | alignment and endianness are unimportant. |
| 340 | 340 | ||
| @@ -3990,7 +3990,7 @@ dump_drain_deferred_symbols (struct dump_context *ctx) | |||
| 3990 | DEFUN ("dump-emacs-portable", | 3990 | DEFUN ("dump-emacs-portable", |
| 3991 | Fdump_emacs_portable, Sdump_emacs_portable, | 3991 | Fdump_emacs_portable, Sdump_emacs_portable, |
| 3992 | 1, 2, 0, | 3992 | 1, 2, 0, |
| 3993 | doc: /* Dump current state of Emacs into portable dump file FILENAME. | 3993 | doc: /* Dump current state of Emacs into dump file FILENAME. |
| 3994 | If TRACK-REFERRERS is non-nil, keep additional debugging information | 3994 | If TRACK-REFERRERS is non-nil, keep additional debugging information |
| 3995 | that can help track down the provenance of unsupported object | 3995 | that can help track down the provenance of unsupported object |
| 3996 | types. */) | 3996 | types. */) |
| @@ -5470,14 +5470,14 @@ pdumper_record_wd (const char *wd) | |||
| 5470 | 5470 | ||
| 5471 | DEFUN ("pdumper-stats", Fpdumper_stats, Spdumper_stats, 0, 0, 0, | 5471 | DEFUN ("pdumper-stats", Fpdumper_stats, Spdumper_stats, 0, 0, 0, |
| 5472 | doc: /* Return statistics about portable dumping used by this session. | 5472 | doc: /* Return statistics about portable dumping used by this session. |
| 5473 | If this Emacs sesion was started from a portable dump file, | 5473 | If this Emacs session was started from a dump file, |
| 5474 | the return value is an alist of the form: | 5474 | the return value is an alist of the form: |
| 5475 | 5475 | ||
| 5476 | ((dumped-with-pdumper . t) (load-time . TIME) (dump-file-name . FILE)) | 5476 | ((dumped-with-pdumper . t) (load-time . TIME) (dump-file-name . FILE)) |
| 5477 | 5477 | ||
| 5478 | where TIME is the time in seconds it took to restore Emacs state | 5478 | where TIME is the time in seconds it took to restore Emacs state |
| 5479 | from the dump file, and FILE is the name of the dump file. | 5479 | from the dump file, and FILE is the name of the dump file. |
| 5480 | Value is nil if this session was not started using a portable dump file.*/) | 5480 | Value is nil if this session was not started using a dump file.*/) |
| 5481 | (void) | 5481 | (void) |
| 5482 | { | 5482 | { |
| 5483 | if (!dumped_with_pdumper_p ()) | 5483 | if (!dumped_with_pdumper_p ()) |
diff --git a/src/pdumper.h b/src/pdumper.h index ab2f426c1e9..5d1e9c3aea3 100644 --- a/src/pdumper.h +++ b/src/pdumper.h | |||
| @@ -35,7 +35,7 @@ INLINE_HEADER_BEGIN | |||
| 35 | variables to which the Lisp heap points. It doesn't know anything | 35 | variables to which the Lisp heap points. It doesn't know anything |
| 36 | about other C variables. The functions below allow code from other | 36 | about other C variables. The functions below allow code from other |
| 37 | parts of Emacs to tell the portable dumper about other bits of | 37 | parts of Emacs to tell the portable dumper about other bits of |
| 38 | information to preserve in dumped images. | 38 | information to preserve in dump files. |
| 39 | 39 | ||
| 40 | These memory-records are themselves preserved in the dump, so call | 40 | These memory-records are themselves preserved in the dump, so call |
| 41 | the functions below only on the !initialized init path, just | 41 | the functions below only on the !initialized init path, just |
| @@ -44,7 +44,7 @@ INLINE_HEADER_BEGIN | |||
| 44 | There are no special functions to preserve a global Lisp_Object. | 44 | There are no special functions to preserve a global Lisp_Object. |
| 45 | You should just staticpro these. */ | 45 | You should just staticpro these. */ |
| 46 | 46 | ||
| 47 | /* Remember the value of THING in dumped images. THING must not | 47 | /* Remember the value of THING in dump files. THING must not |
| 48 | contain any pointers or Lisp_Object variables: these values are not | 48 | contain any pointers or Lisp_Object variables: these values are not |
| 49 | valid across dump and load. */ | 49 | valid across dump and load. */ |
| 50 | #define PDUMPER_REMEMBER_SCALAR(thing) \ | 50 | #define PDUMPER_REMEMBER_SCALAR(thing) \ |
diff --git a/src/unexaix.c b/src/unexaix.c index 349d3653830..c95486cf72a 100644 --- a/src/unexaix.c +++ b/src/unexaix.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Dump an executable image. | 1 | /* Dump an executable file. |
| 2 | Copyright (C) 1985-1988, 1999, 2001-2019 Free Software Foundation, | 2 | Copyright (C) 1985-1988, 1999, 2001-2019 Free Software Foundation, |
| 3 | Inc. | 3 | Inc. |
| 4 | 4 | ||