All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
@ 2011-05-17 20:01 Mahesh J Salgaonkar
  2011-07-15  9:35 ` Ken'ichi Ohmichi
  2011-07-25  8:11 ` Ken'ichi Ohmichi
  0 siblings, 2 replies; 16+ messages in thread
From: Mahesh J Salgaonkar @ 2011-05-17 20:01 UTC (permalink / raw)
  To: kexec, Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, Mahesh Salgaonkar,
	Dave Anderson, Prerna Saxena, Reinhard

From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

So far makedumpfile implementation does not have to deal with module
debuginfo files. In order to support filtering of kernel module data,
it needs to read dwarf information from module debuginfo files. The linux
kernel module debuginfo are of ET_REL type and requires relocation to be
applied in order to get the dwarf information.

This patch uses dwfl_* API's to make the code relocation-aware while
loading module debuginfo files. It also uses dwfl_* API to search module
debuginfo files installed under default debuginfo path.

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Prerna Saxena <prerna@linux.vnet.ibm.com>
---

 makedumpfile.c |  261 +++++++++++++++++++++++++++++++++++++++++++++-----------
 makedumpfile.h |    7 ++
 2 files changed, 216 insertions(+), 52 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index f136eba..2274b18 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1372,6 +1372,146 @@ get_elf_info(void)
 	return TRUE;
 }
 
+static int
+process_module (Dwfl_Module *dwflmod,
+		void **userdata __attribute__ ((unused)),
+		const char *name __attribute__ ((unused)),
+		Dwarf_Addr base __attribute__ ((unused)),
+		void *arg)
+{
+	const char *fname, *mod_name, *debugfile;
+	Dwarf_Addr dwbias;
+
+	/* get a debug context descriptor.*/
+	dwarf_info.dwarfd = dwfl_module_getdwarf (dwflmod, &dwbias);
+	dwarf_info.elfd = dwarf_getelf(dwarf_info.dwarfd);
+
+	mod_name = dwfl_module_info(dwflmod, NULL, NULL, NULL, NULL, NULL,
+							&fname, &debugfile);
+
+	if (!strcmp(dwarf_info.module_name, mod_name) &&
+		!dwarf_info.name_debuginfo && debugfile) {
+		/*
+		 * Store the debuginfo filename. Next time we will
+		 * open debuginfo file direclty instead of searching
+		 * for it again.
+		 */
+		dwarf_info.name_debuginfo = strdup(debugfile);
+	}
+
+	return DWARF_CB_OK;
+}
+
+static int
+dwfl_report_module_p(const char *modname, const char *filename)
+{
+	if (filename && !strcmp(modname, dwarf_info.module_name))
+		return 1;
+	return 0;
+}
+
+static void
+clean_dwfl_info(void)
+{
+	if (dwarf_info.dwfl)
+		dwfl_end(dwarf_info.dwfl);
+
+	dwarf_info.dwfl = NULL;
+	dwarf_info.dwarfd = NULL;
+	dwarf_info.elfd = NULL;
+}
+
+/*
+ * Intitialize the dwarf info.
+ * Linux kernel module debuginfo are of ET_REL (relocatable) type. The old
+ * implementation of get_debug_info() function that reads the debuginfo was
+ * not relocation-aware and hence could not read the dwarf info properly
+ * from module debuginfo.
+ *
+ * This function uses dwfl API's to apply relocation before reading the
+ * dwarf information from module debuginfo.
+ * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
+ * after applying relocation to module debuginfo.
+ */
+static int
+init_dwarf_info(void)
+{
+	Dwfl *dwfl = NULL;
+	int dwfl_fd = -1;
+	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
+	static const Dwfl_Callbacks callbacks = {
+		.section_address = dwfl_offline_section_address,
+		.find_debuginfo = dwfl_standard_find_debuginfo,
+		.debuginfo_path = &debuginfo_path,
+	};
+
+	dwarf_info.elfd = NULL;
+	dwarf_info.dwarfd = NULL;
+
+	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
+		ERRMSG("Can't create a handle for a new dwfl session.\n");
+		return FALSE;
+	}
+
+	if (dwarf_info.name_debuginfo) {
+		/* We have absolute path for debuginfo file, use it directly
+		 * instead of searching it through
+		 * dwfl_linux_kernel_report_offline() call.
+		 *
+		 * Open the debuginfo file if it is not already open.
+		 */
+		if (dwarf_info.fd_debuginfo < 0)
+			dwarf_info.fd_debuginfo =
+				open(dwarf_info.name_debuginfo, O_RDONLY);
+
+		dwfl_fd = dup(dwarf_info.fd_debuginfo);
+		if (dwfl_fd < 0) {
+			ERRMSG("Failed to get a duplicate handle for"
+				" debuginfo.\n");
+			goto err_out;
+		}
+	}
+	if (dwarf_info.fd_debuginfo > 0) {
+		if (dwfl_report_offline(dwfl, dwarf_info.module_name,
+				dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
+			ERRMSG("Failed reading %s: %s\n",
+				dwarf_info.name_debuginfo, dwfl_errmsg (-1));
+			/* dwfl_fd is consumed on success, not on failure */
+			close(dwfl_fd);
+			goto err_out;
+		}
+	}
+	else if (dwfl_linux_kernel_report_offline(dwfl,
+						info->system_utsname.release,
+						&dwfl_report_module_p)) {
+		ERRMSG("Can't get Module debuginfo for module '%s'\n",
+					dwarf_info.module_name);
+		goto err_out;
+	}
+	dwfl_report_end(dwfl, NULL, NULL);
+
+	dwfl_getmodules(dwfl, &process_module, NULL, 0);
+
+	if (dwarf_info.elfd == NULL) {
+		ERRMSG("Can't get first elf header of %s.\n",
+		    dwarf_info.name_debuginfo);
+		goto err_out;
+	}
+
+	if (dwarf_info.dwarfd == NULL) {
+		ERRMSG("Can't get debug context descriptor for %s.\n",
+		    dwarf_info.name_debuginfo);
+		goto err_out;
+	}
+	dwarf_info.dwfl = dwfl;
+	return TRUE;
+err_out:
+	if (dwfl)
+		dwfl_end(dwfl);
+
+	return FALSE;
+}
+
 unsigned long long
 get_symbol_addr(char *symname)
 {
@@ -1383,18 +1523,12 @@ get_symbol_addr(char *symname)
 	Elf_Data *data = NULL;
 	Elf_Scn *scn = NULL;
 	char *sym_name = NULL;
-	const off_t failed = (off_t)-1;
 
-	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
-		ERRMSG("Can't seek the kernel file(%s). %s\n",
-		    dwarf_info.name_debuginfo, strerror(errno));
-		return NOT_FOUND_SYMBOL;
-	}
-	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
-		ERRMSG("Can't get first elf header of %s.\n",
-		    dwarf_info.name_debuginfo);
-		return NOT_FOUND_SYMBOL;
-	}
+	if (!init_dwarf_info())
+		return 0;
+
+	elfd = dwarf_info.elfd;
+
 	while ((scn = elf_nextscn(elfd, scn)) != NULL) {
 		if (gelf_getshdr(scn, &shdr) == NULL) {
 			ERRMSG("Can't get section header.\n");
@@ -1431,8 +1565,7 @@ get_symbol_addr(char *symname)
 		}
 	}
 out:
-	if (elfd != NULL)
-		elf_end(elfd);
+	clean_dwfl_info();
 
 	return symbol;
 }
@@ -1449,18 +1582,12 @@ get_next_symbol_addr(char *symname)
 	Elf_Data *data = NULL;
 	Elf_Scn *scn = NULL;
 	char *sym_name = NULL;
-	const off_t failed = (off_t)-1;
 
-	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
-		ERRMSG("Can't seek the kernel file(%s). %s\n",
-		    dwarf_info.name_debuginfo, strerror(errno));
-		return NOT_FOUND_SYMBOL;
-	}
-	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
-		ERRMSG("Can't get first elf header of %s.\n",
-		    dwarf_info.name_debuginfo);
-		return NOT_FOUND_SYMBOL;
-	}
+	if (!init_dwarf_info())
+		return 0;
+
+	elfd = dwarf_info.elfd;
+
 	while ((scn = elf_nextscn(elfd, scn)) != NULL) {
 		if (gelf_getshdr(scn, &shdr) == NULL) {
 			ERRMSG("Can't get section header.\n");
@@ -1522,8 +1649,7 @@ get_next_symbol_addr(char *symname)
 		}
 	}
 out:
-	if (elfd != NULL)
-		elf_end(elfd);
+	clean_dwfl_info();
 
 	return next_symbol;
 }
@@ -2034,24 +2160,15 @@ get_debug_info(void)
 	Elf_Scn *scn = NULL;
 	GElf_Shdr scnhdr_mem, *scnhdr = NULL;
 	Dwarf_Die cu_die;
-	const off_t failed = (off_t)-1;
 
 	int ret = FALSE;
 
-	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
-		ERRMSG("Can't seek the kernel file(%s). %s\n",
-		    dwarf_info.name_debuginfo, strerror(errno));
-		return FALSE;
-	}
-	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ_MMAP, NULL))) {
-		ERRMSG("Can't get first elf header of %s.\n",
-		    dwarf_info.name_debuginfo);
+	if (!init_dwarf_info())
 		return FALSE;
-	}
-	if (!(dwarfd = dwarf_begin_elf(elfd, DWARF_C_READ, NULL))) {
-		ERRMSG("Can't create a handle for a new debug session.\n");
-		goto out;
-	}
+
+	elfd = dwarf_info.elfd;
+	dwarfd = dwarf_info.dwarfd;
+
 	if (elf_getshstrndx(elfd, &shstrndx) < 0) {
 		ERRMSG("Can't get the section index of the string table.\n");
 		goto out;
@@ -2088,10 +2205,7 @@ get_debug_info(void)
 	}
 	ret = TRUE;
 out:
-	if (dwarfd != NULL)
-		dwarf_end(dwarfd);
-	if (elfd != NULL)
-		elf_end(elfd);
+	clean_dwfl_info();
 
 	return ret;
 }
@@ -2448,14 +2562,58 @@ get_mem_type(void)
 	return ret;
 }
 
+/*
+ * Set the dwarf_info with kernel/module debuginfo file information.
+ */
+int
+set_dwarf_debuginfo(char *mod_name, char *name_debuginfo, int fd_debuginfo)
+{
+	if (!mod_name)
+		return FALSE;
+	if (dwarf_info.module_name && !strcmp(dwarf_info.module_name, mod_name))
+		return TRUE;
+
+	/* Switching to different module.
+	 *
+	 * Close the file descriptor if previous module is != kernel and
+	 * xen-syms. The reason is, vmlinux file will always be supplied
+	 * by user and code to open/close kernel debuginfo file already
+	 * in place. The module debuginfo files are opened only if '--config'
+	 * option is used. This helps not to break the existing functionlity
+	 * if called without '--config' option.
+	 */
+
+	if (dwarf_info.module_name
+			&& strcmp(dwarf_info.module_name, "vmlinux")
+			&& strcmp(dwarf_info.module_name, "xen-syms")) {
+		if (dwarf_info.fd_debuginfo > 0)
+			close(dwarf_info.fd_debuginfo);
+		if (dwarf_info.name_debuginfo)
+			free(dwarf_info.name_debuginfo);
+	}
+	dwarf_info.fd_debuginfo = fd_debuginfo;
+	dwarf_info.name_debuginfo = name_debuginfo;
+	dwarf_info.module_name = mod_name;
+
+	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
+		!strcmp(dwarf_info.module_name, "xen-syms"))
+		return TRUE;
+
+	/* check to see whether module debuginfo is available */
+	if (!init_dwarf_info())
+		return FALSE;
+	else
+		clean_dwfl_info();
+	return TRUE;
+}
+
 int
 generate_vmcoreinfo(void)
 {
 	if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
 		return FALSE;
 
-	dwarf_info.fd_debuginfo   = info->fd_vmlinux;
-	dwarf_info.name_debuginfo = info->name_vmlinux;
+	set_dwarf_debuginfo("vmlinux", info->name_vmlinux, info->fd_vmlinux);
 
 	if (!get_symbol_info())
 		return FALSE;
@@ -3888,8 +4046,8 @@ initial(void)
 	 * Get the debug information for analysis from the kernel file
 	 */
 	} else if (info->name_vmlinux) {
-		dwarf_info.fd_debuginfo   = info->fd_vmlinux;
-		dwarf_info.name_debuginfo = info->name_vmlinux;
+		set_dwarf_debuginfo("vmlinux", info->name_vmlinux,
+						info->fd_vmlinux);
 
 		if (!get_symbol_info())
 			return FALSE;
@@ -6552,8 +6710,7 @@ generate_vmcoreinfo_xen(void)
 		ERRMSG("Can't get the size of page.\n");
 		return FALSE;
 	}
