From 64f552d11cb9660d153647ba713276dd5e07ec77 Mon Sep 17 00:00:00 2001 From: Helmut Eller Date: Tue, 25 Jun 2024 16:44:35 +0200 Subject: [PATCH 1/3] Add some checks when dumping and when loading the dump * src/igc.h (igc_dump_check_object_starts): New. * src/igc.c (igc_dump_check_object_starts): Implementation. (check_dump): New. (igc_on_pdump_loaded): Use it. * src/pdumper.c (dump_igc_check_object_starts): New. (Fdump_emacs_portable): Use it. --- src/igc.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/igc.h | 3 +++ src/pdumper.c | 16 +++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/igc.c b/src/igc.c index 4c9860c35d9..49abc136a0c 100644 --- a/src/igc.c +++ b/src/igc.c @@ -4093,6 +4093,62 @@ igc_dump_finish_obj (void *client, enum igc_obj_type type, return base + nbytes; } +void +igc_dump_check_object_starts (Lisp_Object relocs, void *dump_base, + void *hot_start, void *hot_end, + void *cold_start, void *heap_end) +{ + eassert (is_aligned (dump_base)); + eassert (is_aligned (hot_start)); + eassert (is_aligned (hot_end)); + eassert (is_aligned (cold_start)); + eassert (is_aligned (hot_end)); + struct region + { + mps_addr_t start, end; + } regions[] = { + {hot_start, hot_end}, + {cold_start, heap_end}, + }; + for (size_t i = 0; i < ARRAYELTS (regions); i++) + { + struct region region = regions[i]; + mps_addr_t p = region.start; + while (p != region.end) + { + eassert (p < region.end); + Lisp_Object r = XCAR (relocs); + relocs = XCDR (relocs); + EMACS_INT start_off = XFIXNUM (XCAR (r)); + EMACS_INT end_off = XFIXNUM (XCAR (XCDR (r))); + mps_addr_t start = (uint8_t *) dump_base + start_off; + mps_addr_t end = (uint8_t *) dump_base + end_off; + eassert (start == p); + p = dflt_skip (p); + eassert (end == p); + } + } + eassert (NILP (relocs)); +} + +static bool +check_dump (mps_addr_t start, mps_addr_t end) +{ + struct pdumper_object_it it = { 0 }; + for (mps_addr_t p = start; p != end; p = dflt_skip (p)) + { + eassert (p < end); + struct igc_header *h = p; + if (h->obj_type != IGC_OBJ_PAD) + { + mps_addr_t obj = pdumper_next_object (&it); + eassert (p == obj); + } + } + eassert (pdumper_next_object (&it) == NULL); + return true; +} + static mps_addr_t pinned_objects_in_dump[3]; /* Called from pdumper_load. [START, END) is the hot section of the @@ -4129,6 +4185,7 @@ igc_on_pdump_loaded (void *dump_base, void *hot_start, void *hot_end, /* Ignore relocs */ set_header (heap_end, IGC_OBJ_PAD, relocs_size, 0); + eassert (check_dump (h, cold_end)); /* Pin some stuff in the dump */ mps_addr_t pinned_roots[] = { charset_table, diff --git a/src/igc.h b/src/igc.h index 8beb4fd2dce..5e59a706af7 100644 --- a/src/igc.h +++ b/src/igc.h @@ -153,6 +153,9 @@ #define EMACS_IGC_H size_t igc_header_size (void); char *igc_dump_finish_obj (void *client, enum igc_obj_type type, char *base, char *end); +void igc_dump_check_object_starts (Lisp_Object relocs, void *dump_base, + void *hot_start, void *hot_end, + void *cold_start, void *heap_end); void *igc_alloc_dump (size_t nbytes); bool igc_busy_p (void); Lisp_Object igc_discard_killed_buffers (Lisp_Object list); diff --git a/src/pdumper.c b/src/pdumper.c index e0ff08c9d3d..a9d67fe203a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -882,6 +882,21 @@ dump_align_output (struct dump_context *ctx, int alignment) } # ifdef HAVE_MPS +static void +dump_igc_check_object_starts (struct dump_context *ctx) +{ + Lisp_Object relocs = CALLN (Fsort, Freverse (ctx->igc_object_starts), + Qdump_emacs_portable__sort_predicate); + void *dump_base = (uint8_t *) ctx->buf; + size_t dump_header_size = ROUNDUP (sizeof ctx->header, sizeof (uintptr_t)); + void *hot_start = (uint8_t *) dump_base + dump_header_size; + void *hot_end = (uint8_t *) dump_base + ctx->header.discardable_start; + void *cold_start = (uint8_t *) dump_base + ctx->header.cold_start; + void *heap_end = (uint8_t *) dump_base + ctx->header.heap_end; + igc_dump_check_object_starts (relocs, dump_base, + hot_start, hot_end, cold_start, heap_end); +} + static void dump_igc_start_obj (struct dump_context *ctx, enum igc_obj_type type, const void *in) @@ -4471,6 +4486,7 @@ DEFUN ("dump-emacs-portable", # ifdef HAVE_MPS ctx->header.heap_end = ctx->offset; + dump_igc_check_object_starts (ctx); dump_igc_start_obj (ctx, IGC_OBJ_DUMPED_BYTES, &discardable_end); # endif -- 2.39.2