diff --git a/src/dumper.c b/src/dumper.c
--- a/src/dumper.c
+++ b/src/dumper.c
@@ -308,6 +308,13 @@
  */
 #endif /* not NEW_GC */
 
+const struct sized_memory_description *
+aslr_lispdesc_indirect_description (const void *obj,
+				    const struct sized_memory_description *sdesc);
+#define ASLR_RELOC_ADDRESS &pdump_length
+#define FIX_ASLR(p, t) \
+  ((t) (((EMACS_UINT) p) - (((pdump_header *) pdump_start)->aslr_reloc_address \
+			    - (EMACS_UINT) ASLR_RELOC_ADDRESS)))
 
 #define PDUMP_SIGNATURE "XEmacsDP"
 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1)
@@ -318,6 +325,7 @@
   unsigned int id;
   EMACS_UINT stab_offset;
   EMACS_UINT reloc_address;
+  EMACS_UINT aslr_reloc_address;
   int nb_root_block_ptrs;
   int nb_root_blocks;
   int nb_cv_data;
@@ -1215,6 +1223,28 @@
   retry_fwrite (desc ? pdump_buf : elt->obj, size, count, pdump_out);
 }
 
+/* Lookup indirect memory descriptions and fix ASLR. */
+const struct sized_memory_description *
+aslr_lispdesc_indirect_description (const void *obj,
+				    const struct sized_memory_description *sdesc)
+{
+  if (sdesc->description)
+    return sdesc;
+  else
+    {
+      int pos;
+      const struct sized_memory_description *aslr_sdesc;
+
+      for (pos = 0; sdesc[pos].size >= 0; pos++)
+	obj = * (const void **) ((const char *) obj + sdesc[pos].size);
+      aslr_sdesc = FIX_ASLR (obj, const struct sized_memory_description *);
+
+      memcpy (&obj, aslr_sdesc, sizeof (void *));
+
+      return aslr_sdesc;
+    }
+}
+
 #ifdef NEW_GC
 /* To be able to relocate during load time, more information about the
    dumped objects are needed: The count (for array-like data
@@ -1313,9 +1343,12 @@
 	case XD_INT_RESET:
 	  break;
 	case XD_INLINE_LISP_OBJECT_BLOCK_PTR:
+	case XD_BLOCK_PTR:
+	  {
+	    aslr_lispdesc_indirect_description (data, desc1->data2.descr);
+	  }
 	case XD_OPAQUE_DATA_PTR:
 	case XD_ASCII_STRING:
-	case XD_BLOCK_PTR:
 	case XD_LO_LINK:
 	  {
 	    EMACS_INT ptr = *(EMACS_INT *) rdata;
@@ -1365,7 +1398,7 @@
 						     data);
 	    int j;
 	    const struct sized_memory_description *sdesc =
-	      lispdesc_indirect_description (data, desc1->data2.descr);
+	      aslr_lispdesc_indirect_description (data, desc1->data2.descr);
 	    Bytecount size = lispdesc_block_size (rdata, sdesc);
 
 	    /* Note: We are recursing over data in the block itself */
@@ -1453,9 +1486,12 @@
 	case XD_LONG:
 	case XD_INT_RESET:
 	  break;
+	case XD_BLOCK_PTR:
+	  {
+	    aslr_lispdesc_indirect_description (data, desc1->data2.descr);
+	  }
 	case XD_OPAQUE_DATA_PTR:
 	case XD_ASCII_STRING:
-	case XD_BLOCK_PTR:
 	case XD_LO_LINK:
 	  {
 	    EMACS_INT ptr = *(EMACS_INT *)rdata;
@@ -1505,7 +1541,7 @@
 						     data);
 	    int j;
 	    const struct sized_memory_description *sdesc =
-	      lispdesc_indirect_description (data, desc1->data2.descr);
+	      aslr_lispdesc_indirect_description (data, desc1->data2.descr);
 	    Bytecount size = lispdesc_block_size (rdata, sdesc);
 
 	    /* Note: We are recursing over data in the block itself */