-	dwarf_info.fd_debuginfo   = info->fd_xen_syms;
-	dwarf_info.name_debuginfo = info->name_xen_syms;
+	set_dwarf_debuginfo("xen-syms", info->name_xen_syms, info->fd_xen_syms);
 
 	if (!get_symbol_info_xen())
 		return FALSE;
@@ -6820,8 +6977,8 @@ initial_xen(void)
 	 * Get the debug information for analysis from the xen-syms file
 	 */
 	} else if (info->name_xen_syms) {
-		dwarf_info.fd_debuginfo   = info->fd_xen_syms;
-		dwarf_info.name_debuginfo = info->name_xen_syms;
+		set_dwarf_debuginfo("xen-syms", info->name_xen_syms,
+							info->fd_xen_syms);
 
 		if (!get_symbol_info_xen())
 			return FALSE;
diff --git a/makedumpfile.h b/makedumpfile.h
index e037f12..3fda754 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -27,6 +27,7 @@
 #include <sys/wait.h>
 #include <zlib.h>
 #include <elfutils/libdw.h>
+#include <elfutils/libdwfl.h>
 #include <libelf.h>
 #include <dwarf.h>
 #include <byteswap.h>
@@ -1177,6 +1178,8 @@ extern struct srcfile_table	srcfile_table;
 /*
  * Debugging information
  */
+#define DEFAULT_DEBUGINFO_PATH	"/usr/lib/debug"
+
 enum {
 	DWARF_INFO_GET_STRUCT_SIZE,
 	DWARF_INFO_GET_MEMBER_OFFSET,
@@ -1194,10 +1197,14 @@ struct dwarf_info {
 	unsigned int	cmd;		/* IN */
 	int	fd_debuginfo;		/* IN */
 	char	*name_debuginfo;	/* IN */
+	char	*module_name;		/* IN */
 	char	*struct_name;		/* IN */
 	char	*symbol_name;		/* IN */
 	char	*member_name;		/* IN */
 	char	*enum_name;		/* IN */
+	Elf	*elfd;			/* OUT */
+	Dwarf	*dwarfd;		/* OUT */
+	Dwfl	*dwfl;			/* OUT */
 	long	struct_size;		/* OUT */
 	long	member_offset;		/* OUT */
 	long	array_length;		/* OUT */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-05-17 20:01 [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo Mahesh J Salgaonkar
@ 2011-07-15  9:35 ` Ken'ichi Ohmichi
  2011-07-15 10:21   ` Mahesh Jagannath Salgaonkar
  2011-07-25  8:11 ` Ken'ichi Ohmichi
  1 sibling, 1 reply; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-15  9:35 UTC (permalink / raw)
  To: Mahesh J Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

On my machine (RHEL5 x86_64), I cannot compile makedumpfile with this patch.
I guess that it is due to old elfutils of my machine, and I am trying this
problem by newer elfutils.

I'd like to get some hints, so can you tell me your environment ?
RHEL6 x86_64 ?


Thanks
Ken'ichi Ohmichi

On Wed, 18 May 2011 01:31:01 +0530
Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> 
> So far makedumpfile implementation does not have to deal with module
> debuginfo files. In order to support filtering of kernel module data,
> it needs to read dwarf information from module debuginfo files. The linux
> kernel module debuginfo are of ET_REL type and requires relocation to be
> applied in order to get the dwarf information.
> 
> This patch uses dwfl_* API's to make the code relocation-aware while
> loading module debuginfo files. It also uses dwfl_* API to search module
> debuginfo files installed under default debuginfo path.
> 
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> Signed-off-by: Prerna Saxena <prerna@linux.vnet.ibm.com>
> ---
> 
>  makedumpfile.c |  261 +++++++++++++++++++++++++++++++++++++++++++++-----------
>  makedumpfile.h |    7 ++
>  2 files changed, 216 insertions(+), 52 deletions(-)
> 
> diff --git a/makedumpfile.c b/makedumpfile.c
> index f136eba..2274b18 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -1372,6 +1372,146 @@ get_elf_info(void)
>  	return TRUE;
>  }
>  
> +static int
> +process_module (Dwfl_Module *dwflmod,
> +		void **userdata __attribute__ ((unused)),
> +		const char *name __attribute__ ((unused)),
> +		Dwarf_Addr base __attribute__ ((unused)),
> +		void *arg)
> +{
> +	const char *fname, *mod_name, *debugfile;
> +	Dwarf_Addr dwbias;
> +
> +	/* get a debug context descriptor.*/
> +	dwarf_info.dwarfd = dwfl_module_getdwarf (dwflmod, &dwbias);
> +	dwarf_info.elfd = dwarf_getelf(dwarf_info.dwarfd);
> +
> +	mod_name = dwfl_module_info(dwflmod, NULL, NULL, NULL, NULL, NULL,
> +							&fname, &debugfile);
> +
> +	if (!strcmp(dwarf_info.module_name, mod_name) &&
> +		!dwarf_info.name_debuginfo && debugfile) {
> +		/*
> +		 * Store the debuginfo filename. Next time we will
> +		 * open debuginfo file direclty instead of searching
> +		 * for it again.
> +		 */
> +		dwarf_info.name_debuginfo = strdup(debugfile);
> +	}
> +
> +	return DWARF_CB_OK;
> +}
> +
> +static int
> +dwfl_report_module_p(const char *modname, const char *filename)
> +{
> +	if (filename && !strcmp(modname, dwarf_info.module_name))
> +		return 1;
> +	return 0;
> +}
> +
> +static void
> +clean_dwfl_info(void)
> +{
> +	if (dwarf_info.dwfl)
> +		dwfl_end(dwarf_info.dwfl);
> +
> +	dwarf_info.dwfl = NULL;
> +	dwarf_info.dwarfd = NULL;
> +	dwarf_info.elfd = NULL;
> +}
> +
> +/*
> + * Intitialize the dwarf info.
> + * Linux kernel module debuginfo are of ET_REL (relocatable) type. The old
> + * implementation of get_debug_info() function that reads the debuginfo was
> + * not relocation-aware and hence could not read the dwarf info properly
> + * from module debuginfo.
> + *
> + * This function uses dwfl API's to apply relocation before reading the
> + * dwarf information from module debuginfo.
> + * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
> + * after applying relocation to module debuginfo.
> + */
> +static int
> +init_dwarf_info(void)
> +{
> +	Dwfl *dwfl = NULL;
> +	int dwfl_fd = -1;
> +	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
> +	static const Dwfl_Callbacks callbacks = {
> +		.section_address = dwfl_offline_section_address,
> +		.find_debuginfo = dwfl_standard_find_debuginfo,
> +		.debuginfo_path = &debuginfo_path,
> +	};
> +
> +	dwarf_info.elfd = NULL;
> +	dwarf_info.dwarfd = NULL;
> +
> +	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
> +		ERRMSG("Can't create a handle for a new dwfl session.\n");
> +		return FALSE;
> +	}
> +
> +	if (dwarf_info.name_debuginfo) {
> +		/* We have absolute path for debuginfo file, use it directly
> +		 * instead of searching it through
> +		 * dwfl_linux_kernel_report_offline() call.
> +		 *
> +		 * Open the debuginfo file if it is not already open.
> +		 */
> +		if (dwarf_info.fd_debuginfo < 0)
> +			dwarf_info.fd_debuginfo =
> +				open(dwarf_info.name_debuginfo, O_RDONLY);
> +
> +		dwfl_fd = dup(dwarf_info.fd_debuginfo);
> +		if (dwfl_fd < 0) {
> +			ERRMSG("Failed to get a duplicate handle for"
> +				" debuginfo.\n");
> +			goto err_out;
> +		}
> +	}
> +	if (dwarf_info.fd_debuginfo > 0) {
> +		if (dwfl_report_offline(dwfl, dwarf_info.module_name,
> +				dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
> +			ERRMSG("Failed reading %s: %s\n",
> +				dwarf_info.name_debuginfo, dwfl_errmsg (-1));
> +			/* dwfl_fd is consumed on success, not on failure */
> +			close(dwfl_fd);
> +			goto err_out;
> +		}
> +	}
> +	else if (dwfl_linux_kernel_report_offline(dwfl,
> +						info->system_utsname.release,
> +						&dwfl_report_module_p)) {
> +		ERRMSG("Can't get Module debuginfo for module '%s'\n",
> +					dwarf_info.module_name);
> +		goto err_out;
> +	}
> +	dwfl_report_end(dwfl, NULL, NULL);
> +
> +	dwfl_getmodules(dwfl, &process_module, NULL, 0);
> +
> +	if (dwarf_info.elfd == NULL) {
> +		ERRMSG("Can't get first elf header of %s.\n",
> +		    dwarf_info.name_debuginfo);
> +		goto err_out;
> +	}
> +
> +	if (dwarf_info.dwarfd == NULL) {
> +		ERRMSG("Can't get debug context descriptor for %s.\n",
> +		    dwarf_info.name_debuginfo);
> +		goto err_out;
> +	}
> +	dwarf_info.dwfl = dwfl;
> +	return TRUE;
> +err_out:
> +	if (dwfl)
> +		dwfl_end(dwfl);
> +
> +	return FALSE;
> +}
> +
>  unsigned long long
>  get_symbol_addr(char *symname)
>  {
> @@ -1383,18 +1523,12 @@ get_symbol_addr(char *symname)
>  	Elf_Data *data = NULL;
>  	Elf_Scn *scn = NULL;
>  	char *sym_name = NULL;
> -	const off_t failed = (off_t)-1;
>  
> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
> -		    dwarf_info.name_debuginfo, strerror(errno));
> -		return NOT_FOUND_SYMBOL;
> -	}
> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
> -		ERRMSG("Can't get first elf header of %s.\n",
> -		    dwarf_info.name_debuginfo);
> -		return NOT_FOUND_SYMBOL;
> -	}
> +	if (!init_dwarf_info())
> +		return 0;
> +
> +	elfd = dwarf_info.elfd;
> +
>  	while ((scn = elf_nextscn(elfd, scn)) != NULL) {
>  		if (gelf_getshdr(scn, &shdr) == NULL) {
>  			ERRMSG("Can't get section header.\n");
> @@ -1431,8 +1565,7 @@ get_symbol_addr(char *symname)
>  		}
>  	}
>  out:
> -	if (elfd != NULL)
> -		elf_end(elfd);
> +	clean_dwfl_info();
>  
>  	return symbol;
>  }
> @@ -1449,18 +1582,12 @@ get_next_symbol_addr(char *symname)
>  	Elf_Data *data = NULL;
>  	Elf_Scn *scn = NULL;
>  	char *sym_name = NULL;
> -	const off_t failed = (off_t)-1;
>  
> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
> -		    dwarf_info.name_debuginfo, strerror(errno));
> -		return NOT_FOUND_SYMBOL;
> -	}
> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
> -		ERRMSG("Can't get first elf header of %s.\n",
> -		    dwarf_info.name_debuginfo);
> -		return NOT_FOUND_SYMBOL;
> -	}
> +	if (!init_dwarf_info())
> +		return 0;
> +
> +	elfd = dwarf_info.elfd;
> +
>  	while ((scn = elf_nextscn(elfd, scn)) != NULL) {
>  		if (gelf_getshdr(scn, &shdr) == NULL) {
>  			ERRMSG("Can't get section header.\n");
> @@ -1522,8 +1649,7 @@ get_next_symbol_addr(char *symname)
>  		}
>  	}
>  out:
> -	if (elfd != NULL)
> -		elf_end(elfd);
> +	clean_dwfl_info();
>  
>  	return next_symbol;
>  }
> @@ -2034,24 +2160,15 @@ get_debug_info(void)
>  	Elf_Scn *scn = NULL;
>  	GElf_Shdr scnhdr_mem, *scnhdr = NULL;
>  	Dwarf_Die cu_die;
> -	const off_t failed = (off_t)-1;
>  
>  	int ret = FALSE;
>  
> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
> -		    dwarf_info.name_debuginfo, strerror(errno));
> -		return FALSE;
> -	}
> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ_MMAP, NULL))) {
> -		ERRMSG("Can't get first elf header of %s.\n",
> -		    dwarf_info.name_debuginfo);
> +	if (!init_dwarf_info())
>  		return FALSE;
> -	}
> -	if (!(dwarfd = dwarf_begin_elf(elfd, DWARF_C_READ, NULL))) {
> -		ERRMSG("Can't create a handle for a new debug session.\n");
> -		goto out;
> -	}
> +
> +	elfd = dwarf_info.elfd;
> +	dwarfd = dwarf_info.dwarfd;
> +
>  	if (elf_getshstrndx(elfd, &shstrndx) < 0) {
>  		ERRMSG("Can't get the section index of the string table.\n");
>  		goto out;
> @@ -2088,10 +2205,7 @@ get_debug_info(void)
>  	}
>  	ret = TRUE;
>  out:
> -	if (dwarfd != NULL)
> -		dwarf_end(dwarfd);
> -	if (elfd != NULL)
> -		elf_end(elfd);
> +	clean_dwfl_info();
>  
>  	return ret;
>  }
> @@ -2448,14 +2562,58 @@ get_mem_type(void)
>  	return ret;
>  }
>  
> +/*
> + * Set the dwarf_info with kernel/module debuginfo file information.
> + */
> +int
> +set_dwarf_debuginfo(char *mod_name, char *name_debuginfo, int fd_debuginfo)
> +{
> +	if (!mod_name)
> +		return FALSE;
> +	if (dwarf_info.module_name && !strcmp(dwarf_info.module_name, mod_name))
> +		return TRUE;
> +
> +	/* Switching to different module.
> +	 *
> +	 * Close the file descriptor if previous module is != kernel and
> +	 * xen-syms. The reason is, vmlinux file will always be supplied
> +	 * by user and code to open/close kernel debuginfo file already
> +	 * in place. The module debuginfo files are opened only if '--config'
> +	 * option is used. This helps not to break the existing functionlity
> +	 * if called without '--config' option.
> +	 */
> +
> +	if (dwarf_info.module_name
> +			&& strcmp(dwarf_info.module_name, "vmlinux")
> +			&& strcmp(dwarf_info.module_name, "xen-syms")) {
> +		if (dwarf_info.fd_debuginfo > 0)
> +			close(dwarf_info.fd_debuginfo);
> +		if (dwarf_info.name_debuginfo)
> +			free(dwarf_info.name_debuginfo);
> +	}
> +	dwarf_info.fd_debuginfo = fd_debuginfo;
> +	dwarf_info.name_debuginfo = name_debuginfo;
> +	dwarf_info.module_name = mod_name;
> +
> +	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
> +		!strcmp(dwarf_info.module_name, "xen-syms"))
> +		return TRUE;
> +
> +	/* check to see whether module debuginfo is available */
> +	if (!init_dwarf_info())
> +		return FALSE;
> +	else
> +		clean_dwfl_info();
> +	return TRUE;
> +}
> +
>  int
>  generate_vmcoreinfo(void)
>  {
>  	if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
>  		return FALSE;
>  
> -	dwarf_info.fd_debuginfo   = info->fd_vmlinux;
> -	dwarf_info.name_debuginfo = info->name_vmlinux;
> +	set_dwarf_debuginfo("vmlinux", info->name_vmlinux, info->fd_vmlinux);
>  
>  	if (!get_symbol_info())
>  		return FALSE;
> @@ -3888,8 +4046,8 @@ initial(void)
>  	 * Get the debug information for analysis from the kernel file
>  	 */
>  	} else if (info->name_vmlinux) {
> -		dwarf_info.fd_debuginfo   = info->fd_vmlinux;
> -		dwarf_info.name_debuginfo = info->name_vmlinux;
> +		set_dwarf_debuginfo("vmlinux", info->name_vmlinux,
> +						info->fd_vmlinux);
>  
>  		if (!get_symbol_info())
>  			return FALSE;
> @@ -6552,8 +6710,7 @@ generate_vmcoreinfo_xen(void)
>  		ERRMSG("Can't get the size of page.\n");
>  		return FALSE;
>  	}
> -	dwarf_info.fd_debuginfo   = info->fd_xen_syms;
> -	dwarf_info.name_debuginfo = info->name_xen_syms;
> +	set_dwarf_debuginfo("xen-syms", info->name_xen_syms, info->fd_xen_syms);
>  
>  	if (!get_symbol_info_xen())
>  		return FALSE;
> @@ -6820,8 +6977,8 @@ initial_xen(void)
>  	 * Get the debug information for analysis from the xen-syms file
>  	 */
>  	} else if (info->name_xen_syms) {
> -		dwarf_info.fd_debuginfo   = info->fd_xen_syms;
> -		dwarf_info.name_debuginfo = info->name_xen_syms;
> +		set_dwarf_debuginfo("xen-syms", info->name_xen_syms,
> +							info->fd_xen_syms);
>  
>  		if (!get_symbol_info_xen())
>  			return FALSE;
> diff --git a/makedumpfile.h b/makedumpfile.h
> index e037f12..3fda754 100644
> --- a/makedumpfile.h
> +++ b/makedumpfile.h
> @@ -27,6 +27,7 @@
>  #include <sys/wait.h>
>  #include <zlib.h>
>  #include <elfutils/libdw.h>
> +#include <elfutils/libdwfl.h>
>  #include <libelf.h>
>  #include <dwarf.h>
>  #include <byteswap.h>
> @@ -1177,6 +1178,8 @@ extern struct srcfile_table	srcfile_table;
>  /*
>   * Debugging information
>   */
> +#define DEFAULT_DEBUGINFO_PATH	"/usr/lib/debug"
> +
>  enum {
>  	DWARF_INFO_GET_STRUCT_SIZE,
>  	DWARF_INFO_GET_MEMBER_OFFSET,
> @@ -1194,10 +1197,14 @@ struct dwarf_info {
>  	unsigned int	cmd;		/* IN */
>  	int	fd_debuginfo;		/* IN */
>  	char	*name_debuginfo;	/* IN */
> +	char	*module_name;		/* IN */
>  	char	*struct_name;		/* IN */
>  	char	*symbol_name;		/* IN */
>  	char	*member_name;		/* IN */
>  	char	*enum_name;		/* IN */
> +	Elf	*elfd;			/* OUT */
> +	Dwarf	*dwarfd;		/* OUT */
> +	Dwfl	*dwfl;			/* OUT */
>  	long	struct_size;		/* OUT */
>  	long	member_offset;		/* OUT */
>  	long	array_length;		/* OUT */
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-15  9:35 ` Ken'ichi Ohmichi
@ 2011-07-15 10:21   ` Mahesh Jagannath Salgaonkar
  2011-07-19  2:27     ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 16+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2011-07-15 10:21 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard

Hi Ken'ichi,

On 07/15/2011 03:05 PM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> On my machine (RHEL5 x86_64), I cannot compile makedumpfile with this patch.
> I guess that it is due to old elfutils of my machine, and I am trying this
> problem by newer elfutils.
> 
> I'd like to get some hints, so can you tell me your environment ?
> RHEL6 x86_64 ?

Yes, I had tested these patches on RHEL6.0 and RHEl6.1 x86_64. As far as
I know RHEL6.0 had elfutils-0.148.

I did not try my patches on RHEL5 x86-64. Let me see if I can get a
RHEL5 x86_64 box to verify.

But in case we can not fix the compilation with RHEL5 environment, do
you think we can go with one of following options:

1. When compiled with older elfutils library, build makedumpfile without
this feature enabled.
2. Make newer elfutils vesion as pre-requisite for future makedumpfile
releases.

What do you think?

Thanks,
-Mahesh.

> 
> 
> Thanks
> Ken'ichi Ohmichi
> 
> On Wed, 18 May 2011 01:31:01 +0530
> Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>>
>> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>>
>> So far makedumpfile implementation does not have to deal with module
>> debuginfo files. In order to support filtering of kernel module data,
>> it needs to read dwarf information from module debuginfo files. The linux
>> kernel module debuginfo are of ET_REL type and requires relocation to be
>> applied in order to get the dwarf information.
>>
>> This patch uses dwfl_* API's to make the code relocation-aware while
>> loading module debuginfo files. It also uses dwfl_* API to search module
>> debuginfo files installed under default debuginfo path.
>>
>> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>> Signed-off-by: Prerna Saxena <prerna@linux.vnet.ibm.com>
>> ---
>>
>>  makedumpfile.c |  261 +++++++++++++++++++++++++++++++++++++++++++++-----------
>>  makedumpfile.h |    7 ++
>>  2 files changed, 216 insertions(+), 52 deletions(-)
>>
>> diff --git a/makedumpfile.c b/makedumpfile.c
>> index f136eba..2274b18 100644
>> --- a/makedumpfile.c
>> +++ b/makedumpfile.c
>> @@ -1372,6 +1372,146 @@ get_elf_info(void)
>>  	return TRUE;
>>  }
>>  
>> +static int
>> +process_module (Dwfl_Module *dwflmod,
>> +		void **userdata __attribute__ ((unused)),
>> +		const char *name __attribute__ ((unused)),
>> +		Dwarf_Addr base __attribute__ ((unused)),
>> +		void *arg)
>> +{
>> +	const char *fname, *mod_name, *debugfile;
>> +	Dwarf_Addr dwbias;
>> +
>> +	/* get a debug context descriptor.*/
>> +	dwarf_info.dwarfd = dwfl_module_getdwarf (dwflmod, &dwbias);
>> +	dwarf_info.elfd = dwarf_getelf(dwarf_info.dwarfd);
>> +
>> +	mod_name = dwfl_module_info(dwflmod, NULL, NULL, NULL, NULL, NULL,
>> +							&fname, &debugfile);
>> +
>> +	if (!strcmp(dwarf_info.module_name, mod_name) &&
>> +		!dwarf_info.name_debuginfo && debugfile) {
>> +		/*
>> +		 * Store the debuginfo filename. Next time we will
>> +		 * open debuginfo file direclty instead of searching
>> +		 * for it again.
>> +		 */
>> +		dwarf_info.name_debuginfo = strdup(debugfile);
>> +	}
>> +
>> +	return DWARF_CB_OK;
>> +}
>> +
>> +static int
>> +dwfl_report_module_p(const char *modname, const char *filename)
>> +{
>> +	if (filename && !strcmp(modname, dwarf_info.module_name))
>> +		return 1;
>> +	return 0;
>> +}
>> +
>> +static void
>> +clean_dwfl_info(void)
>> +{
>> +	if (dwarf_info.dwfl)
>> +		dwfl_end(dwarf_info.dwfl);
>> +
>> +	dwarf_info.dwfl = NULL;
>> +	dwarf_info.dwarfd = NULL;
>> +	dwarf_info.elfd = NULL;
>> +}
>> +
>> +/*
>> + * Intitialize the dwarf info.
>> + * Linux kernel module debuginfo are of ET_REL (relocatable) type. The old
>> + * implementation of get_debug_info() function that reads the debuginfo was
>> + * not relocation-aware and hence could not read the dwarf info properly
>> + * from module debuginfo.
>> + *
>> + * This function uses dwfl API's to apply relocation before reading the
>> + * dwarf information from module debuginfo.
>> + * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
>> + * after applying relocation to module debuginfo.
>> + */
>> +static int
>> +init_dwarf_info(void)
>> +{
>> +	Dwfl *dwfl = NULL;
>> +	int dwfl_fd = -1;
>> +	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
>> +	static const Dwfl_Callbacks callbacks = {
>> +		.section_address = dwfl_offline_section_address,
>> +		.find_debuginfo = dwfl_standard_find_debuginfo,
>> +		.debuginfo_path = &debuginfo_path,
>> +	};
>> +
>> +	dwarf_info.elfd = NULL;
>> +	dwarf_info.dwarfd = NULL;
>> +
>> +	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
>> +		ERRMSG("Can't create a handle for a new dwfl session.\n");
>> +		return FALSE;
>> +	}
>> +
>> +	if (dwarf_info.name_debuginfo) {
>> +		/* We have absolute path for debuginfo file, use it directly
>> +		 * instead of searching it through
>> +		 * dwfl_linux_kernel_report_offline() call.
>> +		 *
>> +		 * Open the debuginfo file if it is not already open.
>> +		 */
>> +		if (dwarf_info.fd_debuginfo < 0)
>> +			dwarf_info.fd_debuginfo =
>> +				open(dwarf_info.name_debuginfo, O_RDONLY);
>> +
>> +		dwfl_fd = dup(dwarf_info.fd_debuginfo);
>> +		if (dwfl_fd < 0) {
>> +			ERRMSG("Failed to get a duplicate handle for"
>> +				" debuginfo.\n");
>> +			goto err_out;
>> +		}
>> +	}
>> +	if (dwarf_info.fd_debuginfo > 0) {
>> +		if (dwfl_report_offline(dwfl, dwarf_info.module_name,
>> +				dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
>> +			ERRMSG("Failed reading %s: %s\n",
>> +				dwarf_info.name_debuginfo, dwfl_errmsg (-1));
>> +			/* dwfl_fd is consumed on success, not on failure */
>> +			close(dwfl_fd);
>> +			goto err_out;
>> +		}
>> +	}
>> +	else if (dwfl_linux_kernel_report_offline(dwfl,
>> +						info->system_utsname.release,
>> +						&dwfl_report_module_p)) {
>> +		ERRMSG("Can't get Module debuginfo for module '%s'\n",
>> +					dwarf_info.module_name);
>> +		goto err_out;
>> +	}
>> +	dwfl_report_end(dwfl, NULL, NULL);
>> +
>> +	dwfl_getmodules(dwfl, &process_module, NULL, 0);
>> +
>> +	if (dwarf_info.elfd == NULL) {
>> +		ERRMSG("Can't get first elf header of %s.\n",
>> +		    dwarf_info.name_debuginfo);
>> +		goto err_out;
>> +	}
>> +
>> +	if (dwarf_info.dwarfd == NULL) {
>> +		ERRMSG("Can't get debug context descriptor for %s.\n",
>> +		    dwarf_info.name_debuginfo);
>> +		goto err_out;
>> +	}
>> +	dwarf_info.dwfl = dwfl;
>> +	return TRUE;
>> +err_out:
>> +	if (dwfl)
>> +		dwfl_end(dwfl);
>> +
>> +	return FALSE;
>> +}
>> +
>>  unsigned long long
>>  get_symbol_addr(char *symname)
>>  {
>> @@ -1383,18 +1523,12 @@ get_symbol_addr(char *symname)
>>  	Elf_Data *data = NULL;
>>  	Elf_Scn *scn = NULL;
>>  	char *sym_name = NULL;
>> -	const off_t failed = (off_t)-1;
>>  
>> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
>> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
>> -		    dwarf_info.name_debuginfo, strerror(errno));
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
>> -		ERRMSG("Can't get first elf header of %s.\n",
>> -		    dwarf_info.name_debuginfo);
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> +	if (!init_dwarf_info())
>> +		return 0;
>> +
>> +	elfd = dwarf_info.elfd;
>> +
>>  	while ((scn = elf_nextscn(elfd, scn)) != NULL) {
>>  		if (gelf_getshdr(scn, &shdr) == NULL) {
>>  			ERRMSG("Can't get section header.\n");
>> @@ -1431,8 +1565,7 @@ get_symbol_addr(char *symname)
>>  		}
>>  	}
>>  out:
>> -	if (elfd != NULL)
>> -		elf_end(elfd);
>> +	clean_dwfl_info();
>>  
>>  	return symbol;
>>  }
>> @@ -1449,18 +1582,12 @@ get_next_symbol_addr(char *symname)
>>  	Elf_Data *data = NULL;
>>  	Elf_Scn *scn = NULL;
>>  	char *sym_name = NULL;
>> -	const off_t failed = (off_t)-1;
>>  
>> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
>> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
>> -		    dwarf_info.name_debuginfo, strerror(errno));
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
>> -		ERRMSG("Can't get first elf header of %s.\n",
>> -		    dwarf_info.name_debuginfo);
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> +	if (!init_dwarf_info())
>> +		return 0;
>> +
>> +	elfd = dwarf_info.elfd;
>> +
>>  	while ((scn = elf_nextscn(elfd, scn)) != NULL) {
>>  		if (gelf_getshdr(scn, &shdr) == NULL) {
>>  			ERRMSG("Can't get section header.\n");
>> @@ -1522,8 +1649,7 @@ get_next_symbol_addr(char *symname)
>>  		}
>>  	}
>>  out:
>> -	if (elfd != NULL)
>> -		elf_end(elfd);
>> +	clean_dwfl_info();
>>  
>>  	return next_symbol;
>>  }
>> @@ -2034,24 +2160,15 @@ get_debug_info(void)
>>  	Elf_Scn *scn = NULL;
>>  	GElf_Shdr scnhdr_mem, *scnhdr = NULL;
>>  	Dwarf_Die cu_die;
>> -	const off_t failed = (off_t)-1;
>>  
>>  	int ret = FALSE;
>>  
>> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
>> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
>> -		    dwarf_info.name_debuginfo, strerror(errno));
>> -		return FALSE;
>> -	}
>> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ_MMAP, NULL))) {
>> -		ERRMSG("Can't get first elf header of %s.\n",
>> -		    dwarf_info.name_debuginfo);
>> +	if (!init_dwarf_info())
>>  		return FALSE;
>> -	}
>> -	if (!(dwarfd = dwarf_begin_elf(elfd, DWARF_C_READ, NULL))) {
>> -		ERRMSG("Can't create a handle for a new debug session.\n");
>> -		goto out;
>> -	}
>> +
>> +	elfd = dwarf_info.elfd;
>> +	dwarfd = dwarf_info.dwarfd;
>> +
>>  	if (elf_getshstrndx(elfd, &shstrndx) < 0) {
>>  		ERRMSG("Can't get the section index of the string table.\n");
>>  		goto out;
>> @@ -2088,10 +2205,7 @@ get_debug_info(void)
>>  	}
>>  	ret = TRUE;
>>  out:
>> -	if (dwarfd != NULL)
>> -		dwarf_end(dwarfd);
>> -	if (elfd != NULL)
>> -		elf_end(elfd);
>> +	clean_dwfl_info();
>>  
>>  	return ret;
>>  }
>> @@ -2448,14 +2562,58 @@ get_mem_type(void)
>>  	return ret;
>>  }
>>  
>> +/*
>> + * Set the dwarf_info with kernel/module debuginfo file information.
>> + */
>> +int
>> +set_dwarf_debuginfo(char *mod_name, char *name_debuginfo, int fd_debuginfo)
>> +{
>> +	if (!mod_name)
>> +		return FALSE;
>> +	if (dwarf_info.module_name && !strcmp(dwarf_info.module_name, mod_name))
>> +		return TRUE;
>> +
>> +	/* Switching to different module.
>> +	 *
>> +	 * Close the file descriptor if previous module is != kernel and
>> +	 * xen-syms. The reason is, vmlinux file will always be supplied
>> +	 * by user and code to open/close kernel debuginfo file already
>> +	 * in place. The module debuginfo files are opened only if '--config'
>> +	 * option is used. This helps not to break the existing functionlity
>> +	 * if called without '--config' option.
>> +	 */
>> +
>> +	if (dwarf_info.module_name
>> +			&& strcmp(dwarf_info.module_name, "vmlinux")
>> +			&& strcmp(dwarf_info.module_name, "xen-syms")) {
>> +		if (dwarf_info.fd_debuginfo > 0)
>> +			close(dwarf_info.fd_debuginfo);
>> +		if (dwarf_info.name_debuginfo)
>> +			free(dwarf_info.name_debuginfo);
>> +	}
>> +	dwarf_info.fd_debuginfo = fd_debuginfo;
>> +	dwarf_info.name_debuginfo = name_debuginfo;
>> +	dwarf_info.module_name = mod_name;
>> +
>> +	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
>> +		!strcmp(dwarf_info.module_name, "xen-syms"))
>> +		return TRUE;
>> +
>> +	/* check to see whether module debuginfo is available */
>> +	if (!init_dwarf_info())
>> +		return FALSE;
>> +	else
>> +		clean_dwfl_info();
>> +	return TRUE;
>> +}
>> +
>>  int
>>  generate_vmcoreinfo(void)
>>  {
>>  	if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
>>  		return FALSE;
>>  
>> -	dwarf_info.fd_debuginfo   = info->fd_vmlinux;
>> -	dwarf_info.name_debuginfo = info->name_vmlinux;
>> +	set_dwarf_debuginfo("vmlinux", info->name_vmlinux, info->fd_vmlinux);
>>  
>>  	if (!get_symbol_info())
>>  		return FALSE;
>> @@ -3888,8 +4046,8 @@ initial(void)
>>  	 * Get the debug information for analysis from the kernel file
>>  	 */
>>  	} else if (info->name_vmlinux) {
>> -		dwarf_info.fd_debuginfo   = info->fd_vmlinux;
>> -		dwarf_info.name_debuginfo = info->name_vmlinux;
>> +		set_dwarf_debuginfo("vmlinux", info->name_vmlinux,
>> +						info->fd_vmlinux);
>>  
>>  		if (!get_symbol_info())
>>  			return FALSE;
>> @@ -6552,8 +6710,7 @@ generate_vmcoreinfo_xen(void)
>>  		ERRMSG("Can't get the size of page.\n");
>>  		return FALSE;
>>  	}
>> -	dwarf_info.fd_debuginfo   = info->fd_xen_syms;
>> -	dwarf_info.name_debuginfo = info->name_xen_syms;
>> +	set_dwarf_debuginfo("xen-syms", info->name_xen_syms, info->fd_xen_syms);
>>  
>>  	if (!get_symbol_info_xen())
>>  		return FALSE;
>> @@ -6820,8 +6977,8 @@ initial_xen(void)
>>  	 * Get the debug information for analysis from the xen-syms file
>>  	 */
>>  	} else if (info->name_xen_syms) {
>> -		dwarf_info.fd_debuginfo   = info->fd_xen_syms;
>> -		dwarf_info.name_debuginfo = info->name_xen_syms;
>> +		set_dwarf_debuginfo("xen-syms", info->name_xen_syms,
>> +							info->fd_xen_syms);
>>  
>>  		if (!get_symbol_info_xen())
>>  			return FALSE;
>> diff --git a/makedumpfile.h b/makedumpfile.h
>> index e037f12..3fda754 100644
>> --- a/makedumpfile.h
>> +++ b/makedumpfile.h
>> @@ -27,6 +27,7 @@
>>  #include <sys/wait.h>
>>  #include <zlib.h>
>>  #include <elfutils/libdw.h>
>> +#include <elfutils/libdwfl.h>
>>  #include <libelf.h>
>>  #include <dwarf.h>
>>  #include <byteswap.h>
>> @@ -1177,6 +1178,8 @@ extern struct srcfile_table	srcfile_table;
>>  /*
>>   * Debugging information
>>   */
>> +#define DEFAULT_DEBUGINFO_PATH	"/usr/lib/debug"
>> +
>>  enum {
>>  	DWARF_INFO_GET_STRUCT_SIZE,
>>  	DWARF_INFO_GET_MEMBER_OFFSET,
>> @@ -1194,10 +1197,14 @@ struct dwarf_info {
>>  	unsigned int	cmd;		/* IN */
>>  	int	fd_debuginfo;		/* IN */
>>  	char	*name_debuginfo;	/* IN */
>> +	char	*module_name;		/* IN */
>>  	char	*struct_name;		/* IN */
>>  	char	*symbol_name;		/* IN */
>>  	char	*member_name;		/* IN */
>>  	char	*enum_name;		/* IN */
>> +	Elf	*elfd;			/* OUT */
>> +	Dwarf	*dwarfd;		/* OUT */
>> +	Dwfl	*dwfl;			/* OUT */
>>  	long	struct_size;		/* OUT */
>>  	long	member_offset;		/* OUT */
>>  	long	array_length;		/* OUT */
>>


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-15 10:21   ` Mahesh Jagannath Salgaonkar
@ 2011-07-19  2:27     ` Ken'ichi Ohmichi
  2011-07-19  9:59       ` Mahesh Jagannath Salgaonkar
  0 siblings, 1 reply; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-19  2:27 UTC (permalink / raw)
  To: Mahesh Jagannath Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

On Fri, 15 Jul 2011 15:51:38 +0530
Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> > 
> > On my machine (RHEL5 x86_64), I cannot compile makedumpfile with this patch.
> > I guess that it is due to old elfutils of my machine, and I am trying this
> > problem by newer elfutils.
> > 
> > I'd like to get some hints, so can you tell me your environment ?
> > RHEL6 x86_64 ?
> 
> Yes, I had tested these patches on RHEL6.0 and RHEl6.1 x86_64. As far as
> I know RHEL6.0 had elfutils-0.148.
> 
> I did not try my patches on RHEL5 x86-64. Let me see if I can get a
> RHEL5 x86_64 box to verify.

I can compile it with elfutils-0.137 and some compiling options on RHEL5.
We need the following change in Makefile.

-       $(CC) $(CFLAGS) $(OBJ_ARCH) -o $@ $< -static -ldw -lelf -lz
+       $(CC) $(CFLAGS) $(OBJ_ARCH) -o $@ $< -static -ldw -lbz2 -lebl -ldl -lelf -lz


By the way, do you have any documents/samples for dwfl_XXXX functions ?
I'd like to see them for reviewing this patch.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-19  2:27     ` Ken'ichi Ohmichi
@ 2011-07-19  9:59       ` Mahesh Jagannath Salgaonkar
  2011-07-19 13:08         ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 16+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2011-07-19  9:59 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard

Hi Ken'ich,

On 07/19/2011 07:57 AM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> On Fri, 15 Jul 2011 15:51:38 +0530
> Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>>>
>>> On my machine (RHEL5 x86_64), I cannot compile makedumpfile with this patch.
>>> I guess that it is due to old elfutils of my machine, and I am trying this
>>> problem by newer elfutils.
>>>
>>> I'd like to get some hints, so can you tell me your environment ?
>>> RHEL6 x86_64 ?
>>
>> Yes, I had tested these patches on RHEL6.0 and RHEl6.1 x86_64. As far as
>> I know RHEL6.0 had elfutils-0.148.
>>
>> I did not try my patches on RHEL5 x86-64. Let me see if I can get a
>> RHEL5 x86_64 box to verify.
> 
> I can compile it with elfutils-0.137 and some compiling options on RHEL5.
> We need the following change in Makefile.
> 
> -       $(CC) $(CFLAGS) $(OBJ_ARCH) -o $@ $< -static -ldw -lelf -lz
> +       $(CC) $(CFLAGS) $(OBJ_ARCH) -o $@ $< -static -ldw -lbz2 -lebl -ldl -lelf -lz
> 
> 
> By the way, do you have any documents/samples for dwfl_XXXX functions ?
> I'd like to see them for reviewing this patch.

As far as I know there is no formal documentation available for
dwfl_xxxx functions apart from 'elfutils/libdwfl/libdwfl.h' from
elfutils sources. In fact the elfutils itself lacks the Documentation
part for most of it's APIs.

I used 'elfutils/libdwfl/libdwfl.h' from elfutils sources as a reference
which has neat explanation for each dwfl_xxx() functions. Apart from
libdwfl.h I also used to go through actual function implementations
available under elfutils sources.

Thanks,
-Mahesh.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-19  9:59       ` Mahesh Jagannath Salgaonkar
@ 2011-07-19 13:08         ` Ken'ichi Ohmichi
  0 siblings, 0 replies; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-19 13:08 UTC (permalink / raw)
  To: Mahesh Jagannath Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

On Tue, 19 Jul 2011 15:29:24 +0530
Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> > 
> > By the way, do you have any documents/samples for dwfl_XXXX functions ?
> > I'd like to see them for reviewing this patch.
> 
> As far as I know there is no formal documentation available for
> dwfl_xxxx functions apart from 'elfutils/libdwfl/libdwfl.h' from
> elfutils sources. In fact the elfutils itself lacks the Documentation
> part for most of it's APIs.
> 
> I used 'elfutils/libdwfl/libdwfl.h' from elfutils sources as a reference
> which has neat explanation for each dwfl_xxx() functions. Apart from
> libdwfl.h I also used to go through actual function implementations
> available under elfutils sources.

OK, Thank you.
I also will see libdwfl.h as a reference.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-05-17 20:01 [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo Mahesh J Salgaonkar
  2011-07-15  9:35 ` Ken'ichi Ohmichi
@ 2011-07-25  8:11 ` Ken'ichi Ohmichi
  2011-07-27  6:09   ` Mahesh Jagannath Salgaonkar
  1 sibling, 1 reply; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-25  8:11 UTC (permalink / raw)
  To: Mahesh J Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

This patch is almost good, and there are some cleanup points.

On Wed, 18 May 2011 01:31:01 +0530
Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> +
> +static void
> +clean_dwfl_info(void)
> +{
> +	if (dwarf_info.dwfl)
> +		dwfl_end(dwarf_info.dwfl);
> +
> +	dwarf_info.dwfl = NULL;
> +	dwarf_info.dwarfd = NULL;
> +	dwarf_info.elfd = NULL;
> +}
> +
> +/*
> + * Intitialize the dwarf info.
>
> + * Linux kernel module debuginfo are of ET_REL (relocatable) type. The old
> + * implementation of get_debug_info() function that reads the debuginfo was
> + * not relocation-aware and hence could not read the dwarf info properly
> + * from module debuginfo.

"The old implementaion .." is useful for my review, but it is not necessary
after merging this patch.


> + *
> + * This function uses dwfl API's to apply relocation before reading the
> + * dwarf information from module debuginfo.
> + * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
> + * after applying relocation to module debuginfo.
> + */
> +static int
> +init_dwarf_info(void)

Is the searching method of debuginfo file only for kernel module ?
Or also for vmlinux ?

I feel this function is a little complex, and I'd like to make it simple.
If only for kernel module, we can do it by separating the searching method
from this function and calling it in case of kernel module.


> +{
> +	Dwfl *dwfl = NULL;
> +	int dwfl_fd = -1;
> +	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
> +	static const Dwfl_Callbacks callbacks = {
> +		.section_address = dwfl_offline_section_address,
> +		.find_debuginfo = dwfl_standard_find_debuginfo,
> +		.debuginfo_path = &debuginfo_path,
> +	};
> +
> +	dwarf_info.elfd = NULL;
> +	dwarf_info.dwarfd = NULL;
> +
> +	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
> +		ERRMSG("Can't create a handle for a new dwfl session.\n");
> +		return FALSE;
> +	}
> +
> +	if (dwarf_info.name_debuginfo) {
> +		/* We have absolute path for debuginfo file, use it directly
> +		 * instead of searching it through
> +		 * dwfl_linux_kernel_report_offline() call.
> +		 *
> +		 * Open the debuginfo file if it is not already open.
> +		 */
> +		if (dwarf_info.fd_debuginfo < 0)
> +			dwarf_info.fd_debuginfo =
> +				open(dwarf_info.name_debuginfo, O_RDONLY);
> +
> +		dwfl_fd = dup(dwarf_info.fd_debuginfo);
> +		if (dwfl_fd < 0) {
> +			ERRMSG("Failed to get a duplicate handle for"
> +				" debuginfo.\n");
> +			goto err_out;
> +		}
> +	}
> +	if (dwarf_info.fd_debuginfo > 0) {

Better to change the above to
	if (dwfl_fd > 0) {

because dwfl_fd is used in the follwoing and dwarf_info.fd_debuginfo is not.


> @@ -1383,18 +1523,12 @@ get_symbol_addr(char *symname)
>  	Elf_Data *data = NULL;
>  	Elf_Scn *scn = NULL;
>  	char *sym_name = NULL;
> -	const off_t failed = (off_t)-1;
>  
> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
> -		    dwarf_info.name_debuginfo, strerror(errno));
> -		return NOT_FOUND_SYMBOL;
> -	}
> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
> -		ERRMSG("Can't get first elf header of %s.\n",
> -		    dwarf_info.name_debuginfo);
> -		return NOT_FOUND_SYMBOL;
> -	}
> +	if (!init_dwarf_info())
> +		return 0;

Better to change the above to
+		return NOT_FOUND_SYMBOL;


> @@ -1449,18 +1582,12 @@ get_next_symbol_addr(char *symname)
>  	Elf_Data *data = NULL;
>  	Elf_Scn *scn = NULL;
>  	char *sym_name = NULL;
> -	const off_t failed = (off_t)-1;
>  
> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
> -		    dwarf_info.name_debuginfo, strerror(errno));
> -		return NOT_FOUND_SYMBOL;
> -	}
> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
> -		ERRMSG("Can't get first elf header of %s.\n",
> -		    dwarf_info.name_debuginfo);
> -		return NOT_FOUND_SYMBOL;
> -	}
> +	if (!init_dwarf_info())
> +		return 0;

