[PATCH] [makedumpfile] Implement memory regions on IA64

Ken'ichi Ohmichi oomichi at mxs.nes.nec.co.jp
Mon May 21 05:32:27 EDT 2007


Hi Bernhard,

2007/05/16 20:20:00 +0900, "Ken'ichi Ohmichi" <oomichi at mxs.nes.nec.co.jp> wrote:
>I propose that makedumpfile distinguishes the page table (3L or 4L)
>by checking the defined file name of pud_t.
>I'm trying for the above implementation.
>I will send you the patch when it is complete.

The attached patch is for the above implementation.
It works fine with linux-2.6.18.
Could you test it with your environment ?

Please apply the attached patch with the following makedumpfile:

makedumpfile-1.1.3
 + 2007/05/11 by Ken'ichi, 01-vaddr_to_offset_ia64.patch 
 + 2007/05/11 by Ken'ichi, 02-ia64-discontigmem.patch
 + 2007/05/16 by Bernhard, [Re: Implement memory regions on IA64] patch
 + 2007/05/21 by Ken'ichi, [Re: Fix missing last node] patch


Thanks
Ken'ichi Ohmichi

--
diff -puN makedumpfile.org/ia64.c makedumpfile/ia64.c
--- makedumpfile.org/ia64.c	2007-05-21 19:20:06.000000000 +0900
+++ makedumpfile/ia64.c	2007-05-21 19:34:06.000000000 +0900
@@ -62,6 +62,15 @@ get_machdep_info_ia64(struct DumpInfo *i
 	info->section_size_bits = _SECTION_SIZE_BITS;
 	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
 
+	if (!strncmp(SRCFILE(pud_t), STR_PUD_T_4L, strlen(STR_PUD_T_4L)))
+		info->mem_flags |= MEMORY_4LAYER_PAGETABLE;
+
+	else if (!strncmp(SRCFILE(pud_t), STR_PUD_T_3L, strlen(STR_PUD_T_3L)))
+		info->mem_flags |= MEMORY_3LAYER_PAGETABLE;
+
+	else
+		MSG("Can't distinguish the pgtable.\n");
+
 	return TRUE;
 }
 
diff -puN makedumpfile.org/makedumpfile.c makedumpfile/makedumpfile.c
--- makedumpfile.org/makedumpfile.c	2007-05-21 19:20:06.000000000 +0900
+++ makedumpfile/makedumpfile.c	2007-05-21 19:28:54.000000000 +0900
@@ -26,6 +26,7 @@ struct symbol_table	symbol_table;
 struct size_table	size_table;
 struct offset_table	offset_table;
 struct array_table	array_table;
+struct srcfile_table	srcfile_table;
 
 struct dwarf_info	dwarf_info;
 struct vm_table		*vt = 0;
@@ -1141,6 +1142,15 @@ is_search_symbol(int cmd)
 		return FALSE;
 }
 
