Skip to content

Commit a5f8ce9

Browse files
author
Po Lu
committedMar 9, 2025
Re-port to 32-bit systems without alignment primitives
* configure.ac (ALIGNOF_INT, ALIGNOF_LONG, ALIGNOF_LONG_LONG): New variables. (emacs_cv_alignas_unavailable): Define if alignas and structure alignment primitives are unavailable. In such an environment, the MSB tagging scheme must be enabled, as must the GNU malloc. * msdos/sed2v2.inp: Adjust correspondingly. * src/alloc.c (union emacs_align_type): Remove types which contain flexible array members. The address of a field subsequent to an aggregate with flexible array members cannot validly be taken. (mark_memory) [!USE_LSB_TAG && !WIDE_EMACS_INT]: Strip type bits before scanning memory. * src/emacs.c (main): * src/eval.c (Fautoload_do_load): * src/fns.c (Frequire): Rename a number of illogically named fields. * src/lisp.h (ALIGNOF_EMACS_INT): Define to the natural alignment of EMACS_INT. (IDEAL_GCALIGNMENT): New macro. (USE_LSB_TAG): Disable if no alignment specifiers are available, WIDE_EMACS_INT is undefined, and the natural alignment of EMACS_INT falls short of LSB tagging's requirements. (gflags): Rename illogically named fields and don't define them as bitfields, which runs afoul of certain compiler issues. (will_dump_p, will_bootstrap_p, will_dump_with_pdumper_p) (dumped_with_pdumper_p): Adjust accordingly. * src/pdumper.c (VM_SUPPORTED): Define to 0 when !USE_LSB_TAG. It is better to read dump files into the heap by hand than to be supplied with an address that is not representable. (_dump_object_start_pseudovector): Rename to dump_object_start_pseudovector, to avoid encroaching on reserved names. (START_DUMP_PVEC): Adjust correspondingly. (dump_mmap_contiguous_vm): Preserve errno around failure cleanup. (dump_bitset_bit_set_p): Work around certain compiler issues. (pdumper_load) [!USE_LSB_TAG]: Reject dump file allocations that are not representable as Lisp_Objects. Tested on i386-unknown-solaris2.10, sparc-sun-solaris2.10.
1 parent 57cef07 commit a5f8ce9

File tree

8 files changed

+193
-100
lines changed

8 files changed

+193
-100
lines changed
 

‎configure.ac

+60-17
Original file line numberDiff line numberDiff line change
@@ -3218,8 +3218,68 @@ AC_CACHE_CHECK(
32183218
fi])
32193219
doug_lea_malloc=$emacs_cv_var_doug_lea_malloc
32203220

3221+
AC_CHECK_ALIGNOF([int])
3222+
AC_CHECK_ALIGNOF([long])
3223+
AC_CHECK_ALIGNOF([long long])
3224+
AC_CHECK_SIZEOF([long])
3225+
3226+
AC_CACHE_CHECK([for struct alignment],
3227+
[emacs_cv_struct_alignment],
3228+
[AC_COMPILE_IFELSE(
3229+
[AC_LANG_PROGRAM([[#include <stddef.h>
3230+
struct s { char c; } __attribute__ ((aligned (8)));
3231+
struct t { char c; struct s s; };
3232+
char verify[offsetof (struct t, s) == 8 ? 1 : -1];
3233+
]])],
3234+
[emacs_cv_struct_alignment=yes],
3235+
[emacs_cv_struct_alignment=no])])
3236+
if test "$emacs_cv_struct_alignment" = yes; then
3237+
AC_DEFINE([HAVE_STRUCT_ATTRIBUTE_ALIGNED], [1],
3238+
[Define to 1 if 'struct __attribute__ ((aligned (N)))' aligns the
3239+
structure to an N-byte boundary.])
3240+
fi
3241+
32213242
system_malloc=yes
32223243