ditto.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-25  8:11 ` Ken'ichi Ohmichi
@ 2011-07-27  6:09   ` Mahesh Jagannath Salgaonkar
  2011-07-28  9:11     ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 16+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2011-07-27  6:09 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard

Hi Ken'ichi,

On 07/25/2011 01:41 PM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> This patch is almost good, and there are some cleanup points.
> 
> On Wed, 18 May 2011 01:31:01 +0530
> Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>> +
>> +static void
>> +clean_dwfl_info(void)
>> +{
>> +	if (dwarf_info.dwfl)
>> +		dwfl_end(dwarf_info.dwfl);
>> +
>> +	dwarf_info.dwfl = NULL;
>> +	dwarf_info.dwarfd = NULL;
>> +	dwarf_info.elfd = NULL;
>> +}
>> +
>> +/*
>> + * Intitialize the dwarf info.
>>
>> + * Linux kernel module debuginfo are of ET_REL (relocatable) type. The old
>> + * implementation of get_debug_info() function that reads the debuginfo was
>> + * not relocation-aware and hence could not read the dwarf info properly
>> + * from module debuginfo.
> 
> "The old implementaion .." is useful for my review, but it is not necessary
> after merging this patch.
> 
> 
>> + *
>> + * This function uses dwfl API's to apply relocation before reading the
>> + * dwarf information from module debuginfo.
>> + * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
>> + * after applying relocation to module debuginfo.
>> + */
>> +static int
>> +init_dwarf_info(void)
> 
> Is the searching method of debuginfo file only for kernel module ?
> Or also for vmlinux ?

