[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