--- ./makedumpfile.h.org	2006-09-07 18:20:33.000000000 +0900
+++ ./makedumpfile.h	2006-09-07 18:21:22.000000000 +0900
@@ -40,6 +40,14 @@
 #define OUTPUT_FAILED	(4)	/* detected an output error. */
 
 /*
+ * Type of memory management
+ */
+enum {
+	NOT_FOUND_MEMTYPE,
+	FLATMEM
+};
+
+/*
  * Page flags
  */
 #define PG_locked	(0)	/* Page is locked. Don't touch. */
@@ -91,6 +99,11 @@ isAnon(unsigned long mapping)
 }
 
 /*
+ * Incorrect address
+ */
+#define NOT_MEMMAP_ADDR	(0x0)
+
+/*
  * Dump Level
  */
 #define MIN_DUMP_LEVEL		(0)
@@ -255,6 +268,12 @@ struct pt_load_segment {
 	unsigned long long	virt_end;
 };
 
+struct mem_map_data {
+	unsigned long	pfn_start;
+	unsigned long	pfn_end;
+	unsigned long	mem_map;
+};
+
 struct dump_bitmap {
 	int		fd;
 	int		no_block;
@@ -274,7 +293,6 @@ struct cache_data {
 
 struct DumpInfo {
 	int		retcd;		     /* return code */
-	unsigned long	addr_mem_map;        /* address of symbol mem_map */
 	int		kernel_version;      /* version of first kernel */
 
 	/*
@@ -309,6 +327,12 @@ struct DumpInfo {
 	struct pt_load_segment	*pt_load_segments;
 
 	/*
+	 * mem_map info:
+	 */
+	unsigned int		num_mem_map;
+	struct mem_map_data	*mem_map_data;
+
+	/*
 	 * System.map file info:
 	 */
 	FILE			*map;
--- ./makedumpfile.c.org	2006-09-07 18:20:29.000000000 +0900
+++ ./makedumpfile.c	2006-09-07 18:31:52.000000000 +0900
@@ -815,60 +815,75 @@ get_structure_info(struct DumpInfo *info
 }
 
 int
+get_mem_type(struct DumpInfo *info)
+{
+	int ret;
+
+	if ((SIZE(page) == NOT_FOUND_STRUCTURE)
+	    || (OFFSET(page.flags) == NOT_FOUND_STRUCTURE)
+	    || (OFFSET(page._count) == NOT_FOUND_STRUCTURE)
+	    || (OFFSET(page.mapping) == NOT_FOUND_STRUCTURE))
+		ret = NOT_FOUND_MEMTYPE;
+	else if (SYMBOL(mem_map) != NOT_FOUND_SYMBOL)
+		ret = FLATMEM;
+	else
+		ret = NOT_FOUND_MEMTYPE;
+
+	return ret;
+}
+
+int
 generate_config(struct DumpInfo *info)
 {
 	struct utsname utsname_buf;
-	long tmp_long;
 
-	/*
-	 * write 1st kernel's OSRELEASE
-	 */
 	if (uname(&utsname_buf)) {
 		ERRMSG("Can't get uname. %s\n", strerror(errno));
 		return FALSE;
 	}
+	if ((info->page_size = sysconf(_SC_PAGE_SIZE)) <= 0) {
+		ERRMSG("Can't get the size of page.\n");
+		return FALSE;
+	}
+	if (!(info->kernel_version = get_kernel_version(utsname_buf.release)))
+		return FALSE;
+
+	if (!get_symbol_info(info))
+		return FALSE;
+
+	if (!get_structure_info(info))
+		return FALSE;
+
+	if (SYMBOL(system_utsname) == NOT_FOUND_SYMBOL) {
+		ERRMSG("Can't get the symbol of system_utsname.\n");
+		return FALSE;
+	}
+	if (get_mem_type(info) == NOT_FOUND_MEMTYPE) {
+		ERRMSG("Can't find the memory type.\n");
+		return FALSE;
+	}
+
+	/*
+	 * write 1st kernel's OSRELEASE
+	 */
 	fprintf(info->file_configfile, "%s%s\n", STR_OSRELEASE,
 	    utsname_buf.release);
 
 	/*
 	 * write 1st kernel's PAGESIZE
 	 */
-	if (!info->page_size) {
-		tmp_long = sysconf(_SC_PAGE_SIZE);
-		if (tmp_long == -1) {
-			ERRMSG("Can't get the size of page.\n");
-			return FALSE;
-		}
-		info->page_size = (size_t)tmp_long;
-	}
 	fprintf(info->file_configfile, "%s%d\n", STR_PAGESIZE,
 	    (int)info->page_size);
 
 	/*
 	 * write the symbol of 1st kernel
 	 */
-	if (!get_symbol_info(info))
-		return FALSE;
-	if ((SYMBOL(mem_map) == NOT_FOUND_SYMBOL)
-	    || (SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)) {
-		ERRMSG("Can't get the symbol of mem_map.\n");
-		return FALSE;
-	}
 	WRITE_SYMBOL("mem_map", mem_map);
 	WRITE_SYMBOL("system_utsname", system_utsname);
 
 	/*
-	 * get 1st kernel's version
-	 */
-	info->kernel_version = get_kernel_version(utsname_buf.release);
-	if (info->kernel_version == FALSE)
-		return FALSE;
-
-	/*
 	 * write the structure size of 1st kernel
 	 */
-	if (!get_structure_info(info))
-		return FALSE;
 	WRITE_STRUCTURE_SIZE("page", page);
 
 	/*
@@ -993,36 +1008,64 @@ read_config(struct DumpInfo *info)
 	return TRUE;
 }
 
+void
+dump_mem_map(struct DumpInfo *info, unsigned long pfn_start,
+    unsigned long pfn_end, unsigned long mem_map, int num_mm)
+{
+	struct mem_map_data *mmd;
+
+	mmd = &info->mem_map_data[num_mm];
+	mmd->pfn_start = pfn_start;
+	mmd->pfn_end   = pfn_end;
+	mmd->mem_map   = mem_map;
+
+	return;
+}
+
 int
-get_mem_map(struct DumpInfo *info)
+get_mm_flatmem(struct DumpInfo *info)
 {
-	unsigned long sym_mem_map = SYMBOL(mem_map);
 	unsigned long addr_mem_map;
 
 	/*
 	 * Get the address of the symbol "mem_map".
-	 * FIXME
-	 *   If this command get the feature of analysing a struct,
-	 *   the info of the memory management will be gotten from "pgdat_list".
 	 */
-	if (!sym_mem_map) {
-		ERRMSG("Can't get the symbol of mem_map.\n");
-		return FALSE;
-	}
-	if (!readmem(info, sym_mem_map, &addr_mem_map, sizeof addr_mem_map)) {
+	if (!readmem(info, SYMBOL(mem_map), &addr_mem_map, sizeof addr_mem_map)
+	    || !addr_mem_map) {
 		ERRMSG("Can't get the address of mem_map.\n");
 		return FALSE;
 	}
-	if (!addr_mem_map) {
-		ERRMSG("Can't get the address of mem_map.\n");
+	info->num_mem_map = 1;
+	if ((info->mem_map_data = (struct mem_map_data *)
+	    g_malloc0(sizeof(struct mem_map_data)*info->num_mem_map)) == NULL) {
+		ERRMSG("Can't allocate memory for the mem_map_data. %s\n",
+		    strerror(errno));
 		return FALSE;
 	}
-	info->addr_mem_map = addr_mem_map;
+	dump_mem_map(info, 0, info->max_mapnr, addr_mem_map, 0);
 
 	return TRUE;
 }
 
 int
+get_mem_map(struct DumpInfo *info)
+{
+	int ret;
+
+	switch (get_mem_type(info)) {
+	case FLATMEM:
+		MSG("Memory type : FLATMEM\n");
+		ret = get_mm_flatmem(info);
+		break;
+	default:
+		ERRMSG("Can't distinguish the memory type.\n");
+		ret = FALSE;
+		break;
+	}
+	return ret;
+}
+
+int
 initial(struct DumpInfo *info)
 {
 	if (!get_elf_info(info))
@@ -1040,11 +1083,6 @@ initial(struct DumpInfo *info)
 	} else {
 		if (!read_config(info))
 			return FALSE;
-		if ((SYMBOL(mem_map) == NOT_FOUND_SYMBOL)
-		    || (SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)) {
-			ERRMSG("Invalid format in %s", info->name_configfile);
-			return FALSE;
-		}
 		if (!check_release(info))
 			return FALSE;
 	}
@@ -1311,17 +1349,17 @@ out:
 int
 create_dump_bitmap(struct DumpInfo *info)
 {
-	int val;
-	unsigned int i, pfn, remain_size;
+	int val, not_found_mem_map;
+	unsigned int i, mm, pfn, remain_size;
 	unsigned long addr_mem_map, paddr;
 	unsigned char *page_cache = NULL, *buf = NULL, *pcache;
 	unsigned int _count;
 	unsigned long flags, mapping;
 	struct cache_data bm1, bm2;
+	struct mem_map_data *mmd;
 	off_t offset_page;
 	const off_t failed = (off_t)-1;
 
-	addr_mem_map = info->addr_mem_map;
 	offset_page  = info->offset_load_memory;
 
 	bm1.fd         = info->fd_bitmap;
@@ -1359,117 +1397,130 @@ create_dump_bitmap(struct DumpInfo *info
 		goto out;
 	}
 
-	for (pfn = 0, paddr = 0; pfn < info->max_mapnr;
-	    pfn++, addr_mem_map += SIZE(page),
-	    paddr += info->page_size) {
+	for (mm = 0; mm < info->num_mem_map; mm++) {
+		mmd = &info->mem_map_data[mm];
+		pfn   = mmd->pfn_start;
+		paddr = pfn*info->page_size;
+		addr_mem_map = mmd->mem_map;
+
+		if (addr_mem_map == NOT_MEMMAP_ADDR)
+			not_found_mem_map = TRUE;
+		else
+			not_found_mem_map = FALSE;
 
-		if ((pfn != 0) && (pfn%PFN_BUFBITMAP) == 0) {
+		for (; pfn < mmd->pfn_end;
+		    pfn++, addr_mem_map += SIZE(page),
+		    paddr += info->page_size) {
+
+			if ((pfn != 0) && (pfn%PFN_BUFBITMAP) == 0) {
+				/*
+				 * Write the 1st-bitmap and the 2nd-bitmap.
+				 */
+				bm1.buf_size = BUFSIZE_BITMAP;
+				bm2.buf_size = BUFSIZE_BITMAP;
+				if (!write_cache_bufsz(&bm1))
+					goto out;
+				if (!write_cache_bufsz(&bm2))
+					goto out;
+
+				/*
+				 * Clear the remainder of the bitmap.
+				 */
+				if ((info->max_mapnr - pfn) <= PFN_BUFBITMAP) {
+					for (i = 0; i < PFN_BUFBITMAP; i++) {
+						set_bitmap(bm1.buf, i, 0);
+						set_bitmap(bm2.buf, i, 0);
+					}
+				}
+			}
 			/*
-			 * Write the 1st-bitmap and the 2nd-bitmap.
+			 * val  1: dump Page
+			 *      0: not dump Page
 			 */
-			bm1.buf_size = BUFSIZE_BITMAP;
-			bm2.buf_size = BUFSIZE_BITMAP;
-			if (!write_cache_bufsz(&bm1))
-				goto out;
-			if (!write_cache_bufsz(&bm2))
-				goto out;
+			val = 1;
 
 			/*
-			 * Clear the remainder of the bitmap.
+			 * Exclude the memory hole.
 			 */
-			if ((info->max_mapnr - pfn) <= PFN_BUFBITMAP) {
-				for (i = 0; i < PFN_BUFBITMAP; i++) {
-					set_bitmap(bm1.buf, i, 0);
-					set_bitmap(bm2.buf, i, 0);
-				}
-			}
-		}
-		/*
-		 * val  1: dump Page
-		 *      0: not dump Page
-		 */
-		val = 1;
-
-		/*
-		 * Exclude the memory hole.
-		 */
-		if (!is_in_segs(info, paddr))
-			val = 0;
+			if (!is_in_segs(info, paddr))
+				val = 0;
 
-		/*
-		 * Set the 1st-bitmap.
-		 *  val  1: not memory hole
-		 *       0: memory hole
-		 */
-		set_bitmap(bm1.buf, pfn%PFN_BUFBITMAP, val);
+			/*
+			 * Set the 1st-bitmap.
+			 *  val  1: not memory hole
+			 *       0: memory hole
+			 */
+			set_bitmap(bm1.buf, pfn%PFN_BUFBITMAP, val);
 
-		/*
-		 * Exclude the page filled with zero in case of creating
-		 * the elf dumpfile.
-		 */
-		if (info->flag_elf_dumpfile
-		    && (val != 0)
-		    && (info->dump_level & DL_EXCLUDE_ZERO)) {
-			if (lseek(info->fd_memory, offset_page, SEEK_SET)
-			    == failed) {
-				ERRMSG("Can't seek the dump memory(%s). %s\n",
-				    info->name_memory, strerror(errno));
-				goto out;
+			/*
+			 * Exclude the page filled with zero in case of creating
+			 * the elf dumpfile.
+			 */
+			if (info->flag_elf_dumpfile
+			    && (val != 0)
+			    && (info->dump_level & DL_EXCLUDE_ZERO)) {
+				if (lseek(info->fd_memory, offset_page,
+				    SEEK_SET) == failed) {
+					ERRMSG("Can't seek the dump memory(%s). %s\n",
+					    info->name_memory, strerror(errno));
+					goto out;
+				}
+				if (read(info->fd_memory, buf, info->page_size)
+				    != info->page_size) {
+					ERRMSG("Can't read the dump memory(%s). %s\n",
+					    info->name_memory, strerror(errno));
+					goto out;
+				}
+				offset_page += info->page_size;
+				if (is_zero_page(buf, info->page_size))
+					val = 0;
 			}
-			if (read(info->fd_memory, buf, info->page_size)
-			    != info->page_size) {
-				ERRMSG("Can't read the dump memory(%s). %s\n",
-				    info->name_memory, strerror(errno));
-				goto out;
+			if ((info->dump_level <= DL_EXCLUDE_ZERO)
+			    || not_found_mem_map) {
+				set_bitmap(bm2.buf, pfn%PFN_BUFBITMAP, val);
+				continue;
 			}
-			offset_page += info->page_size;
-			if (is_zero_page(buf, info->page_size))
-				val = 0;
-		}
-		if (info->dump_level <= DL_EXCLUDE_ZERO) {
-			set_bitmap(bm2.buf, pfn%PFN_BUFBITMAP, val);
-			continue;
-		}
 
-		if ((pfn % PGMM_CACHED) == 0) {
-			if (!readmem(info, addr_mem_map, page_cache,
-			    SIZE(page) * PGMM_CACHED))
-				goto out;
-		}
-		pcache  = page_cache + ((pfn%PGMM_CACHED) * SIZE(page));
-		flags   = ULONG(pcache + OFFSET(page.flags));
-		_count  = UINT(pcache + OFFSET(page._count));
-		mapping = ULONG(pcache + OFFSET(page.mapping));
+			if ((pfn % PGMM_CACHED) == 0) {
+				if (!readmem(info, addr_mem_map, page_cache,
+				    SIZE(page) * PGMM_CACHED))
+					goto out;
+			}
+			pcache  = page_cache + ((pfn%PGMM_CACHED) * SIZE(page));
+			flags   = ULONG(pcache + OFFSET(page.flags));
+			_count  = UINT(pcache + OFFSET(page._count));
+			mapping = ULONG(pcache + OFFSET(page.mapping));
 
-		/*
-		 * Exclude the cache page without the private page.
-		 */
-		if ((info->dump_level & DL_EXCLUDE_CACHE)
-		    && (isLRU(flags) || isSwapCache(flags))
-		    && !isPrivate(flags) && !isAnon(mapping))
-			val = 0;
+			/*
+			 * Exclude the cache page without the private page.
+			 */
+			if ((info->dump_level & DL_EXCLUDE_CACHE)
+			    && (isLRU(flags) || isSwapCache(flags))
+			    && !isPrivate(flags) && !isAnon(mapping))
+				val = 0;
 
-		/*
-		 * Exclude the cache page with the private page.
-		 */
-		else if ((info->dump_level & DL_EXCLUDE_CACHE_PRI)
-		    && (isLRU(flags) || isSwapCache(flags))
-		    && !isAnon(mapping))
-			val = 0;
+			/*
+			 * Exclude the cache page with the private page.
+			 */
+			else if ((info->dump_level & DL_EXCLUDE_CACHE_PRI)
+			    && (isLRU(flags) || isSwapCache(flags))
+			    && !isAnon(mapping))
+				val = 0;
 
-		/*
-		 * Exclude the data page of the user process.
-		 */
-		else if ((info->dump_level & DL_EXCLUDE_USER_DATA)
-		    && isAnon(mapping))
-			val = 0;
+			/*
+			 * Exclude the data page of the user process.
+			 */
+			else if ((info->dump_level & DL_EXCLUDE_USER_DATA)
+			    && isAnon(mapping))
+				val = 0;
 
-		/*
-		 * Set the 2nd-bitmap.
-		 *  val  1: dump page
-		 *       0: not dump page(the memory hole, or the excluded page)
-		 */
-		set_bitmap(bm2.buf, pfn%PFN_BUFBITMAP, val);
+			/*
+			 * Set the 2nd-bitmap.
+			 *  val  1: dump page
+			 *       0: not dump page(memory hole, or page excluded)
+			 */
+			set_bitmap(bm2.buf, pfn%PFN_BUFBITMAP, val);
+		}
 	}
 
 	/*
@@ -2410,8 +2461,10 @@ main(int argc, char *argv[])
 		MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 	}
 	MSG("makedumpfile Completed.\n");
-	if (!info->flag_generate_config)
+	if (!info->flag_generate_config) {
 		g_free(info->pt_load_segments);
+		g_free(info->mem_map_data);
+	}
 	g_free(info->dump_header);
 	g_free(info);
 	return COMPLETED;
@@ -2429,6 +2482,8 @@ out:
 		close(info->fd_bitmap);
 	if (info->pt_load_segments != NULL)
 		g_free(info->pt_load_segments);
+	if (info->mem_map_data != NULL)
+		g_free(info->mem_map_data);
 	if (info->dump_header != NULL)
 		g_free(info->dump_header);
 	if (info != NULL)