Yes, the searching method is only for module debuginfo. For vmlinux we
set the dwarf_info.name_debuginfo before call to init_dwarf_info() and
we never call search routine dwfl_linux_kernel_report_offline() for
vmlinux. The routine dwfl_report_offline() applies the relocation on
specified debuginfo module. In case vmlinux it basically does nothing.

> 
> I feel this function is a little complex, and I'd like to make it simple.
> If only for kernel module, we can do it by separating the searching method
> from this function and calling it in case of kernel module.

The init_dwarf_info() function gets called everytime when
get_debug_info() is called. The get_debug_info() is called multiple
times for same debuginfo file. This function tries to avoid the repeated
search for same debuginfo, hence the function is little complex.
	- In case of kernel module the very first invocation of
init_dwarf_info() would call dwfl_linux_kernel_report_offline() which
will iterate over the available kernel modules and process the debuginfo
only for the module for which we are interested in.
	- We set the dwarf_info.name_debuginfo with the debuginfo file name
found during the first invocation.
	- The second invocation of init_dwarf_info() for same kernel module,
will find dwarf_info.name_debuginfo is already set and will avoid the
debuginfo search. In this case it will just apply relocation using
routine dwfl_report_offline().

This function does not have any special handling code for vmlinux. The
function is independent of whether it is called for vmlinux or kernel
module. In case of vmlinux this function has absolutely no side effects.