@@ -2094,6 +2130,7 @@
   memcpy (header.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN);
   header.id = dump_id;
   header.reloc_address = 0;
+  header.aslr_reloc_address = (EMACS_UINT) ASLR_RELOC_ADDRESS;
   header.nb_root_block_ptrs = Dynarr_length (pdump_root_block_ptrs);
   header.nb_root_blocks = Dynarr_length (pdump_root_blocks);
   header.nb_cv_data = Dynarr_length (pdump_cv_data);
@@ -2316,7 +2353,8 @@
 	  for (i = 0; i < rt.count; i++)
 	    {
 	      reloc[i] = (Rawbyte *) pdump_get_mc_addr (reloc[i]);
-	      pdump_reloc_one_mc (reloc[i], rt.desc);
+	      pdump_reloc_one_mc (reloc[i], FIX_ASLR (rt.desc, 
+						      const struct memory_description *));
 	    }
 	  p += rt.count * sizeof (Rawbyte *);
 	}
@@ -2331,9 +2369,9 @@
     {
       pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer);
 #ifdef NEW_GC
-      (* ptr.address) = (Rawbyte *) pdump_get_mc_addr (ptr.value);
+      (* FIX_ASLR (ptr.address, Rawbyte **)) = (Rawbyte *) pdump_get_mc_addr (ptr.value);
 #else /* not NEW_GC */
-      (* ptr.address) = ptr.value + delta;
+      (* FIX_ASLR (ptr.address, Rawbyte **)) = ptr.value + delta;
 #endif /* not NEW_GC */
     }
 
@@ -2341,12 +2379,14 @@
   for (i = 0; i < header->nb_root_blocks; i++)
     {
       pdump_root_block info = PDUMP_READ_ALIGNED (p, pdump_root_block);
-      memcpy ((void *) info.blockaddr, p, info.size);
+      memcpy (FIX_ASLR (info.blockaddr, void *), p, info.size);
       if (info.desc)
 #ifdef NEW_GC
-	pdump_reloc_one_mc ((void *) info.blockaddr, info.desc);
+	pdump_reloc_one_mc (FIX_ASLR (info.blockaddr, void *), 
+			    FIX_ASLR (info.desc, const struct memory_description *));
 #else /* not NEW_GC */
-	pdump_reloc_one ((void *) info.blockaddr, delta, info.desc);
+	pdump_reloc_one (FIX_ASLR (info.blockaddr, void *), delta,
+			 FIX_ASLR (info.desc, const struct memory_description *));
 #endif /* not NEW_GC */
       p += info.size;
     }
@@ -2365,7 +2405,7 @@
 	  for (i = 0; i < rt.count; i++)
 	    {
 	      reloc[i] += delta;
-	      pdump_reloc_one (reloc[i], delta, rt.desc);
+	      pdump_reloc_one (reloc[i], delta, FIX_ASLR (rt.desc, const struct memory_description *));
 	    }
 	  p += rt.count * sizeof (Rawbyte *);
 	}
@@ -2389,7 +2429,7 @@
         obj.value = wrap_pointer_1 ((Rawbyte *) XPNTR (obj.value) + delta);
 #endif /* not NEW_GC */
 
-      (* obj.address) = obj.value;
+      (* FIX_ASLR (obj.address, Lisp_Object *)) = obj.value;
     }
 
   /* Final cleanups */
@@ -2401,8 +2441,9 @@
       p = (Rawbyte *) ALIGN_PTR (p, Lisp_Object);
       if (!rt.desc)
 	break;
-      if (rt.desc == hash_table_description)
+      if (rt.desc == hash_table_description) // TODO: FIX_ASLR?
 	{
+	  printf("hash_table\n");
 	  for (i = 0; i < rt.count; i++)
 	    pdump_reorganize_hash_table (PDUMP_READ (p, Lisp_Object));
 	  break;
@@ -2413,9 +2454,6 @@
 
 #ifdef NEW_GC
   xfree (pdump_mc_hash);
-#endif /* NEW_GC */
-
-#ifdef NEW_GC
   allow_incremental_gc = allow_inc_gc;
 #endif /* NEW_GC */
 