3244+
# If it appears as if the system malloc can't be trusted to return
3245+
# adequately positioned memory, enable the GNU malloc, which more
3246+
# consistently provides allocations at low addresses, as is required for
3247+
# the pdumper to load dump files at a representable location.
3248+
AS_IF([test "$with_pdumper" = "yes" && test "$with_wide_int" != "yes"],
3249+
AC_CHECK_HEADERS([stdalign.h])
3250+
[AC_CACHE_CHECK([whether alignas is required yet unavailable],
3251+
[emacs_cv_alignas_unavailable],
3252+
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
3253+
#ifdef HAVE_STDALIGN_H
3254+
#include <stdalign.h>
3255+
#endif
3256+
#include <limits.h>
3257+
]], [[
3258+
#define IDEAL_GCALIGNMENT 8
3259+
#if INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT
3260+
# define ALIGNOF_EMACS_INT ALIGNOF_INT
3261+
# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
3262+
# define ALIGNOF_EMACS_INT ALIGNOF_LONG
3263+
# elif INTPTR_MAX <= LLONG_MAX
3264+
# define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG
3265+
# else
3266+
# error "INTPTR_MAX too large"
3267+
#endif
3268+
3269+
#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \
3270+
&& !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED \
3271+
&& !defined __alignas_is_defined \
3272+
&& __STDC_VERSION__ < 202311 && __cplusplus < 201103)
3273+
#error "!USE_LSB_TAG required"
3274+
#endif
3275+
]])], [emacs_cv_alignas_unavailable=no],
3276+
[emacs_cv_alignas_unavailable=yes])])
3277+
AS_IF([test "$emacs_cv_alignas_unavailable" = "yes"],
3278+
[system_malloc=no
3279+
AC_MSG_WARN([The GNU memory manager will be enabled as your system
3280+
does not guarantee that the portable dumper can allocate memory at a suitably
3281+
low address.])])])
3282+
32233283
dnl This must be before the test of $ac_cv_func_sbrk below.
32243284
AC_CHECK_FUNCS_ONCE([sbrk])
32253285

@@ -5823,7 +5883,6 @@ AC_SUBST([HAVE_LIBSECCOMP])
58235883
AC_SUBST([LIBSECCOMP_LIBS])
58245884
AC_SUBST([LIBSECCOMP_CFLAGS])
58255885

5826-
AC_CHECK_SIZEOF([long])
58275886
SIZEOF_LONG="$ac_cv_sizeof_long"
58285887
AC_SUBST([SIZEOF_LONG])
58295888

@@ -7186,22 +7245,6 @@ else
71867245
fi
71877246
AC_SUBST([LIBXMENU])
71887247

7189-
AC_CACHE_CHECK([for struct alignment],
7190-
[emacs_cv_struct_alignment],
7191-
[AC_COMPILE_IFELSE(
7192-
[AC_LANG_PROGRAM([[#include <stddef.h>
7193-
struct s { char c; } __attribute__ ((aligned (8)));
7194-
struct t { char c; struct s s; };
7195-
char verify[offsetof (struct t, s) == 8 ? 1 : -1];
7196-
]])],
7197-
[emacs_cv_struct_alignment=yes],
7198-
[emacs_cv_struct_alignment=no])])
7199-
if test "$emacs_cv_struct_alignment" = yes; then
7200-
AC_DEFINE([HAVE_STRUCT_ATTRIBUTE_ALIGNED], [1],
7201-
[Define to 1 if 'struct __attribute__ ((aligned (N)))' aligns the
7202-
structure to an N-byte boundary.])
7203-
fi
7204-
72057248
AC_C_RESTRICT
72067249
AC_C_TYPEOF
72077250

‎msdos/sed2v2.inp

+3
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ s/^#undef HAVE_DECL_STRTOIMAX *$/#define HAVE_DECL_STRTOIMAX 1/
140140
s/^#undef HAVE_PDUMPER *$/#define HAVE_PDUMPER 1/
141141
s/^#undef HAVE_STRTOLL *$/#define HAVE_STRTOLL 1/
142142
s/^#undef HAVE_STRTOULL *$/#define HAVE_STRTOULL 1/
143+
s/^#undef ALIGNOF_INT *$/s/^.*$/#define ALIGNOF_INT 4/
144+
s/^#undef ALIGNOF_LONG *$/s/^.*$/#define ALIGNOF_LONG 4/
145+
s/^#undef ALIGNOF_LONG_LONG *$/s/^.*$/#define ALIGNOF_LONG_LONG 4/
143146
/^#undef HAVE_STRUCT_DIRENT_D_TYPE *$/c\
144147
#if __DJGPP__ + (__DJGPP_MINOR__ >= 5) >= 3\
145148
#define HAVE_STRUCT_DIRENT_D_TYPE 1/\