> 
> 
>> +{
>> +	Dwfl *dwfl = NULL;
>> +	int dwfl_fd = -1;
>> +	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
>> +	static const Dwfl_Callbacks callbacks = {
>> +		.section_address = dwfl_offline_section_address,
>> +		.find_debuginfo = dwfl_standard_find_debuginfo,
>> +		.debuginfo_path = &debuginfo_path,
>> +	};
>> +
>> +	dwarf_info.elfd = NULL;
>> +	dwarf_info.dwarfd = NULL;
>> +
>> +	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
>> +		ERRMSG("Can't create a handle for a new dwfl session.\n");
>> +		return FALSE;
>> +	}
>> +
>> +	if (dwarf_info.name_debuginfo) {
>> +		/* We have absolute path for debuginfo file, use it directly
>> +		 * instead of searching it through
>> +		 * dwfl_linux_kernel_report_offline() call.
>> +		 *
>> +		 * Open the debuginfo file if it is not already open.
>> +		 */
>> +		if (dwarf_info.fd_debuginfo < 0)
>> +			dwarf_info.fd_debuginfo =
>> +				open(dwarf_info.name_debuginfo, O_RDONLY);
>> +
>> +		dwfl_fd = dup(dwarf_info.fd_debuginfo);
>> +		if (dwfl_fd < 0) {
>> +			ERRMSG("Failed to get a duplicate handle for"
>> +				" debuginfo.\n");
>> +			goto err_out;
>> +		}
>> +	}
>> +	if (dwarf_info.fd_debuginfo > 0) {
> 
> Better to change the above to
> 	if (dwfl_fd > 0) {
> 
> because dwfl_fd is used in the follwoing and dwarf_info.fd_debuginfo is not.

Agree.

> 
> 
>> @@ -1383,18 +1523,12 @@ get_symbol_addr(char *symname)
>>  	Elf_Data *data = NULL;
>>  	Elf_Scn *scn = NULL;
>>  	char *sym_name = NULL;
>> -	const off_t failed = (off_t)-1;
>>  
>> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
>> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
>> -		    dwarf_info.name_debuginfo, strerror(errno));
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
>> -		ERRMSG("Can't get first elf header of %s.\n",
>> -		    dwarf_info.name_debuginfo);
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> +	if (!init_dwarf_info())
>> +		return 0;
> 
> Better to change the above to
> +		return NOT_FOUND_SYMBOL;
> 

Agree.

> 
>> @@ -1449,18 +1582,12 @@ get_next_symbol_addr(char *symname)
>>  	Elf_Data *data = NULL;
>>  	Elf_Scn *scn = NULL;
>>  	char *sym_name = NULL;
>> -	const off_t failed = (off_t)-1;
>>  
>> -	if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
>> -		ERRMSG("Can't seek the kernel file(%s). %s\n",
>> -		    dwarf_info.name_debuginfo, strerror(errno));
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> -	if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
>> -		ERRMSG("Can't get first elf header of %s.\n",
>> -		    dwarf_info.name_debuginfo);
>> -		return NOT_FOUND_SYMBOL;
>> -	}
>> +	if (!init_dwarf_info())
>> +		return 0;
> 
> ditto.