+int
+is_search_srcfile(int cmd)
+{
+	if (cmd == DWARF_INFO_GET_TYPEDEF_SRCNAME)
+		return TRUE;
+	else
+		return FALSE;
+}
+
 static void
 search_structure(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 {
@@ -1190,6 +1200,49 @@ search_structure(Dwarf *dwarfd, Dwarf_Di
 }
 
 static void
+search_srcfile(Dwarf *dwarfd, Dwarf_Die *die, int *found)
+{
+	int tag = 0, rtag = 0;
+	char *src_name = NULL;
+	const char *name;
+
+	switch (dwarf_info.cmd) {
+	case DWARF_INFO_GET_TYPEDEF_SRCNAME:
+		rtag = DW_TAG_typedef;
+		break;
+	}
+
+	/*
+	 * If we get to here then we don't have any more
+	 * children, check to see if this is a relevant tag
+	 */
+	do {
+		tag  = dwarf_tag(die);
+		name = dwarf_diename(die);
+
+		if ((tag != rtag) || (!name)
+		    || strcmp(name, dwarf_info.decl_name))
+			continue;
+
+		src_name = (char *)dwarf_decl_file(die);
+
+		if (!src_name)
+			break;
+
+	} while (!dwarf_siblingof(die, die));
+
+	if (!src_name)
+		return;
+
+	/*
+	 * Found the demanded one.
+	 */
+	strncpy(dwarf_info.src_name, src_name, LEN_SRCFILE);
+
+	*found = TRUE;
+}
+
+static void
 search_symbol(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 {
 	int tag;
@@ -1250,6 +1303,9 @@ search_die_tree(Dwarf *dwarfd, Dwarf_Die
 
 	else if (is_search_symbol(dwarf_info.cmd))
 		search_symbol(dwarfd, die, found);
+
+	else if (is_search_srcfile(dwarf_info.cmd))
+		search_srcfile(dwarfd, die, found);
 }
 
 int
@@ -1390,6 +1446,23 @@ get_array_length(char *name01, char *nam
 	return dwarf_info.array_length;
 }
 
+/*
+ * Get the source filename.
+ */
+int
+get_source_filename(char *decl_name, char *src_name, int cmd)
+{
+	dwarf_info.cmd = cmd;
+	dwarf_info.decl_name = decl_name;
+
+	if (!get_debug_info())
+		return FALSE;
+
+	strncpy(src_name, dwarf_info.src_name, LEN_SRCFILE);
+
+	return TRUE;
+}
+
 int
 get_symbol_info(struct DumpInfo *info)
 {
@@ -1420,174 +1493,6 @@ get_symbol_info(struct DumpInfo *info)
 	return TRUE;
 }
 
-
-int
-read_kernel_config(struct DumpInfo *info)
-{
-	int ii, ret, end, found=0;
-	unsigned long size, bufsz;
-	char *pos, *ln, *buf, *head, *tail, *val, *uncomp;
-	char line[512];
-	z_stream stream;
-	unsigned long kernel_config_data;
-
-	kernel_config_data = get_symbol_addr(info, "kernel_config_data");
-	if (kernel_config_data <= 0) {
-		ERRMSG("Can't read kernel cofiguration from kernel binary");
-		return FALSE;
-	}
-
-	/* We don't know how large IKCONFIG is, so we start with
-	 * 32k, if we can't find MAGIC_END assume we didn't read
-	 * enough, double it and try again.
-	 */
-	ii = 32;
-
-again:
-	size = ii * 1024;
-
-	if ((buf = (char *)malloc(size)) == NULL) {
-		MSG("cannot malloc IKCONFIG input buffer\n");
-		return FALSE;
-	}
-
-        if (!readmem(info, kernel_config_data, buf, size)) {
-		MSG("cannot read kernel_config_data\n");
-		goto out2;
-	}
-
-	/* Find the start */
-	if (strstr(buf, MAGIC_START))
-		head = buf + MAGIC_SIZE + 10; /* skip past MAGIC_START and gzip header */
-	else {
-		MSG("could not find MAGIC_START!\n");
-		goto out2;
-	}
-
-	tail = head;
-
-	end = strlen(MAGIC_END);
-
-	/* Find the end*/
-	while (tail < (buf + (size - 1))) {
-
-		if (strncmp(tail, MAGIC_END, end)==0) {
-			found = 1;
-			break;
-		}
-		tail++;
-	}
-
-	if (found) {
-		bufsz = tail - head;
-		size = 10 * bufsz;
-		if ((uncomp = (char *)malloc(size)) == NULL) {
-			MSG("cannot malloc IKCONFIG output buffer\n");
-			goto out2;
-		}
-	} else {
-		if (ii > 512) {
-			MSG("could not find MAGIC_END!\n");
-			goto out2;
-		} else {
-			free(buf);
-			ii *= 2;
-			goto again;
-		}
-	}
-
-
-	/* initialize zlib */
-	stream.next_in = (Bytef *)head;
-	stream.avail_in = (uInt)bufsz;
-
-	stream.next_out = (Bytef *)uncomp;
-	stream.avail_out = (uInt)size;
-
-	stream.zalloc = NULL;
-	stream.zfree = NULL;
-	stream.opaque = NULL;
-
-	ret = inflateInit2(&stream, -MAX_WBITS);
-	if (ret != Z_OK) {
-		ERRMSG("error while reading kernel config, inflateInit2 "
-				"returned %d\n", ret);
-		goto out1;
-	}
-
-	ret = inflate(&stream, Z_FINISH);
-
-	if (ret != Z_STREAM_END) {
-		inflateEnd(&stream);
-		if (ret == Z_NEED_DICT ||
-		   (ret == Z_BUF_ERROR && stream.avail_in == 0)) {
-			ERRMSG("error while reading kernel config, stream.avail_in = 0,"
-					"inflate returned %d\n", ret);
-			goto out1;
-		}
-		ERRMSG("error while reading kernel config, inflate returned"
-				"with %d\n", ret);
-		goto out1;
-	}
-	size = stream.total_out;
-
-	ret = inflateEnd(&stream);
-
-	pos = uncomp;
-
-	do {
-		ret = sscanf(pos, "%511[^\n]\n%n", line, &ii);
-		if (ret > 0) {
-			pos += ii;
-
-			ln = line;
-
-			/* skip leading whitespace */
-			while (is_blank(*ln))
-				ln++;
-
-			/* skip comments */
-			if (*ln == '#')
-				continue;
-
-			/* Find '=' */
-			if ((head = strchr(ln, '=')) != NULL) {
-				*head = '\0';
-				val = head + 1;
-
-				head--;
-
-				/* skip trailing whitespace */
-				while (is_blank(*head)) {
-					*head = '\0';
-					head--;
-				}
-
-				/* skip whitespace */
-				while (is_blank(*val))
-					val++;
-
-			} else /* Bad line, skip it */
-				continue;
-
-			if (strcmp(ln, "CONFIG_PGTABLE_4") == 0)
-				info->mem_flags |= MEMORY_4LAYER_PAGETABLE;
-		}
-	} while (ret > 0);
-
-
-	free(uncomp);
-	free(buf);
-	return TRUE;
-
-out1:
-	free(uncomp);
-out2:
-	free(buf);
-
-	return FALSE;
-}
-
 int
 get_structure_info(struct DumpInfo *info)
 {
@@ -1653,6 +1558,14 @@ get_structure_info(struct DumpInfo *info
 }
 
 int
+get_srcfile_info(struct DumpInfo *info)
+{
+	TYPEDEF_SRCFILE_INIT(pud_t, "pud_t");
+
+	return TRUE;
+}
+
+int
 is_sparsemem_extreme(struct DumpInfo *info)
 {
 	if (ARRAY_LENGTH(mem_section)
@@ -1722,6 +1635,9 @@ generate_config(struct DumpInfo *info)
 	if (!get_structure_info(info))
 		return FALSE;
 
+	if (!get_srcfile_info(info))
+		return FALSE;
+
 	if ((SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)
 	    && (SYMBOL(init_uts_ns) == NOT_FOUND_SYMBOL)) {
 		ERRMSG("Can't get the symbol of system_utsname.\n");
@@ -1807,6 +1723,11 @@ generate_config(struct DumpInfo *info)
 
 	WRITE_ARRAY_LENGTH("zone.free_area", zone.free_area);
 
+	/*
+	 * write the source file of 1st kernel
+	 */
+	WRITE_SRCFILE("pud_t", pud_t);
+
 	return TRUE;
 }
 
@@ -1920,6 +1841,30 @@ read_config_structure(struct DumpInfo *i
 }
 
 int
+read_config_string(struct DumpInfo *info, char *str_in, char *str_out)
+{
+	char buf[BUFSIZE_FGETS];
+	unsigned int i;
+
+	if (fseek(info->file_configfile, 0, SEEK_SET) < 0) {
+		ERRMSG("Can't seek the config file(%s). %s\n",
+		    info->name_configfile, strerror(errno));
+		return FALSE;
+	}
+
+	while (fgets(buf, BUFSIZE_FGETS, info->file_configfile)) {
+		i = strlen(buf);
+		if (buf[i - 1] == '\n')
+			buf[i - 1] = '\0';
+		if (strncmp(buf, str_in, strlen(str_in)) == 0) {
+			strncpy(str_out, buf + strlen(str_in), BUFSIZE_FGETS - strlen(str_in));
+			break;
+		}
+	}
+	return TRUE;
+}
+
+int
 read_config(struct DumpInfo *info)
 {
 	if (!read_config_basic_info(info))
@@ -1974,6 +1919,8 @@ read_config(struct DumpInfo *info)
 	READ_ARRAY_LENGTH("mem_section", mem_section);
 	READ_ARRAY_LENGTH("zone.free_area", zone.free_area);
 
+	READ_SRCFILE("pud_t", pud_t);
+
 	return TRUE;
 }
 
@@ -2455,6 +2402,9 @@ initial(struct DumpInfo *info)
 		}
 		if (!get_structure_info(info))
 			return FALSE;
+
+		if (!get_srcfile_info(info))
+			return FALSE;
 	}
 
 	if (!get_machdep_kernel_start(info))
@@ -2463,9 +2413,6 @@ initial(struct DumpInfo *info)
 	if (!check_release(info))
 		return FALSE;
 
-	if (!read_kernel_config(info))
-		return FALSE;
-
 	if (!get_machdep_info(info))
 		return FALSE;
 
diff -puN makedumpfile.org/makedumpfile.h makedumpfile/makedumpfile.h
--- makedumpfile.org/makedumpfile.h	2007-05-21 19:20:06.000000000 +0900
+++ makedumpfile/makedumpfile.h	2007-05-21 19:36:43.000000000 +0900
@@ -69,14 +69,7 @@ enum {
  * Flags
  */
 #define MEMORY_4LAYER_PAGETABLE	(1 << 0)
-
-/*
- * For kernel configuration
- */
-#define MAGIC_START  "IKCFG_ST"
-#define MAGIC_END    "IKCFG_ED"
-#define MAGIC_SIZE   (sizeof(MAGIC_START) - 1)
-
+#define MEMORY_3LAYER_PAGETABLE	(1 << 1)
 
 static inline int
 test_bit(int nr, unsigned long addr)
@@ -87,12 +80,6 @@ test_bit(int nr, unsigned long addr)
 	return ((mask & addr) != 0);
 }
 
-static inline int
-is_blank(int c)
-{
-	return c == ' ' || c == '\t';
-}
-
 #define isLRU(flags)		test_bit(PG_lru, flags)
 #define isPrivate(flags)	test_bit(PG_private, flags)
 #define isSwapCache(flags)	test_bit(PG_swapcache, flags)
@@ -288,6 +275,29 @@ do { \
 } while (0)
 
 /*
+ * for source file name
+ */
+#define SRCFILE(X)		(srcfile_table.X)
+#define	TYPEDEF_SRCFILE_INIT(decl_name, str_decl_name) \
+do { \
+	get_source_filename(str_decl_name, SRCFILE(decl_name), DWARF_INFO_GET_TYPEDEF_SRCNAME); \
+} while (0)
+
+#define WRITE_SRCFILE(str_decl_name, decl_name) \
+do { \
+	if (strlen(SRCFILE(decl_name))) { \
+		fprintf(info->file_configfile, "%s%s\n", \
+		    STR_SRCFILE(str_decl_name), SRCFILE(decl_name)); \
+	} \
+} while (0)
+
+#define READ_SRCFILE(str_decl_name, decl_name) \
+do { \
+	if (!read_config_string(info, STR_SRCFILE(str_decl_name), SRCFILE(decl_name))) \
+		return FALSE; \
+} while (0)
+
+/*
  * kernel version
  */
 #define VERSION_2_6_15		(15)
@@ -309,6 +319,7 @@ do { \
 #define STR_SIZE(X)	"SIZE("X")="
 #define STR_OFFSET(X)	"OFFSET("X")="
 #define STR_LENGTH(X)	"LENGTH("X")="
+#define STR_SRCFILE(X)	"SRCFILE("X")="
 
 /*
  * common value
@@ -412,6 +423,12 @@ do { \
 #define MASK_PUD   	((1UL << REGION_SHIFT) - 1) & (~((1UL << PUD_SHIFT) - 1))
 #define MASK_PGD_4L	((1UL << REGION_SHIFT) - 1) & (~((1UL << PGDIR_SHIFT_4L) - 1))
 
+/*
+ * Key for distinguishing PGTABLE_3L or PGTABLE_4L.
+ */
+#define STR_PUD_T_3L	"include/asm-generic/pgtable-nopud.h"
+#define STR_PUD_T_4L	"include/asm/page.h"
+
 #endif          /* ia64 */
 
 /*
@@ -679,10 +696,19 @@ struct array_table {
 	} zone;
 };
 
+#define LEN_SRCFILE				(50)
+struct srcfile_table {
+	/*
+	 * typedef
+	 */
+	char	pud_t[LEN_SRCFILE];
+};
+
 extern struct symbol_table	symbol_table;
 extern struct size_table	size_table;
 extern struct offset_table	offset_table;
 extern struct array_table	array_table;
+extern struct srcfile_table	srcfile_table;
 
 /*
  * Debugging information
@@ -693,6 +719,7 @@ extern struct array_table	array_table;
 #define DWARF_INFO_GET_MEMBER_ARRAY_LENGTH	(4)
 #define DWARF_INFO_GET_SYMBOL_ARRAY_LENGTH	(5)
 #define DWARF_INFO_CHECK_SYMBOL_ARRAY_TYPE	(6)
+#define DWARF_INFO_GET_TYPEDEF_SRCNAME		(7)
 
 struct dwarf_info {
 	unsigned int	cmd;		/* IN */
@@ -701,14 +728,17 @@ struct dwarf_info {
 	char	*struct_name;		/* IN */
 	char	*symbol_name;		/* IN */
 	char	*member_name;		/* IN */
+	char	*decl_name;		/* IN */
 	long	struct_size;		/* OUT */
 	long	member_offset;		/* OUT */
 	long	array_length;		/* OUT */
+	char	src_name[LEN_SRCFILE];	/* OUT */
 };
 
 extern struct dwarf_info	dwarf_info;
 
 int readmem();
+off_t paddr_to_offset();
 unsigned long long vaddr_to_paddr();
 unsigned long long paddr_to_vaddr();
 
_



More information about the kexec mailing list