‎src/alloc.c

+15-7
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ union emacs_align_type
150150
{
151151
struct frame frame;
152152
struct Lisp_Bignum Lisp_Bignum;
153-
struct Lisp_Bool_Vector Lisp_Bool_Vector;
154-
struct Lisp_Char_Table Lisp_Char_Table;
155153
struct Lisp_CondVar Lisp_CondVar;
156154
struct Lisp_Finalizer Lisp_Finalizer;
157155
struct Lisp_Float Lisp_Float;
@@ -160,21 +158,25 @@ union emacs_align_type
160158
struct Lisp_Misc_Ptr Lisp_Misc_Ptr;
161159
struct Lisp_Mutex Lisp_Mutex;
162160
struct Lisp_Overlay Lisp_Overlay;
163-
struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table;
164161
struct Lisp_Subr Lisp_Subr;
165162
struct Lisp_Sqlite Lisp_Sqlite;
166163
struct Lisp_User_Ptr Lisp_User_Ptr;
167-
struct Lisp_Vector Lisp_Vector;
168164
struct terminal terminal;
169165
struct thread_state thread_state;
170166
struct window window;
171167

172168
/* Omit the following since they would require including process.h
173-
etc. In practice their alignments never exceed that of the
174-
structs already listed. */
169+
etc, or because they are defined with flexible array members, which
170+
are rejected by some C99 compilers when this union subsequently
171+
appears in an `alignof' expression. In practice their alignments
172+
never exceed that of the structs already listed. */
175173
#if 0
174+
struct Lisp_Bool_Vector Lisp_Bool_Vector;
175+
struct Lisp_Char_Table Lisp_Char_Table;
176+
struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table;
176177
struct Lisp_Module_Function Lisp_Module_Function;
177178
struct Lisp_Process Lisp_Process;
179+
struct Lisp_Vector Lisp_Vector;
178180
struct save_window_data save_window_data;
179181
struct scroll_bar scroll_bar;
180182
struct xwidget_view xwidget_view;
@@ -5167,14 +5169,20 @@ mark_memory (void const *start, void const *end)
51675169
for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT)
51685170
{
51695171
void *p = *(void *const *) pp;
5172+
intptr_t ip;
5173+
5174+
#if !USE_LSB_TAG && !defined WIDE_EMACS_INT
5175+
ip = (intptr_t) p;
5176+
mark_maybe_pointer ((void *) (ip & VALMASK), false);
5177+
#else /* USE_LSB_TAG || WIDE_EMACS_INT */
51705178
mark_maybe_pointer (p, false);
5179+
#endif /* USE_LSB_TAG || WIDE_EMACS_INT */
51715180

51725181
/* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol
51735182
previously disguised by adding the address of 'lispsym'.
51745183
On a host with 32-bit pointers and 64-bit Lisp_Objects,
51755184
a Lisp_Object might be split into registers saved into
51765185
non-adjacent words and P might be the low-order word's value. */
5177-
intptr_t ip;
51785186
ckd_add (&ip, (intptr_t) p, (intptr_t) lispsym);
51795187
mark_maybe_pointer ((void *) ip, true);
51805188
}

‎src/emacs.c

+5-7
Original file line numberDiff line numberDiff line change
@@ -1311,13 +1311,11 @@ android_emacs_init (int argc, char **argv, char *dump_file)
13111311
if (!initialized && temacs)
13121312
{
13131313
#ifdef HAVE_PDUMPER
1314-
if (strcmp (temacs, "pdump") == 0 ||
1315-
strcmp (temacs, "pbootstrap") == 0)
1316-
gflags.will_dump_with_pdumper_ = true;
1317-
if (strcmp (temacs, "pbootstrap") == 0)
1318-
gflags.will_bootstrap_ = true;
1319-
gflags.will_dump_ =
1320-
will_dump_with_pdumper_p ();
1314+
if (!strcmp (temacs, "pdump") || !strcmp (temacs, "pbootstrap"))
1315+
gflags.will_dump_with_pdumper = true;
1316+
if (!strcmp (temacs, "pbootstrap"))
1317+
gflags.will_bootstrap = true;
1318+
gflags.will_dump = will_dump_with_pdumper_p ();
13211319
if (will_dump_p ())
13221320
dump_mode = temacs;
13231321
#endif

‎src/eval.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2389,7 +2389,7 @@ it defines a macro. */)
23892389
{
23902390
/* Avoid landing here recursively while outputting the
23912391
backtrace from the error. */
2392-
gflags.will_dump_ = false;
2392+
gflags.will_dump = false;
23932393
error ("Attempt to autoload %s while preparing to dump",
23942394
SDATA (SYMBOL_NAME (funname)));
23952395
}

‎src/fns.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3780,7 +3780,7 @@ FILENAME are suppressed. */)
37803780
{
37813781
/* Avoid landing here recursively while outputting the
37823782
backtrace from the error. */
3783-
gflags.will_dump_ = false;
3783+
gflags.will_dump = false;
37843784
error ("(require %s) while preparing to dump",
37853785
SDATA (SYMBOL_NAME (feature)));
37863786
}

‎src/lisp.h

+25-9
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,21 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
8989
typedef int EMACS_INT;
9090
typedef unsigned int EMACS_UINT;
9191
enum { EMACS_INT_WIDTH = INT_WIDTH, EMACS_UINT_WIDTH = UINT_WIDTH };
92+
# define ALIGNOF_EMACS_INT ALIGNOF_INT
9293
# define EMACS_INT_MAX INT_MAX
9394
# define pI ""
9495
# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
9596
typedef long int EMACS_INT;
9697
typedef unsigned long EMACS_UINT;
9798
enum { EMACS_INT_WIDTH = LONG_WIDTH, EMACS_UINT_WIDTH = ULONG_WIDTH };
99+
# define ALIGNOF_EMACS_INT ALIGNOF_LONG
98100
# define EMACS_INT_MAX LONG_MAX
99101
# define pI "l"
100102
# elif INTPTR_MAX <= LLONG_MAX
101103
typedef long long int EMACS_INT;
102104
typedef unsigned long long int EMACS_UINT;
103105
enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH };
106+
# define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG
104107
# define EMACS_INT_MAX LLONG_MAX
105108
/* MinGW supports %lld only if __USE_MINGW_ANSI_STDIO is non-zero,
106109
which is arranged by config.h, and (for mingw.org) if GCC is 6.0 or
@@ -237,13 +240,26 @@ DEFINE_GDB_SYMBOL_END (INTTYPEBITS)
237240
expression involving VAL_MAX. */
238241
#define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1))
239242

243+
/* The alignment ideally required of objects subject to garbage
244+
collection. (In the sense that it would be ideal for such an
245+
alignment to be available to enable LSB tagging.) */
246+
#define IDEAL_GCALIGNMENT 8
247+
240248
/* Whether the least-significant bits of an EMACS_INT contain the tag.
241249
On hosts where pointers-as-ints do not exceed VAL_MAX / 2, USE_LSB_TAG is:
242250
a. unnecessary, because the top bits of an EMACS_INT are unused, and
243251
b. slower, because it typically requires extra masking.
244252
So, USE_LSB_TAG is true only on hosts where it might be useful. */
245253
DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG)
254+
#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \
255+
&& !defined WIDE_EMACS_INT \
256+
&& !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED \
257+
&& !defined __alignas_is_defined \
258+
&& __STDC_VERSION__ < 202311 && __cplusplus < 201103)
259+
#define USE_LSB_TAG 0
260+
#else /* EMACS_INT_WIDTH >= GCALIGNMENT || defined alignas ... */
246261
#define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX)
262+
#endif /* EMACS_INT_WIDTH >= GCALIGNMENT || defined alignas ... */
247263
DEFINE_GDB_SYMBOL_END (USE_LSB_TAG)
248264

249265
/* Mask for the value (as opposed to the type bits) of a Lisp object. */
@@ -262,7 +278,7 @@ DEFINE_GDB_SYMBOL_END (VALMASK)
262278
USE_LSB_TAG, 1 otherwise. It must be a literal integer constant,
263279
for older versions of GCC (through at least 4.9). */
264280
#if USE_LSB_TAG
265-
# define GCALIGNMENT 8
281+
# define GCALIGNMENT IDEAL_GCALIGNMENT
266282
# if GCALIGNMENT != 1 << GCTYPEBITS
267283
# error "GCALIGNMENT and GCTYPEBITS are inconsistent"
268284
# endif
@@ -629,23 +645,23 @@ extern bool initialized;
629645
extern struct gflags
630646
{
631647
/* True means this Emacs instance was born to dump. */
632-
bool will_dump_ : 1;
633-
bool will_bootstrap_ : 1;
648+
bool will_dump;
649+
bool will_bootstrap;
634650
#ifdef HAVE_PDUMPER
635651
/* Set in an Emacs process that will likely dump with pdumper; all
636652
Emacs processes may dump with pdumper, however. */
637-
bool will_dump_with_pdumper_ : 1;
653+
bool will_dump_with_pdumper;
638654
/* Set in an Emacs process that has been restored from a portable
639655
dump. */
640-
bool dumped_with_pdumper_ : 1;
656+
bool dumped_with_pdumper;
641657
#endif
642658
} gflags;
643659

644660
INLINE bool
645661
will_dump_p (void)
646662
{
647663
#if HAVE_PDUMPER
648-
return gflags.will_dump_;
664+
return gflags.will_dump;
649665
#else
650666
return false;
651667
#endif
@@ -655,7 +671,7 @@ INLINE bool
655671
will_bootstrap_p (void)
656672
{
657673
#if HAVE_PDUMPER
658-
return gflags.will_bootstrap_;
674+
return gflags.will_bootstrap;
659675
#else
660676
return false;
661677
#endif
@@ -665,7 +681,7 @@ INLINE bool
665681
will_dump_with_pdumper_p (void)
666682
{
667683
#if HAVE_PDUMPER
668-
return gflags.will_dump_with_pdumper_;
684+
return gflags.will_dump_with_pdumper;
669685
#else
670686
return false;
671687
#endif
@@ -675,7 +691,7 @@ INLINE bool
675691
dumped_with_pdumper_p (void)
676692
{
677693
#if HAVE_PDUMPER
678-
return gflags.dumped_with_pdumper_;
694+
return gflags.dumped_with_pdumper;
679695
#else
680696
return false;
681697
#endif

‎src/pdumper.c

+83-58
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
7777
#define VM_POSIX 1
7878
#define VM_MS_WINDOWS 2
7979

80-
#if defined (HAVE_MMAP) && defined (MAP_FIXED)
80+
#if !USE_LSB_TAG
81+
# define VM_SUPPORTED 0
82+
#elif defined (HAVE_MMAP) && defined (MAP_FIXED)
8183
# define VM_SUPPORTED VM_POSIX
8284
# if !defined (MAP_POPULATE) && defined (MAP_PREFAULT_READ)
8385
# define MAP_POPULATE MAP_PREFAULT_READ
@@ -1964,9 +1966,9 @@ dump_field_emacs_ptr (struct dump_context *ctx,
19641966
}
19651967

19661968
static void
1967-
_dump_object_start_pseudovector (struct dump_context *ctx,
1968-
union vectorlike_header *out_hdr,
1969-
const union vectorlike_header *in_hdr)
1969+
dump_object_start_pseudovector (struct dump_context *ctx,
1970+
union vectorlike_header *out_hdr,
1971+
const union vectorlike_header *in_hdr)
19701972
{
19711973
eassert (in_hdr->size & PSEUDOVECTOR_FLAG);
19721974
ptrdiff_t vec_size = vectorlike_nbytes (in_hdr);
@@ -1976,9 +1978,9 @@ _dump_object_start_pseudovector (struct dump_context *ctx,
19761978

19771979
/* Need a macro for alloca. */
19781980
#define START_DUMP_PVEC(ctx, hdr, type, out) \
1979-
const union vectorlike_header *_in_hdr = (hdr); \
1980-
type *out = alloca (vectorlike_nbytes (_in_hdr)); \
1981-
_dump_object_start_pseudovector (ctx, &out->header, _in_hdr)
1981+
const union vectorlike_header *in_hdr = (hdr); \
1982+
type *out = alloca (vectorlike_nbytes (in_hdr)); \
1983+
dump_object_start_pseudovector (ctx, &out->header, in_hdr)
19821984

19831985
static dump_off
19841986
finish_dump_pvec (struct dump_context *ctx,
@@ -3994,14 +3996,14 @@ dump_do_fixup (struct dump_context *ctx,
39943996
Lisp_Object fixup,
39953997
Lisp_Object prev_fixup)
39963998
{
3997-
enum dump_fixup_type type =
3998-
(enum dump_fixup_type) XFIXNUM (dump_pop (&fixup));
3999+
enum dump_fixup_type type
4000+
= (enum dump_fixup_type) XFIXNUM (dump_pop (&fixup));
39994001
dump_off dump_fixup_offset = dump_off_from_lisp (dump_pop (&fixup));
40004002
#ifdef ENABLE_CHECKING
40014003
if (!NILP (prev_fixup))
40024004
{
4003-
dump_off prev_dump_fixup_offset =
4004-
dump_off_from_lisp (XCAR (XCDR (prev_fixup)));
4005+
dump_off prev_dump_fixup_offset
4006+
= dump_off_from_lisp (XCAR (XCDR (prev_fixup)));
40054007
eassert (dump_fixup_offset - prev_dump_fixup_offset
40064008
>= sizeof (void *));
40074009
}
@@ -4618,23 +4620,8 @@ dump_anonymous_allocate_posix (void *base,
46184620
}
46194621
#endif
46204622

4621-
/* Perform anonymous memory allocation. */
4622-
static void *
4623-
dump_anonymous_allocate (void *base,
4624-
const size_t size,
4625-
enum dump_memory_protection protection)
4626-
{
4627-
#if VM_SUPPORTED == VM_POSIX
4628-
return dump_anonymous_allocate_posix (base, size, protection);
4629-
#elif VM_SUPPORTED == VM_MS_WINDOWS
4630-
return dump_anonymous_allocate_w32 (base, size, protection);
4631-
#else
4632-
errno = ENOSYS;
4633-
return NULL;
4634-
#endif
4635-
}
4623+
/* Undo the effect of `dump_reserve_address_space'. */
46364624

4637-
/* Undo the effect of dump_reserve_address_space(). */
46384625
static void
46394626
dump_anonymous_release (void *addr, size_t size)
46404627
{
@@ -4653,6 +4640,26 @@ dump_anonymous_release (void *addr, size_t size)
46534640
#endif
46544641
}
46554642

4643+
/* Perform anonymous memory allocation. */
4644+
static void *
4645+
dump_anonymous_allocate (void *base,
4646+
const size_t size,
4647+
enum dump_memory_protection protection)
4648+
{
4649+
void *val;
4650+
4651+
#if VM_SUPPORTED == VM_POSIX
4652+
val = dump_anonymous_allocate_posix (base, size, protection);
4653+
#elif VM_SUPPORTED == VM_MS_WINDOWS
4654+
val = dump_anonymous_allocate_w32 (base, size, protection);
4655+
#else
4656+
errno = ENOSYS;
4657+
val = NULL;
4658+
#endif
4659+
4660+
return val;
4661+
}
4662+
46564663
#if VM_SUPPORTED == VM_MS_WINDOWS
46574664
static void *
46584665
dump_map_file_w32 (void *base, int fd, off_t offset, size_t size,
@@ -4824,20 +4831,20 @@ static void
48244831
dump_discard_mem (void *mem, size_t size)
48254832
{
48264833
#if VM_SUPPORTED == VM_MS_WINDOWS
4827-
/* Discard COWed pages. */
4828-
(void) VirtualFree (mem, size, MEM_DECOMMIT);
4829-
/* Release the commit charge for the mapping. */
4830-
DWORD old_prot;
4831-
(void) VirtualProtect (mem, size, PAGE_NOACCESS, &old_prot);
4834+
/* Discard COWed pages. */
4835+
(void) VirtualFree (mem, size, MEM_DECOMMIT);
4836+
/* Release the commit charge for the mapping. */
4837+
DWORD old_prot;
4838+
(void) VirtualProtect (mem, size, PAGE_NOACCESS, &old_prot);
48324839
#elif VM_SUPPORTED == VM_POSIX
48334840
# ifdef HAVE_POSIX_MADVISE
4834-
/* Discard COWed pages. */
4835-
(void) posix_madvise (mem, size, POSIX_MADV_DONTNEED);
4841+
/* Discard COWed pages. */
4842+
(void) posix_madvise (mem, size, POSIX_MADV_DONTNEED);
48364843
# elif defined HAVE_MADVISE
4837-
(void) madvise (mem, size, MADV_DONTNEED);
4844+
(void) madvise (mem, size, MADV_DONTNEED);
48384845
#endif
4839-
/* Release the commit charge for the mapping. */
4840-
(void) mprotect (mem, size, PROT_NONE);
4846+
/* Release the commit charge for the mapping. */
4847+
(void) mprotect (mem, size, PROT_NONE);
48414848
#endif
48424849
}
48434850

@@ -4959,21 +4966,23 @@ dump_mmap_release_vm (struct dump_memory_map *map)
49594966
static bool
49604967
needs_mmap_retry_p (void)
49614968
{
4962-
#if defined CYGWIN || VM_SUPPORTED == VM_MS_WINDOWS || defined _AIX
4969+
#if defined CYGWIN || VM_SUPPORTED == VM_MS_WINDOWS \
4970+
|| defined _AIX
49634971
return true;
4964-
#else
4972+
#else /* !CYGWIN && VM_SUPPORTED != VM_MS_WINDOWS && !_AIX */
49654973
return false;
4966-
#endif
4974+
#endif /* !CYGWIN && VM_SUPPORTED != VM_MS_WINDOWS && !_AIX */
49674975
}
49684976

49694977
static bool
49704978
dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps,
49714979
size_t total_size)
49724980
{
4981+
int save_errno;
49734982
bool ret = false;
49744983
void *resv = NULL;
49754984
bool retry = false;
4976-
const bool need_retry = needs_mmap_retry_p ();
4985+
bool need_retry = needs_mmap_retry_p ();
49774986

49784987
do
49794988
{
@@ -4986,11 +4995,10 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps,
49864995
}
49874996

49884997
eassert (resv == NULL);
4989-
resv = dump_anonymous_allocate (NULL,
4990-
total_size,
4998+
resv = dump_anonymous_allocate (NULL, total_size,
49914999
DUMP_MEMORY_ACCESS_NONE);
49925000
if (!resv)
4993-
goto out;
5001+
goto out;
49945002

49955003
char *mem = resv;
49965004

@@ -5039,6 +5047,7 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps,
50395047
ret = true;
50405048
resv = NULL;
50415049
out:
5050+
save_errno = errno;
50425051
if (resv)
50435052
dump_anonymous_release (resv, total_size);
50445053
if (!ret)
@@ -5051,15 +5060,16 @@ dump_mmap_contiguous_vm (struct dump_memory_map *maps, int nr_maps,
50515060
dump_mmap_release (&maps[i]);
50525061
}
50535062
}
5063+
errno = save_errno;
50545064
return ret;
50555065
}
50565066

50575067
/* Map a range of addresses into a chunk of contiguous memory.
50585068
50595069
Each dump_memory_map structure describes how to fill the
50605070
corresponding range of memory. On input, all members except MAPPING
5061-
are valid. On output, MAPPING contains the location of the given
5062-
chunk of memory. The MAPPING for MAPS[N] is MAPS[N-1].mapping +
5071+
are valid. On output, MAPPING contains the location of the given
5072+
chunk of memory. The MAPPING for MAPS[N] is MAPS[N-1].mapping +
50635073
MAPS[N-1].size.
50645074
50655075
Each mapping SIZE must be a multiple of the system page size except
@@ -5085,8 +5095,10 @@ dump_mmap_contiguous (struct dump_memory_map *maps, int nr_maps)
50855095
total_size += maps[i].spec.size;
50865096
}
50875097

5088-
return (VM_SUPPORTED ? dump_mmap_contiguous_vm : dump_mmap_contiguous_heap)
5089-
(maps, nr_maps, total_size);
5098+
if (VM_SUPPORTED)
5099+
return dump_mmap_contiguous_vm (maps, nr_maps, total_size);
5100+
else
5101+
return dump_mmap_contiguous_heap (maps, nr_maps, total_size);
50905102
}
50915103

50925104
typedef uint_fast32_t dump_bitset_word;
@@ -5129,7 +5141,7 @@ dump_bitset_bit_set_p (const struct dump_bitset *bitset,
51295141
{
51305142
dump_bitset_word bit = 1;
51315143
bit <<= bit_number % DUMP_BITSET_WORD_WIDTH;
5132-
return *dump_bitset__bit_slot (bitset, bit_number) & bit;
5144+
return (*dump_bitset__bit_slot (bitset, bit_number) & bit) != 0;
51335145
}
51345146

51355147
static void
@@ -5548,8 +5560,8 @@ dump_do_dump_relocation (const uintptr_t dump_base,
55485560
struct bignum_reload_info reload_info;
55495561
static_assert (sizeof (reload_info) <= sizeof (*bignum_val (bignum)));
55505562
memcpy (&reload_info, bignum_val (bignum), sizeof (reload_info));
5551-
const mp_limb_t *limbs =
5552-
dump_ptr (dump_base, reload_info.data_location);
5563+
const mp_limb_t *limbs = dump_ptr (dump_base,
5564+
reload_info.data_location);
55535565
mpz_roinit_n (bignum->value, limbs, reload_info.nlimbs);
55545566
break;
55555567
}
@@ -5790,15 +5802,29 @@ pdumper_load (const char *dump_filename, char *argv0)
57905802
goto out;
57915803

57925804
err = PDUMPER_LOAD_ERROR;
5793-
mark_bits_needed =
5794-
divide_round_up (header->discardable_start, DUMP_ALIGNMENT);
5805+
dump_base = (uintptr_t) sections[DS_HOT].mapping;
5806+
5807+
#if !USE_LSB_TAG
5808+
/* The dump may have been mapped at a location that does not admit of
5809+
representation as Lisp_Objects. Abort in this case. */
5810+
if ((dump_base + dump_size) & ~VALMASK)
5811+
{
5812+
fprintf (stderr,
5813+
"Failed to load dump file: 0x%p+0x%p & 0x%p != 0\n",
5814+
(void *) dump_base, (void *) dump_size,
5815+
(void *) (uintptr_t) VALMASK);
5816+
goto out;
5817+
}
5818+
#endif /* !USE_LSB_TAG */
5819+
5820+
mark_bits_needed
5821+
= divide_round_up (header->discardable_start, DUMP_ALIGNMENT);
57955822
if (!dump_bitsets_init (mark_bits, mark_bits_needed))
57965823
goto out;
57975824

57985825
/* Point of no return. */
57995826
err = PDUMPER_LOAD_SUCCESS;
5800-
dump_base = (uintptr_t) sections[DS_HOT].mapping;
5801-
gflags.dumped_with_pdumper_ = true;
5827+
gflags.dumped_with_pdumper = true;
58025828
dump_private.header = *header;
58035829
dump_private.mark_bits = mark_bits[0];
58045830
dump_private.last_mark_bits = mark_bits[1];
@@ -5815,8 +5841,8 @@ pdumper_load (const char *dump_filename, char *argv0)
58155841
Lisp_Object hashes = zero_vector;
58165842
if (header->hash_list)
58175843
{
5818-
struct Lisp_Vector *hash_tables =
5819-
(struct Lisp_Vector *) (dump_base + header->hash_list);
5844+
struct Lisp_Vector *hash_tables
5845+
= (struct Lisp_Vector *) (dump_base + header->hash_list);
58205846
hashes = make_lisp_ptr (hash_tables, Lisp_Vectorlike);
58215847
}
58225848

@@ -5852,7 +5878,6 @@ pdumper_load (const char *dump_filename, char *argv0)
58525878
dump_mmap_release (&sections[i]);
58535879
if (dump_fd >= 0)
58545880
emacs_close (dump_fd);
5855-
58565881
return err;
58575882
}
58585883

0 commit comments

Comments
 (0)
Please sign in to comment.