Agree.

Thanks,
-Mahesh.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-27  6:09   ` Mahesh Jagannath Salgaonkar
@ 2011-07-28  9:11     ` Ken'ichi Ohmichi
  2011-07-28 10:38       ` Mahesh Jagannath Salgaonkar
  2011-07-28 15:11       ` Mahesh Jagannath Salgaonkar
  0 siblings, 2 replies; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-28  9:11 UTC (permalink / raw)
  To: Mahesh Jagannath Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

This feature's patches are very large, and I created a devel branch
on sourceforge git tree for sharing the code with you.

http://makedumpfile.git.sourceforge.net/git/gitweb.cgi?p=makedumpfile/makedumpfile;a=shortlog;h=refs/heads/filter-out-devel

I commited all of your patches and my cleanup patches.
If you notice some problems or cleate some patches, please let me know them.

On Wed, 27 Jul 2011 11:39:44 +0530
Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> >> + *
> >> + * This function uses dwfl API's to apply relocation before reading the
> >> + * dwarf information from module debuginfo.
> >> + * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
> >> + * after applying relocation to module debuginfo.
> >> + */
> >> +static int
> >> +init_dwarf_info(void)
> > 
> > Is the searching method of debuginfo file only for kernel module ?
> > Or also for vmlinux ?
> 
> Yes, the searching method is only for module debuginfo. For vmlinux we
> set the dwarf_info.name_debuginfo before call to init_dwarf_info() and
> we never call search routine dwfl_linux_kernel_report_offline() for
> vmlinux. The routine dwfl_report_offline() applies the relocation on
> specified debuginfo module. In case vmlinux it basically does nothing.
>
> > I feel this function is a little complex, and I'd like to make it simple.
> > If only for kernel module, we can do it by separating the searching method
> > from this function and calling it in case of kernel module.
> 
> The init_dwarf_info() function gets called everytime when
> get_debug_info() is called. The get_debug_info() is called multiple
> times for same debuginfo file. This function tries to avoid the repeated
> search for same debuginfo, hence the function is little complex.
> 	- In case of kernel module the very first invocation of
> init_dwarf_info() would call dwfl_linux_kernel_report_offline() which
> will iterate over the available kernel modules and process the debuginfo
> only for the module for which we are interested in.
> 	- We set the dwarf_info.name_debuginfo with the debuginfo file name
> found during the first invocation.
> 	- The second invocation of init_dwarf_info() for same kernel module,
> will find dwarf_info.name_debuginfo is already set and will avoid the
> debuginfo search. In this case it will just apply relocation using
> routine dwfl_report_offline().
> 
> This function does not have any special handling code for vmlinux. The
> function is independent of whether it is called for vmlinux or kernel
> module. In case of vmlinux this function has absolutely no side effects.

If adding the searching method to the blow position and removing the code
from init_dwarf_info(), I guess it makes the code simple.

@ process_config_file()
 9402                         if (!set_dwarf_debuginfo(config->module_name,
 9403                                                                 NULL, -1)) {
 9404                                 ERRMSG("Skipping to next Module section\n");
 9405                                 skip_section = 1;
 9406                                 free_config(config);
 9407                                 continue;
 9408                         }
 9409                         << HERE >> 

Anyway, I need to investigate the code more.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-28  9:11     ` Ken'ichi Ohmichi
@ 2011-07-28 10:38       ` Mahesh Jagannath Salgaonkar
  2011-07-29  7:21         ` Ken'ichi Ohmichi
  2011-07-28 15:11       ` Mahesh Jagannath Salgaonkar
  1 sibling, 1 reply; 16+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2011-07-28 10:38 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard

Hi Keni'chi,

On 07/28/2011 02:41 PM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> This feature's patches are very large, and I created a devel branch
> on sourceforge git tree for sharing the code with you.
> 
> http://makedumpfile.git.sourceforge.net/git/gitweb.cgi?p=makedumpfile/makedumpfile;a=shortlog;h=refs/heads/filter-out-devel
> 
> I commited all of your patches and my cleanup patches.
> If you notice some problems or cleate some patches, please let me know them.
> 

Sure. Will take a look.

> On Wed, 27 Jul 2011 11:39:44 +0530
> Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>>>> + *
>>>> + * This function uses dwfl API's to apply relocation before reading the
>>>> + * dwarf information from module debuginfo.
>>>> + * On success, this function sets the dwarf_info.elfd and dwarf_info.dwarfd
>>>> + * after applying relocation to module debuginfo.
>>>> + */
>>>> +static int
>>>> +init_dwarf_info(void)
>>>
>>> Is the searching method of debuginfo file only for kernel module ?
>>> Or also for vmlinux ?
>>
>> Yes, the searching method is only for module debuginfo. For vmlinux we
>> set the dwarf_info.name_debuginfo before call to init_dwarf_info() and
>> we never call search routine dwfl_linux_kernel_report_offline() for
>> vmlinux. The routine dwfl_report_offline() applies the relocation on
>> specified debuginfo module. In case vmlinux it basically does nothing.
>>
>>> I feel this function is a little complex, and I'd like to make it simple.
>>> If only for kernel module, we can do it by separating the searching method
>>> from this function and calling it in case of kernel module.
>>
>> The init_dwarf_info() function gets called everytime when
>> get_debug_info() is called. The get_debug_info() is called multiple
>> times for same debuginfo file. This function tries to avoid the repeated
>> search for same debuginfo, hence the function is little complex.
>> 	- In case of kernel module the very first invocation of
>> init_dwarf_info() would call dwfl_linux_kernel_report_offline() which
>> will iterate over the available kernel modules and process the debuginfo
>> only for the module for which we are interested in.
>> 	- We set the dwarf_info.name_debuginfo with the debuginfo file name
>> found during the first invocation.
>> 	- The second invocation of init_dwarf_info() for same kernel module,
>> will find dwarf_info.name_debuginfo is already set and will avoid the
>> debuginfo search. In this case it will just apply relocation using
>> routine dwfl_report_offline().
>>
>> This function does not have any special handling code for vmlinux. The
>> function is independent of whether it is called for vmlinux or kernel
>> module. In case of vmlinux this function has absolutely no side effects.
> 
> If adding the searching method to the blow position and removing the code
> from init_dwarf_info(), I guess it makes the code simple.
> 
> @ process_config_file()
>  9402                         if (!set_dwarf_debuginfo(config->module_name,
>  9403                                                                 NULL, -1)) {
>  9404                                 ERRMSG("Skipping to next Module section\n");
>  9405                                 skip_section = 1;
>  9406                                 free_config(config);
>  9407                                 continue;
>  9408                         }
>  9409                         << HERE >> 

This may not be the correct place to call search method. We may end up
calling search method multiple times for same kernel module. I think
moving the search method inside set_dwarf_debuginfo() routine at below
position is a better place:

@set_dwarf_debuginfo()
	......
	......
	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
                !strcmp(dwarf_info.module_name, "xen-syms"))
                return TRUE;
+	 << HERE >>
-        /* check to see whether module debuginfo is available */
-        if (!init_dwarf_info())
-                return FALSE;
-        else
-                clean_dwfl_info();
	 return TRUE;
}

And then we can remove search routine from init_dwarf_info(). What do
you think?

Thanks,
-Mahesh.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-28  9:11     ` Ken'ichi Ohmichi
  2011-07-28 10:38       ` Mahesh Jagannath Salgaonkar
@ 2011-07-28 15:11       ` Mahesh Jagannath Salgaonkar
  2011-07-29  7:24         ` Ken'ichi Ohmichi
  1 sibling, 1 reply; 16+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2011-07-28 15:11 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard

Hi Ken'ichi,

On 07/28/2011 02:41 PM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> This feature's patches are very large, and I created a devel branch
> on sourceforge git tree for sharing the code with you.
> 
> http://makedumpfile.git.sourceforge.net/git/gitweb.cgi?p=makedumpfile/makedumpfile;a=shortlog;h=refs/heads/filter-out-devel
> 
> I commited all of your patches and my cleanup patches.
> If you notice some problems or cleate some patches, please let me know them.
> 

I checked out the devel branch and verified that all patches looks fine.
I will take this branch as base and will work on moving search method to
set_dwarf_debuginfo() routine.

Thanks,
-Mahesh.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-28 10:38       ` Mahesh Jagannath Salgaonkar
@ 2011-07-29  7:21         ` Ken'ichi Ohmichi
  2011-08-09 17:42           ` Mahesh J Salgaonkar
  0 siblings, 1 reply; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-29  7:21 UTC (permalink / raw)
  To: Mahesh Jagannath Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

On Thu, 28 Jul 2011 16:08:15 +0530
Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> > 
> > If adding the searching method to the blow position and removing the code
> > from init_dwarf_info(), I guess it makes the code simple.
> > 
> > @ process_config_file()
> >  9402                         if (!set_dwarf_debuginfo(config->module_name,
> >  9403                                                                 NULL, -1)) {
> >  9404                                 ERRMSG("Skipping to next Module section\n");
> >  9405                                 skip_section = 1;
> >  9406                                 free_config(config);
> >  9407                                 continue;
> >  9408                         }
> >  9409                         << HERE >> 
> 
> This may not be the correct place to call search method. We may end up
> calling search method multiple times for same kernel module. I think
> moving the search method inside set_dwarf_debuginfo() routine at below
> position is a better place:
> 
> @set_dwarf_debuginfo()
> 	......
> 	......
> 	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
>                 !strcmp(dwarf_info.module_name, "xen-syms"))
>                 return TRUE;
> +	 << HERE >>
> -        /* check to see whether module debuginfo is available */
> -        if (!init_dwarf_info())
> -                return FALSE;
> -        else
> -                clean_dwfl_info();
> 	 return TRUE;
> }
> 
> And then we can remove search routine from init_dwarf_info(). What do
> you think?

I think the above change will be good, thanks in advance.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-28 15:11       ` Mahesh Jagannath Salgaonkar
@ 2011-07-29  7:24         ` Ken'ichi Ohmichi
  0 siblings, 0 replies; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-29  7:24 UTC (permalink / raw)
  To: Mahesh Jagannath Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

On Thu, 28 Jul 2011 20:41:43 +0530
Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> > 
> > This feature's patches are very large, and I created a devel branch
> > on sourceforge git tree for sharing the code with you.
> > 
> > http://makedumpfile.git.sourceforge.net/git/gitweb.cgi?p=makedumpfile/makedumpfile;a=shortlog;h=refs/heads/filter-out-devel
> > 
> > I commited all of your patches and my cleanup patches.
> > If you notice some problems or cleate some patches, please let me know them.
> > 
> 
> I checked out the devel branch and verified that all patches looks fine.
> I will take this branch as base and will work on moving search method to
> set_dwarf_debuginfo() routine.

Thank you for your review and tests.
I pushed some additional cleanup patches.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-07-29  7:21         ` Ken'ichi Ohmichi
@ 2011-08-09 17:42           ` Mahesh J Salgaonkar
  2011-08-10  2:30             ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 16+ messages in thread
From: Mahesh J Salgaonkar @ 2011-08-09 17:42 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard

Hi Ken'ichi,

On 2011-07-29 16:21:04 Fri, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> On Thu, 28 Jul 2011 16:08:15 +0530
> Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> > > 
> > > If adding the searching method to the blow position and removing the code
> > > from init_dwarf_info(), I guess it makes the code simple.
> > > 
> > > @ process_config_file()
> > >  9402                         if (!set_dwarf_debuginfo(config->module_name,
> > >  9403                                                                 NULL, -1)) {
> > >  9404                                 ERRMSG("Skipping to next Module section\n");
> > >  9405                                 skip_section = 1;
> > >  9406                                 free_config(config);
> > >  9407                                 continue;
> > >  9408                         }
> > >  9409                         << HERE >> 
> > 
> > This may not be the correct place to call search method. We may end up
> > calling search method multiple times for same kernel module. I think
> > moving the search method inside set_dwarf_debuginfo() routine at below
> > position is a better place:
> > 
> > @set_dwarf_debuginfo()
> > 	......
> > 	......
> > 	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
> >                 !strcmp(dwarf_info.module_name, "xen-syms"))
> >                 return TRUE;
> > +	 << HERE >>
> > -        /* check to see whether module debuginfo is available */
> > -        if (!init_dwarf_info())
> > -                return FALSE;
> > -        else
> > -                clean_dwfl_info();
> > 	 return TRUE;
> > }
> > 
> > And then we can remove search routine from init_dwarf_info(). What do
> > you think?
> 
> I think the above change will be good, thanks in advance.

Please find the inline patch below that separates the search method from
init_dwarf_info() function. Please review it and let know your comments.

Thanks,
-Mahesh.
----------

makedumpfile: Move debuginfo search to set_dwarf_debuginfo() routine.

From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Move the debuginfo search logic out of init_dwarf_info() function to make
this function more simpler. Now we call search method in set_dwarf_debuginfo
when switch to different module section.

This patch also fixes a BUG where dwarf_info.module_name becomes a stale
pointer after free_config() invocation. This patch now uses strdup() to get
duplicate string and assigns it to dwarf_info.module_name.

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
 makedumpfile.c |  126 ++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 86 insertions(+), 40 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 35cbed9..fe8e8b0 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1186,7 +1186,60 @@ clean_dwfl_info(void)
 }
 
 /*
- * Intitialize the dwarf info.
+ * Search module debuginfo.
+ * This function searches for module debuginfo in default debuginfo path for
+ * a given module in dwarf_info.module_name.
+ *
+ * On success, dwarf_info.name_debuginfo is set to absolute path of
+ * module debuginfo.
+ */
+static int
+search_module_debuginfo(void)
+{
+	Dwfl *dwfl = NULL;
+	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
+	static const Dwfl_Callbacks callbacks = {
+		.section_address = dwfl_offline_section_address,
+		.find_debuginfo = dwfl_standard_find_debuginfo,
+		.debuginfo_path = &debuginfo_path,
+	};
+
+	/*
+	 * Check if We already have debuginfo file name with us. If yes,
+	 * then we don't need to proceed with search method.
+	 */
+	if (dwarf_info.name_debuginfo)
+		return TRUE;
+
+	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
+		ERRMSG("Can't create a handle for a new dwfl session.\n");
+		return FALSE;
+	}
+
+	/* Search for module debuginfo file. */
+	if (dwfl_linux_kernel_report_offline(dwfl,
+						info->system_utsname.release,
+						&dwfl_report_module_p)) {
+		ERRMSG("Can't get Module debuginfo for module '%s'\n",
+					dwarf_info.module_name);
+		dwfl_end(dwfl);
+		return FALSE;
+	}
+	dwfl_report_end(dwfl, NULL, NULL);
+	dwfl_getmodules(dwfl, &process_module, NULL, 0);
+
+	dwfl_end(dwfl);
+	clean_dwfl_info();
+
+	/* Return success if module debuginfo is found. */
+	if (dwarf_info.name_debuginfo)
+		return TRUE;
+
+	return FALSE;
+}
+
+/*
+ * Initialize the dwarf info.
  * Linux kernel module debuginfo are of ET_REL (relocatable) type.
  * This function uses dwfl API's to apply relocation before reading the
  * dwarf information from module debuginfo.
@@ -1198,51 +1251,45 @@ init_dwarf_info(void)
 {
 	Dwfl *dwfl = NULL;
 	int dwfl_fd = -1;
-	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
 	static const Dwfl_Callbacks callbacks = {
 		.section_address = dwfl_offline_section_address,
-		.find_debuginfo = dwfl_standard_find_debuginfo,
-		.debuginfo_path = &debuginfo_path,
 	};
 
 	dwarf_info.elfd = NULL;
 	dwarf_info.dwarfd = NULL;
 
+	 /*
+	  * We already know the absolute path of debuginfo file. Fail if we
+	  * still don't have one. Ideally we should never be in this situation.
+	  */
+	if (!dwarf_info.name_debuginfo) {
+		ERRMSG("Can't find absolute path to debuginfo file.\n");
+		return FALSE;
+	}
+
 	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
 		ERRMSG("Can't create a handle for a new dwfl session.\n");
 		return FALSE;
 	}
 
-	if (dwarf_info.name_debuginfo) {
-		/* We have absolute path for debuginfo file, use it directly
-		 * instead of searching it through
-		 * dwfl_linux_kernel_report_offline() call.
-		 *
-		 * Open the debuginfo file if it is not already open.
-		 */
-		if (dwarf_info.fd_debuginfo < 0)
-			dwarf_info.fd_debuginfo =
-				open(dwarf_info.name_debuginfo, O_RDONLY);
-
-		dwfl_fd = dup(dwarf_info.fd_debuginfo);
-		if (dwfl_fd < 0) {
-			ERRMSG("Failed to get a duplicate handle for"
-				" debuginfo.\n");
-			goto err_out;
-		}
-		if (dwfl_report_offline(dwfl, dwarf_info.module_name,
-				dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
-			ERRMSG("Failed reading %s: %s\n",
-				dwarf_info.name_debuginfo, dwfl_errmsg (-1));
-			/* dwfl_fd is consumed on success, not on failure */
-			close(dwfl_fd);
-			goto err_out;
-		}
-	} else if (dwfl_linux_kernel_report_offline(dwfl,
-						info->system_utsname.release,
-						&dwfl_report_module_p)) {
-		ERRMSG("Can't get Module debuginfo for module '%s'\n",
-					dwarf_info.module_name);
+	/* Open the debuginfo file if it is not already open.  */
+	if (dwarf_info.fd_debuginfo < 0)
+		dwarf_info.fd_debuginfo =
+			open(dwarf_info.name_debuginfo, O_RDONLY);
+
+	dwfl_fd = dup(dwarf_info.fd_debuginfo);
+	if (dwfl_fd < 0) {
+		ERRMSG("Failed to get a duplicate handle for"
+			" debuginfo.\n");
+		goto err_out;
+	}
+	/* Apply relocations. */
+	if (dwfl_report_offline(dwfl, dwarf_info.module_name,
+			dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
+		ERRMSG("Failed reading %s: %s\n",
+			dwarf_info.name_debuginfo, dwfl_errmsg (-1));
+		/* dwfl_fd is consumed on success, not on failure */
+		close(dwfl_fd);
 		goto err_out;
 	}
 	dwfl_report_end(dwfl, NULL, NULL);
@@ -2522,20 +2569,19 @@ set_dwarf_debuginfo(char *mod_name, char *name_debuginfo, int fd_debuginfo)
 		if (dwarf_info.name_debuginfo)
 			free(dwarf_info.name_debuginfo);
 	}
+	if (dwarf_info.module_name)
+		free(dwarf_info.module_name);
+
 	dwarf_info.fd_debuginfo = fd_debuginfo;
 	dwarf_info.name_debuginfo = name_debuginfo;
-	dwarf_info.module_name = mod_name;
+	dwarf_info.module_name = strdup(mod_name);
 
 	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
 		!strcmp(dwarf_info.module_name, "xen-syms"))
 		return TRUE;
 
 	/* check to see whether module debuginfo is available */
-	if (!init_dwarf_info())
-		return FALSE;
-	else
-		clean_dwfl_info();
-	return TRUE;
+	return search_module_debuginfo();
 }
 
 int


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
  2011-08-09 17:42           ` Mahesh J Salgaonkar
@ 2011-08-10  2:30             ` Ken'ichi Ohmichi
  0 siblings, 0 replies; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-08-10  2:30 UTC (permalink / raw)
  To: mahesh
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec, Dave Anderson,
	Prerna Saxena, Reinhard


Hi Mahesh,

On Tue, 9 Aug 2011 23:12:30 +0530
Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> > > > 
> > > > If adding the searching method to the blow position and removing the code
> > > > from init_dwarf_info(), I guess it makes the code simple.
> > > > 
> > > > @ process_config_file()
> > > >  9402                         if (!set_dwarf_debuginfo(config->module_name,
> > > >  9403                                                                 NULL, -1)) {
> > > >  9404                                 ERRMSG("Skipping to next Module section\n");
> > > >  9405                                 skip_section = 1;
> > > >  9406                                 free_config(config);
> > > >  9407                                 continue;
> > > >  9408                         }
> > > >  9409                         << HERE >> 
> > > 
> > > This may not be the correct place to call search method. We may end up
> > > calling search method multiple times for same kernel module. I think
> > > moving the search method inside set_dwarf_debuginfo() routine at below
> > > position is a better place:
> > > 
> > > @set_dwarf_debuginfo()
> > > 	......
> > > 	......
> > > 	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
> > >                 !strcmp(dwarf_info.module_name, "xen-syms"))
> > >                 return TRUE;
> > > +	 << HERE >>
> > > -        /* check to see whether module debuginfo is available */
> > > -        if (!init_dwarf_info())
> > > -                return FALSE;
> > > -        else
> > > -                clean_dwfl_info();
> > > 	 return TRUE;
> > > }
> > > 
> > > And then we can remove search routine from init_dwarf_info(). What do
> > > you think?
> > 
> > I think the above change will be good, thanks in advance.
> 
> Please find the inline patch below that separates the search method from
> init_dwarf_info() function. Please review it and let know your comments.

Thank you for the patch.
I think this patch is good, and the patch has been magerd into
filter-out-devel branch.


Thanks
Ken'ichi Ohmichi

> makedumpfile: Move debuginfo search to set_dwarf_debuginfo() routine.
> 
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> 
> Move the debuginfo search logic out of init_dwarf_info() function to make
> this function more simpler. Now we call search method in set_dwarf_debuginfo
> when switch to different module section.
> 
> This patch also fixes a BUG where dwarf_info.module_name becomes a stale
> pointer after free_config() invocation. This patch now uses strdup() to get
> duplicate string and assigns it to dwarf_info.module_name.
> 
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> ---
>  makedumpfile.c |  126 ++++++++++++++++++++++++++++++++++++++------------------
>  1 files changed, 86 insertions(+), 40 deletions(-)
> 
> diff --git a/makedumpfile.c b/makedumpfile.c
> index 35cbed9..fe8e8b0 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -1186,7 +1186,60 @@ clean_dwfl_info(void)
>  }
>  
>  /*
> - * Intitialize the dwarf info.
> + * Search module debuginfo.
> + * This function searches for module debuginfo in default debuginfo path for
> + * a given module in dwarf_info.module_name.
> + *
> + * On success, dwarf_info.name_debuginfo is set to absolute path of
> + * module debuginfo.
> + */
> +static int
> +search_module_debuginfo(void)
> +{
> +	Dwfl *dwfl = NULL;
> +	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
> +	static const Dwfl_Callbacks callbacks = {
> +		.section_address = dwfl_offline_section_address,
> +		.find_debuginfo = dwfl_standard_find_debuginfo,
> +		.debuginfo_path = &debuginfo_path,
> +	};
> +
> +	/*
> +	 * Check if We already have debuginfo file name with us. If yes,
> +	 * then we don't need to proceed with search method.
> +	 */
> +	if (dwarf_info.name_debuginfo)
> +		return TRUE;
> +
> +	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
> +		ERRMSG("Can't create a handle for a new dwfl session.\n");
> +		return FALSE;
> +	}
> +
> +	/* Search for module debuginfo file. */
> +	if (dwfl_linux_kernel_report_offline(dwfl,
> +						info->system_utsname.release,
> +						&dwfl_report_module_p)) {
> +		ERRMSG("Can't get Module debuginfo for module '%s'\n",
> +					dwarf_info.module_name);
> +		dwfl_end(dwfl);
> +		return FALSE;
> +	}
> +	dwfl_report_end(dwfl, NULL, NULL);
> +	dwfl_getmodules(dwfl, &process_module, NULL, 0);
> +
> +	dwfl_end(dwfl);
> +	clean_dwfl_info();
> +
> +	/* Return success if module debuginfo is found. */
> +	if (dwarf_info.name_debuginfo)
> +		return TRUE;
> +
> +	return FALSE;
> +}
> +
> +/*
> + * Initialize the dwarf info.
>   * Linux kernel module debuginfo are of ET_REL (relocatable) type.
>   * This function uses dwfl API's to apply relocation before reading the
>   * dwarf information from module debuginfo.
> @@ -1198,51 +1251,45 @@ init_dwarf_info(void)
>  {
>  	Dwfl *dwfl = NULL;
>  	int dwfl_fd = -1;
> -	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
>  	static const Dwfl_Callbacks callbacks = {
>  		.section_address = dwfl_offline_section_address,
> -		.find_debuginfo = dwfl_standard_find_debuginfo,
> -		.debuginfo_path = &debuginfo_path,
>  	};
>  
>  	dwarf_info.elfd = NULL;
>  	dwarf_info.dwarfd = NULL;
>  
> +	 /*
> +	  * We already know the absolute path of debuginfo file. Fail if we
> +	  * still don't have one. Ideally we should never be in this situation.
> +	  */
> +	if (!dwarf_info.name_debuginfo) {
> +		ERRMSG("Can't find absolute path to debuginfo file.\n");
> +		return FALSE;
> +	}
> +
>  	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
>  		ERRMSG("Can't create a handle for a new dwfl session.\n");
>  		return FALSE;
>  	}
>  
> -	if (dwarf_info.name_debuginfo) {
> -		/* We have absolute path for debuginfo file, use it directly
> -		 * instead of searching it through
> -		 * dwfl_linux_kernel_report_offline() call.
> -		 *
> -		 * Open the debuginfo file if it is not already open.
> -		 */
> -		if (dwarf_info.fd_debuginfo < 0)
> -			dwarf_info.fd_debuginfo =
> -				open(dwarf_info.name_debuginfo, O_RDONLY);
> -
> -		dwfl_fd = dup(dwarf_info.fd_debuginfo);
> -		if (dwfl_fd < 0) {
> -			ERRMSG("Failed to get a duplicate handle for"
> -				" debuginfo.\n");
> -			goto err_out;
> -		}
> -		if (dwfl_report_offline(dwfl, dwarf_info.module_name,
> -				dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
> -			ERRMSG("Failed reading %s: %s\n",
> -				dwarf_info.name_debuginfo, dwfl_errmsg (-1));
> -			/* dwfl_fd is consumed on success, not on failure */
> -			close(dwfl_fd);
> -			goto err_out;
> -		}
> -	} else if (dwfl_linux_kernel_report_offline(dwfl,
> -						info->system_utsname.release,
> -						&dwfl_report_module_p)) {
> -		ERRMSG("Can't get Module debuginfo for module '%s'\n",
> -					dwarf_info.module_name);
> +	/* Open the debuginfo file if it is not already open.  */
> +	if (dwarf_info.fd_debuginfo < 0)
> +		dwarf_info.fd_debuginfo =
> +			open(dwarf_info.name_debuginfo, O_RDONLY);
> +
> +	dwfl_fd = dup(dwarf_info.fd_debuginfo);
> +	if (dwfl_fd < 0) {
> +		ERRMSG("Failed to get a duplicate handle for"
> +			" debuginfo.\n");
> +		goto err_out;
> +	}
> +	/* Apply relocations. */
> +	if (dwfl_report_offline(dwfl, dwarf_info.module_name,
> +			dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
> +		ERRMSG("Failed reading %s: %s\n",
> +			dwarf_info.name_debuginfo, dwfl_errmsg (-1));
> +		/* dwfl_fd is consumed on success, not on failure */
> +		close(dwfl_fd);
>  		goto err_out;
>  	}
>  	dwfl_report_end(dwfl, NULL, NULL);
> @@ -2522,20 +2569,19 @@ set_dwarf_debuginfo(char *mod_name, char *name_debuginfo, int fd_debuginfo)
>  		if (dwarf_info.name_debuginfo)
>  			free(dwarf_info.name_debuginfo);
>  	}
> +	if (dwarf_info.module_name)
> +		free(dwarf_info.module_name);
> +
>  	dwarf_info.fd_debuginfo = fd_debuginfo;
>  	dwarf_info.name_debuginfo = name_debuginfo;
> -	dwarf_info.module_name = mod_name;
> +	dwarf_info.module_name = strdup(mod_name);
>  
>  	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
>  		!strcmp(dwarf_info.module_name, "xen-syms"))
>  		return TRUE;
>  
>  	/* check to see whether module debuginfo is available */
> -	if (!init_dwarf_info())
> -		return FALSE;
> -	else
> -		clean_dwfl_info();
> -	return TRUE;
> +	return search_module_debuginfo();
>  }
>  
>  int
> 


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.
       [not found] <CAA393vjc3vE3PG7EW70+8q3rTfv+yxcN-MbVGvH-nSUE9kCqVw@mail.gmail.com>
@ 2011-07-15 15:08 ` Ken'ichi Ohmichi
  0 siblings, 0 replies; 16+ messages in thread
From: Ken'ichi Ohmichi @ 2011-07-15 15:08 UTC (permalink / raw)
  To: mahesh, oomichi, kexec

Hi Mahesh,

>> On my machine (RHEL5 x86_64), I cannot compile makedumpfile with this patch.
>> I guess that it is due to old elfutils of my machine, and I am trying this
>> problem by newer elfutils.
>>
>> I'd like to get some hints, so can you tell me your environment ?
>> RHEL6 x86_64 ?
>
> Yes, I had tested these patches on RHEL6.0 and RHEl6.1 x86_64. As far as
> I know RHEL6.0 had elfutils-0.148.

OK, Thanks.

> I did not try my patches on RHEL5 x86-64. Let me see if I can get a
> RHEL5 x86_64 box to verify.
>
> But in case we can not fix the compilation with RHEL5 environment, do
> you think we can go with one of following options:
>
> 1. When compiled with older elfutils library, build makedumpfile without
> this feature enabled.
> 2. Make newer elfutils vesion as pre-requisite for future makedumpfile
> releases.
>
> What do you think?

That is a good question.
I think option 2 is better, because option 1 stops the enhancement.
On current README file, makedumpfile needs elfutils-0.125 or latter,
and it should be changed to newer.
Anyway, I will be digging more for compling it on most envrionments.


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2011-08-10  3:30 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-17 20:01 [PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo Mahesh J Salgaonkar
2011-07-15  9:35 ` Ken'ichi Ohmichi
2011-07-15 10:21   ` Mahesh Jagannath Salgaonkar
2011-07-19  2:27     ` Ken'ichi Ohmichi
2011-07-19  9:59       ` Mahesh Jagannath Salgaonkar
2011-07-19 13:08         ` Ken'ichi Ohmichi
2011-07-25  8:11 ` Ken'ichi Ohmichi
2011-07-27  6:09   ` Mahesh Jagannath Salgaonkar
2011-07-28  9:11     ` Ken'ichi Ohmichi
2011-07-28 10:38       ` Mahesh Jagannath Salgaonkar
2011-07-29  7:21         ` Ken'ichi Ohmichi
2011-08-09 17:42           ` Mahesh J Salgaonkar
2011-08-10  2:30             ` Ken'ichi Ohmichi
2011-07-28 15:11       ` Mahesh Jagannath Salgaonkar
2011-07-29  7:24         ` Ken'ichi Ohmichi
     [not found] <CAA393vjc3vE3PG7EW70+8q3rTfv+yxcN-MbVGvH-nSUE9kCqVw@mail.gmail.com>
2011-07-15 15:08 ` Ken'ichi Ohmichi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.