All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/7] makedumpfile security key filtering with eppic
@ 2012-12-14  9:25 Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 1/7] Initialize and setup eppic Aravinda Prasad
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:25 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

makedumpfile security key filtering enhancement - Add Eppic language
support (formerly known as SIAL) to specify rules to scrub data in a
dumpfile. Eppic was previously part of crash source code repository.

The following series of patches enhance the makedumpfile to provide
a more powerful way to specify rules and commands to traverse and
erase complex data structures in a dump file by integrating Embeddable
Pre-Processor and Interpreter for C (eppic).

Eppic is an interpreter that facilitates access to the symbol and type
information stored in an executable image or a dump file. Eppic defines
a language semantic which is similar to C. Eppic macros can be used to
specify rules/commands to erase data in an image file. makedumpfile
will interpret the rules/commands provided by eppic macros with the
help of eppic library and will suitably erase the required data in a
dump file. Eppic provides a lot of language constructs like conditional
statements, logical and arithmetic operators, nested loops, functions,
etc., to traverse nested lists and trees and conditionally erase data
in the dump file, enabling users to literally erase any data in the
dump file which is accessible through global symbols.

The series of patches integrates eppic with makdumpfile. These patches
require eppic library libeppic.a and eppic_api.h header file. The
libeppic.a library can be built from the eppic source code available
at the following URL:

http://code.google.com/p/eppic/

TODO:

  - Currently, works only for symbols in vmlinux, extend it to module
    symbols
  - Functionality support:
    - Implement the following callback functions.
      - apialignment
      - apigetenum
      - apigetdefs
    - Other functionalities specified in the code with TODO tag
  - Support specifying eppic macros in makedumpfile.conf file
  - Update erase info

Changelog from v2 to v3:
  - Re-based to v1.5.1
  - Removed EPPIC=on option from Makefile.
  - Dynamically loads eppic shared object instead of statically linking
    - Based on the discussion in the mailing list
    - http://lists.infradead.org/pipermail/kexec/2012-December/007450.html
    - Only patches 1 and 2 are modified

Changelog from v1 to v2:

  - Re-based to v1.5.0
  - Introduced EPPIC=on in makefile, and hence eppic is now optional
  - Incorporated review comments from Atsushi
  - Minor formatting changes

Regards,
Aravinda
---

Aravinda Prasad (7):
      Initialize and setup eppic
      makedumpfile and eppic interface layer
      Eppic call back functions to query a dump image
      Implement apigetctype call back function
      Implement apimember and apigetrtype call back functions
      Extend eppic built-in functions to include memset function
      Support fully typed symbol access mode


 Makefile          |    5 -
 dwarf_info.c      |  367 +++++++++++++++++++++++++++++++++++++++++++
 dwarf_info.h      |   18 ++
 erase_info.c      |   91 ++++++++++-
 erase_info.h      |    1 
 extension_eppic.c |  451 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 extension_eppic.h |   75 +++++++++
 makedumpfile.c    |    7 +
 makedumpfile.h    |    6 +
 9 files changed, 1016 insertions(+), 5 deletions(-)
 create mode 100644 extension_eppic.c
 create mode 100644 extension_eppic.h

-- 
Aravinda Prasad


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

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

* [PATCH v3 1/7] Initialize and setup eppic
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
@ 2012-12-14  9:26 ` Aravinda Prasad
  2012-12-20  8:45   ` Atsushi Kumagai
  2012-12-14  9:26 ` [PATCH v3 2/7] makedumpfile and eppic interface layer Aravinda Prasad
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:26 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

This patch contains routines which initialize eppic and register call
back function which will be called whenever a new eppic macro is loaded
using eppic_load() API. The registered call back function executes the
eppic macro as soon as it is loaded.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 Makefile          |    5 +++
 extension_eppic.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 extension_eppic.h |   23 +++++++++++++++
 3 files changed, 111 insertions(+), 1 deletions(-)
 create mode 100644 extension_eppic.c
 create mode 100644 extension_eppic.h

diff --git a/Makefile b/Makefile
index e6c4e5d..f123a5f 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ $(OBJ_ARCH): $(SRC_ARCH)
 	$(CC) $(CFLAGS_ARCH) -c -o ./$@ ./$(@:.o=.c) 
 
 makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
-	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_PART) $(OBJ_ARCH) -o $@ $< $(LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_PART) $(OBJ_ARCH) -rdynamic -o $@ $< $(LIBS)
 	echo .TH MAKEDUMPFILE 8 \"$(DATE)\" \"makedumpfile v$(VERSION)\" \"Linux System Administrator\'s Manual\" > temp.8
 	grep -v "^.TH MAKEDUMPFILE 8" makedumpfile.8 >> temp.8
 	mv temp.8 makedumpfile.8
@@ -79,6 +79,9 @@ makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
 	mv temp.5 makedumpfile.conf.5
 	gzip -c ./makedumpfile.conf.5 > ./makedumpfile.conf.5.gz
 
+eppic_makedumpfile.so: extension_eppic.c
+	$(CC) $(CFLAGS) -nostartfiles -shared -rdynamic -o $@ extension_eppic.c -fPIC -leppic
+
 clean:
 	rm -f $(OBJ) $(OBJ_PART) $(OBJ_ARCH) makedumpfile makedumpfile.8.gz makedumpfile.conf.5.gz
 
diff --git a/extension_eppic.c b/extension_eppic.c
new file mode 100644
index 0000000..48a3cbe
--- /dev/null
+++ b/extension_eppic.c
@@ -0,0 +1,84 @@
+/*
+ * extension_eppic.c
+ *
+ * Created by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
+ *
+ * Copyright (C) 2012  IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "extension_eppic.h"
+
+/*
+ * Most of the functions included in this file performs similar
+ * functionality as in the applications/crash/eppic.c file part of
+ * eppic, but uses DWARF instead of gdb. Few of the functions are
+ * reused directly which are acknowledged in the comment before the
+ * function.
+ */
+
+/*
+ * This is the call back function called when a new eppic macro is
+ * loaded. This will execute the loaded eppic macro.
+ *
+ * "fname" is considered as the entry point of an eppic macro only if
+ * the following functions are defined:
+ *
+ *  fname_help()
+ *  fname_usage()
+ *
+ * These functions have no relevance in makedumpfile context as
+ * makedumpfile automatically executes the eppic macro by calling the
+ * entry point and user will not have any option to execute the usage
+ * or help functions. However they are required to identify the entry
+ * points in the eppic macro.
+ */
+void
+reg_callback(char *name, int load)
+{
+	char fname[MAX_SYMNAMELEN];
+
+	/* Nothing to process for unload request */
+	if (!load)
+		return;
+
+	snprintf(fname, sizeof(fname), "%s_help", name);
+	if (eppic_chkfname(fname, 0)) {
+		snprintf(fname, sizeof(fname), "%s_usage", name);
+		if (eppic_chkfname(fname, 0))
+			eppic_cmd(name, NULL, 0);
+	}
+	return;
+}
+
+
+/* Initialize eppic */
+int
+_init()
+{
+	if (eppic_open() >= 0) {
+
+		/* Register call back functions */
+		eppic_apiset(NULL, 3, sizeof(long), 0);
+
+		/* set the new function callback */
+		eppic_setcallback(reg_callback);
+
+		return 0;
+	}
+	return 1;
+}
+
diff --git a/extension_eppic.h b/extension_eppic.h
new file mode 100644
index 0000000..ca74ce4
--- /dev/null
+++ b/extension_eppic.h
@@ -0,0 +1,23 @@
+/*
+ * extension_eppic.h
+ *
+ * Created by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
+ *
+ * Copyright (C) 2012  IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _EXTENSION_EPPIC_H
+#define _EXTENSION_EPPIC_H
+
+#include "eppic_api.h"
+
+#endif /* _EXTENSION_EPPIC_H */


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

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

* [PATCH v3 2/7] makedumpfile and eppic interface layer
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 1/7] Initialize and setup eppic Aravinda Prasad
@ 2012-12-14  9:26 ` Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 3/7] Eppic call back functions to query a dump image Aravinda Prasad
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:26 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

This patch extends the makedumpfile functionality to include eppic
language support. The patch dynamically loads the makedumpfile specific
shared object and calls the eppic_load function in shared object to
load/compile and execute the specified eppic macros.

This patch also includes "--eppic" option to makedumpfile command to
specify the eppic macro or the directory containing eppic macros. The
specified eppic macro will be executed to scrub the data in the
dumpfile. In case of a directory, all the eppic macros inside the
directory will be executed for scrubbing the data.

TODO
	- Support specifying eppic macros in the makedumpfile.conf file.
	  A new command should be added to makedumpfile.conf to identify
	  an eppic macro. This command could be used in any section of
	  the makedumpfile.conf, where the section name indicates the kernel
	  module name. makedumpfile will only search for symbols encountered
	  by eppic macro only in the specified module. Because, searching
	  these symbols in all the modules will cause huge performance
	  overhead.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 erase_info.c      |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 extension_eppic.h |    1 +
 makedumpfile.c    |    7 +++++-
 makedumpfile.h    |    6 +++++
 4 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/erase_info.c b/erase_info.c
index e2e6a52..0b6dcf4 100644
--- a/erase_info.c
+++ b/erase_info.c
@@ -21,6 +21,8 @@
 #include "dwarf_info.h"
 #include "erase_info.h"
 
+#include <dlfcn.h>
+
 struct erase_info	*erase_info = NULL;
 unsigned long		num_erase_info = 1; /* Node 0 is unused. */
 
@@ -1811,6 +1813,48 @@ process_config_file(const char *name_config)
 	return TRUE;
 }
 
+
+/* Process the eppic macro using eppic library */
+static int
+process_eppic_file(char *name_config)
+{
+	void *handle;
+	void (*eppic_load)(char *), (*eppic_unload)(char *);
+
+	/*
+	 * Dynamically load the eppic_makedumpfile.so library.
+	 * Dynamically loading will cause _init function to be called
+	 */
+	handle = dlopen("eppic_makedumpfile.so", RTLD_LAZY | RTLD_GLOBAL);
+	if (!handle) {
+		ERRMSG("dlopen failed: %s\n", dlerror());
+		return FALSE;
+	}
+
+	/* TODO
+	 * Support specifying eppic macros in makedumpfile.conf file
+	 */
+
+	eppic_load = dlsym(handle, "eppic_load");
+	if (!eppic_load) {
+		ERRMSG("Could not find eppic_load function\n");
+		return FALSE;
+	}
+
+	eppic_unload = dlsym(handle, "eppic_unload");
+	if (!eppic_unload)
+		ERRMSG("Could not find eppic_unload function\n");
+
+	/* Load/compile, execute and unload the eppic macro */
+	eppic_load(name_config);
+	eppic_unload(name_config);
+
+	if (dlclose(handle))
+		ERRMSG("dlclose failed: %s\n", dlerror());
+
+	return TRUE;
+}
+
 static void
 split_filter_info(struct filter_info *prev, unsigned long long next_paddr,
 						size_t size)
@@ -1904,7 +1948,7 @@ extract_filter_info(unsigned long long start_paddr,
 int
 gather_filter_info(void)
 {
-	int ret;
+	int ret = TRUE;
 
 	/*
 	 * Before processing filter config file, load the symbol data of
@@ -1915,7 +1959,17 @@ gather_filter_info(void)
 	if (!load_module_symbols())
 		return FALSE;
 
-	ret = process_config_file(info->name_filterconfig);
+	/*
+	 * XXX: We support specifying both makedumpfile.conf and
+	 * eppic macro at the same time. Whether to retain or discard the
+	 * functionality provided by makedumpfile.conf is open for
+	 * discussion
+	 */
+	if (info->name_filterconfig)
+		ret = process_config_file(info->name_filterconfig);
+
+	if (info->name_eppic_config)
+		ret &= process_eppic_file(info->name_eppic_config);
 
 	/*
 	 * Remove modules symbol information, we dont need now.
diff --git a/extension_eppic.h b/extension_eppic.h
index ca74ce4..34396e4 100644
--- a/extension_eppic.h
+++ b/extension_eppic.h
@@ -21,3 +21,4 @@
 #include "eppic_api.h"
 
 #endif /* _EXTENSION_EPPIC_H */
+
diff --git a/makedumpfile.c b/makedumpfile.c
index 314dc46..087f556 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -7330,7 +7330,8 @@ retry:
 		}
 	}
 
-	if (info->name_filterconfig && !gather_filter_info())
+	if ((info->name_filterconfig || info->name_eppic_config)
+			&& !gather_filter_info())
 		return FALSE;
 
 	if (!create_dump_bitmap())
@@ -8228,6 +8229,7 @@ static struct option longopts[] = {
 	{"diskset", required_argument, NULL, 'k'},
 	{"non-cyclic", no_argument, NULL, 'Y'},
 	{"cyclic-buffer", required_argument, NULL, 'Z'},
+	{"eppic", required_argument, NULL, 'S'},
 	{0, 0, 0, 0}
 };
 
@@ -8326,6 +8328,9 @@ main(int argc, char *argv[])
 		case 's':
 			info->flag_split = 1;
 			break;
+		case 'S':
+			info->name_eppic_config = optarg;
+			break;
 		case 'r':
 			info->flag_reassemble = 1;
 			break;
diff --git a/makedumpfile.h b/makedumpfile.h
index d2bdc0c..a9b7680 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -905,6 +905,12 @@ struct DumpInfo {
 	FILE		*file_filterconfig;
 
 	/*
+	 * Filter config file containing eppic language filtering rules
+	 * to filter out kernel data from vmcore
+	 */
+	char		*name_eppic_config;
+
+	/*
 	 * diskdimp info:
 	 */
 	int		block_order;


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

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

* [PATCH v3 3/7] Eppic call back functions to query a dump image
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 1/7] Initialize and setup eppic Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 2/7] makedumpfile and eppic interface layer Aravinda Prasad
@ 2012-12-14  9:26 ` Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 4/7] Implement apigetctype call back function Aravinda Prasad
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:26 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

This patch implements a series of apigetuint* call back functions
which are used to access data from the dump image. Eppic uses these
call back functions to fetch the actual value of the global variables.

This patch also adds other call back functions as a place holder which
will be implemented in later patches. This is mainly to avoid
compilation error while registering the call back functions using
eppic_apiset() function.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 extension_eppic.c |  128 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 extension_eppic.h |   49 ++++++++++++++++++++
 2 files changed, 175 insertions(+), 2 deletions(-)

diff --git a/extension_eppic.c b/extension_eppic.c
index 48a3cbe..774d16e 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <fcntl.h>
 
+#include "makedumpfile.h"
 #include "extension_eppic.h"
 
 /*
@@ -64,6 +65,131 @@ reg_callback(char *name, int load)
 	return;
 }
 
+/*
+ * Call back functions for eppic to query the dump image
+ */
+
+static int
+apigetmem(ull iaddr, void *p, int nbytes)
+{
+	return readmem(VADDR, iaddr, p, nbytes);
+}
+
+static int
+apiputmem(ull iaddr, void *p, int nbytes)
+{
+	return 1;
+}
+
+static char *
+apimember(char *mname, ull pidx, type_t *tm,
+		member_t *m, ull *lidx)
+{
+	return 0;
+}
+
+static int
+apigetctype(int ctype, char *name, type_t *tout)
+{
+	return 0;
+}
+
+static char *
+apigetrtype(ull idx, type_t *t)
+{
+	return "";
+}
+
+static int
+apialignment(ull idx)
+{
+	return 0;
+}
+
+int
+apigetval(char *name, ull *val, VALUE_S *value)
+{
+	ull ptr = 0;
+
+	ptr = get_symbol_addr(name);
+	if (!ptr)
+		return 0;
+
+	*val = ptr;
+	return 1;
+}
+
+static enum_t *
+apigetenum(char *name)
+{
+	return 0;
+}
+
+static def_t *
+apigetdefs(void)
+{
+	return 0;
+}
+
+static uint8_t
+apigetuint8(void *ptr)
+{
+	uint8_t val;
+	if (!readmem(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint8_t) -1;
+	return val;
+}
+
+static uint16_t
+apigetuint16(void *ptr)
+{
+	uint16_t val;
+	if (!readmem(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint16_t) -1;
+	return val;
+}
+
+static uint32_t
+apigetuint32(void *ptr)
+{
+	uint32_t val;
+	if (!readmem(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint32_t) -1;
+	return val;
+}
+
+static uint64_t
+apigetuint64(void *ptr)
+{
+	uint64_t val;
+	if (!readmem(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint64_t) -1;
+	return val;
+}
+
+static char *
+apifindsym(char *p)
+{
+	return NULL;
+}
+
+apiops icops = {
+	apigetmem,
+	apiputmem,
+	apimember,
+	apigetctype,
+	apigetrtype,
+	apialignment,
+	apigetval,
+	apigetenum,
+	apigetdefs,
+	apigetuint8,
+	apigetuint16,
+	apigetuint32,
+	apigetuint64,
+	apifindsym
+};
+
 
 /* Initialize eppic */
 int
@@ -72,7 +198,7 @@ _init()
 	if (eppic_open() >= 0) {
 
 		/* Register call back functions */
-		eppic_apiset(NULL, 3, sizeof(long), 0);
+		eppic_apiset(&icops, 3, sizeof(long), 0);
 
 		/* set the new function callback */
 		eppic_setcallback(reg_callback);
diff --git a/extension_eppic.h b/extension_eppic.h
index 34396e4..beb68e4 100644
--- a/extension_eppic.h
+++ b/extension_eppic.h
@@ -20,5 +20,52 @@
 
 #include "eppic_api.h"
 
-#endif /* _EXTENSION_EPPIC_H */
+/*
+ * MEMBER_S, ENUM_S, DEF_S and TYPE_S are extracts from eppic header
+ * file eppic.h. The reason for not including the eppic.h header file
+ * in this file is because, lot of things in eppic.h are not required
+ * for makedumpfile extension.
+ */
+
+/* member information */
+typedef MEMBER_S {
+
+	char *name;
+	int offset; /* offset from top of structure */
+	int size;   /* size in bytes of the member or of the bit array */
+	int fbit;   /* fist bit (-1) is not a bit field */
+	int nbits;  /* number of bits for this member */
+	int value;  /* for a enum member, the corresponding value_t */
+
+} member_t;
+
+/* list to hold enum constant information */
+typedef ENUM_S {
+	struct enum_s *next;
+	char *name;
+	int value;
 
+} enum_t;
+
+/* list of macro symbols and there corresponding value_ts */
+typedef DEF_S {
+	struct def_s *next;
+	char *name;
+	char *val;
+
+} def_t;
+
+
+typedef TYPE_S {
+	int type;   /* type_t of type_t */
+	ull idx;    /* index to basetype_t or ctype_t */
+	int size;   /* size of this item */
+	/* ... next fields are use internally */
+	int typattr;    /* base type_t qualifiers */
+	int ref;    /* level of reference */
+	int fct;        /* 1 if function pointer */
+	int *idxlst;    /* points to list of indexes if array */
+	ull rtype;  /* type_t a reference refers too */
+} type_t;
+
+#endif /* _EXTENSION_EPPIC_H */


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

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

* [PATCH v3 4/7] Implement apigetctype call back function
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
                   ` (2 preceding siblings ...)
  2012-12-14  9:26 ` [PATCH v3 3/7] Eppic call back functions to query a dump image Aravinda Prasad
@ 2012-12-14  9:26 ` Aravinda Prasad
  2012-12-20  8:45   ` Atsushi Kumagai
  2012-12-14  9:26 ` [PATCH v3 5/7] Implement apimember and apigetrtype call back functions Aravinda Prasad
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:26 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

libeppic will call apigetctype call back function whenever it
encounters a token in the eppic macro. The call back function will use
DWARF to query information related to the requested token and will
pass it back to eppic using libeppic API calls. If the token does not
exist, then apigetctype call returns 0.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 dwarf_info.c      |  109 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 dwarf_info.h      |    9 ++++
 extension_eppic.c |   28 +++++++++++++-
 3 files changed, 145 insertions(+), 1 deletions(-)

diff --git a/dwarf_info.c b/dwarf_info.c
index 09a8e1e..a8a87e1 100644
--- a/dwarf_info.c
+++ b/dwarf_info.c
@@ -51,6 +51,7 @@ struct dwarf_info {
 	long	enum_number;		/* OUT */
 	unsigned char	type_flag;	/* OUT */
 	char	src_name[LEN_SRCFILE];	/* OUT */
+	Dwarf_Off die_offset;		/* OUT */
 };
 static struct dwarf_info	dwarf_info;
 
@@ -102,6 +103,22 @@ is_search_typedef(int cmd)
 }
 
 static int
+is_search_domain(int cmd)
+{
+	if ((cmd == DWARF_INFO_GET_DOMAIN_STRUCT)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_TYPEDEF)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_ARRAY)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_UNION)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_ENUM)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_REF)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_STRING)
+		|| (cmd == DWARF_INFO_GET_DOMAIN_BASE))
+		return TRUE;
+	else
+		return FALSE;
+}
+
+static int
 process_module (Dwfl_Module *dwflmod,
 		void **userdata __attribute__ ((unused)),
 		const char *name __attribute__ ((unused)),
@@ -750,6 +767,74 @@ search_symbol(Dwarf_Die *die, int *found)
 }
 
 static void
+search_domain(Dwarf_Die *die, int *found)
+{
+	int tag;
+	const char *name;
+	short flag = 0;
+	Dwarf_Die die_type;
+
+	do {
+		tag  = dwarf_tag(die);
+		name = dwarf_diename(die);
+
+		/*
+		 * Descend into members and search for the
+		 * needed domain there.
+		 */
+		if (!name) {
+			if (!get_die_type(die, &die_type))
+				continue;
+
+			if (is_container(&die_type)) {
+				Dwarf_Die child;
+
+				if (dwarf_child(&die_type, &child) != 0)
+					continue;
+
+				search_domain(&child, found);
+
+				if (*found)
+					return;
+			}
+		}
+
+		if ((!name) || strcmp(name, dwarf_info.symbol_name))
+			continue;
+
+		switch (dwarf_info.cmd) {
+		case DWARF_INFO_GET_DOMAIN_STRUCT:
+			if (tag == DW_TAG_structure_type)
+				flag = 1;
+			break;
+		case DWARF_INFO_GET_DOMAIN_UNION:
+			if (tag == DW_TAG_union_type)
+				flag = 1;
+			break;
+		case DWARF_INFO_GET_DOMAIN_TYPEDEF:
+			if (tag == DW_TAG_typedef)
+				flag = 1;
+			break;
+		/* TODO
+		 * Implement functionality for the rest of the domains
+		 */
+		}
+
+		if (!flag)
+			continue;
+
+		dwarf_info.struct_size = dwarf_bytesize(die);
+
+		if (dwarf_info.struct_size > 0) {
+			if (found)
+				*found = TRUE;
+			dwarf_info.die_offset = dwarf_dieoffset(die);
+			break;
+		}
+	} while (!dwarf_siblingof(die, die));
+}
+
+static void
 search_die_tree(Dwarf_Die *die, int *found)
 {
 	Dwarf_Die child;
@@ -774,6 +859,9 @@ search_die_tree(Dwarf_Die *die, int *found)
 
 	else if (is_search_typedef(dwarf_info.cmd))
 		search_typedef(die, found);
+
+	else if (is_search_domain(dwarf_info.cmd))
+		search_domain(die, found);
 }
 
 static int
@@ -1166,6 +1254,27 @@ get_source_filename(char *structname, char *src_name, int cmd)
 }
 
 /*
+ * Get the domain information of the symbol
+ */
+long
+get_domain(char *symname, int cmd, unsigned long long *die)
+{
+	dwarf_info.cmd         = cmd;
+	dwarf_info.symbol_name = symname;
+	dwarf_info.type_name   = NULL;
+	dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
+	dwarf_info.die_offset  = 0;
+
+	if (!get_debug_info())
+		return 0;
+
+	if (die)
+		*die = (unsigned long long) dwarf_info.die_offset;
+
+	return dwarf_info.struct_size;
+}
+
+/*
  * Set the dwarf_info with kernel/module debuginfo file information.
  */
 int
diff --git a/dwarf_info.h b/dwarf_info.h
index 185cbb6..074b5cc 100644
--- a/dwarf_info.h
+++ b/dwarf_info.h
@@ -47,6 +47,14 @@ enum {
 	DWARF_INFO_GET_SYMBOL_TYPE,
 	DWARF_INFO_GET_MEMBER_TYPE,
 	DWARF_INFO_GET_ENUMERATION_TYPE_SIZE,
+	DWARF_INFO_GET_DOMAIN_STRUCT,
+	DWARF_INFO_GET_DOMAIN_TYPEDEF,
+	DWARF_INFO_GET_DOMAIN_ARRAY,
+	DWARF_INFO_GET_DOMAIN_UNION,
+	DWARF_INFO_GET_DOMAIN_ENUM,
+	DWARF_INFO_GET_DOMAIN_REF,
+	DWARF_INFO_GET_DOMAIN_STRING,
+	DWARF_INFO_GET_DOMAIN_BASE,
 };
 
 char *get_dwarf_module_name(void);
@@ -61,6 +69,7 @@ char *get_member_type_name(char *structname, char *membername, int cmd, long *si
 long get_array_length(char *name01, char *name02, unsigned int cmd);
 long get_enum_number(char *enum_name);
 int get_source_filename(char *structname, char *src_name, int cmd);
+long get_domain(char *symname, int cmd, unsigned long long *die);
 int set_dwarf_debuginfo(char *mod_name, char *os_release, char *name_debuginfo, int fd_debuginfo);
 
 #endif  /* DWARF_INFO_H */
diff --git a/extension_eppic.c b/extension_eppic.c
index 774d16e..3fa3e88 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -91,7 +91,33 @@ apimember(char *mname, ull pidx, type_t *tm,
 static int
 apigetctype(int ctype, char *name, type_t *tout)
 {
-	return 0;
+	long size = 0;
+	unsigned long long die = 0;
+
+	switch (ctype) {
+	case V_TYPEDEF:
+		size = get_domain(name, DWARF_INFO_GET_DOMAIN_TYPEDEF, &die);
+		break;
+	case V_STRUCT:
+		size = get_domain(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
+		break;
+	case V_UNION:
+		size = get_domain(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
+		break;
+	/* TODO
+	 * Implement for all the domains
+	 */
+	}
+
+	if (size <= 0 || !die)
+		return 0;
+
+	/* populate */
+	eppic_type_settype(tout, ctype);
+	eppic_type_setsize(tout, size);
+	eppic_type_setidx(tout, (ull)(unsigned long)die);
+	eppic_pushref(tout, 0);
+	return 1;
 }
 
 static char *


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

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

* [PATCH v3 5/7] Implement apimember and apigetrtype call back functions
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
                   ` (3 preceding siblings ...)
  2012-12-14  9:26 ` [PATCH v3 4/7] Implement apigetctype call back function Aravinda Prasad
@ 2012-12-14  9:26 ` Aravinda Prasad
  2012-12-14  9:26 ` [PATCH v3 6/7] Extend eppic built-in functions to include memset function Aravinda Prasad
  2012-12-14  9:27 ` [PATCH v3 7/7] Support fully typed symbol access mode Aravinda Prasad
  6 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:26 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

The patch includes functionality for apimember and apigetrtype eppic
callback routines along with helper functions to fetch information
related to the member of the structure/union

Whenever a structure/union member is accessed inside the eppic macro,
eppic will query makedumpfile through call back functions requesting
more information on the structure or union member. The information
includes member name, offset from structure, data type and size.
makedumpfile will get all these information using DWARF and pass
back to eppic using libeppic API calls.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 dwarf_info.c      |  206 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 dwarf_info.h      |    7 ++
 extension_eppic.c |  179 +++++++++++++++++++++++++++++++++++++++++++++-
 extension_eppic.h |    2 +
 4 files changed, 390 insertions(+), 4 deletions(-)

diff --git a/dwarf_info.c b/dwarf_info.c
index a8a87e1..f66d351 100644
--- a/dwarf_info.c
+++ b/dwarf_info.c
@@ -463,6 +463,29 @@ get_dwarf_base_type(Dwarf_Die *die)
 	return TRUE;
 }
 
+/*
+ * Get the die, given the offset
+ */
+static int
+get_die_from_offset(Dwarf_Off offset, Dwarf_Die *die)
+{
+	if (!init_dwarf_info())
+		return FALSE;
+
+	if ((!offset) || (!die))
+		return FALSE;
+
+	if (!dwarf_offdie(dwarf_info.dwarfd, offset, die)) {
+		ERRMSG("Can't find the DIE.\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/*
+ * Function for searching struct page.union.struct.mapping.
+ */
 static int
 is_container(Dwarf_Die *die)
 {
@@ -1275,6 +1298,189 @@ get_domain(char *symname, int cmd, unsigned long long *die)
 }
 
 /*
+ * Get the number of fields in a structure or union provided the
+ * die offset of the structure or union
+ */
+int
+get_die_nfields(unsigned long long die_off)
+{
+	int tag, nfields = 0;
+	Dwarf_Die result, child, *die;
+
+	if (!get_die_from_offset((Dwarf_Off) die_off, &result)) {
+		ERRMSG("Can't find the DIE.\n");
+		return -1;
+	}
+
+	die = &result;
+	tag = dwarf_tag(die);
+	if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
+		ERRMSG("DIE is not of structure or union type.\n");
+		return -1;
+	}
+
+	if (dwarf_child(die, &child) != 0)
+		return -1;
+
+	/* Find the number of fields in the structure */
+	die = &child;
+	do {
+		tag = dwarf_tag(die);
+		if (tag == DW_TAG_member)
+			nfields++;
+		else
+			continue;
+	} while (!dwarf_siblingof(die, die));
+
+	return nfields;
+}
+
+/*
+ * Get the information of the structure member given by index
+ */
+int
+get_die_member(unsigned long long die_off, int index, long *offset,
+		char **name, int *nbits, int *fbits, unsigned long long *m_die)
+{
+	int tag, size, nfields = 0;
+	Dwarf_Die result, child, die_base, *die;
+
+	if (!offset || !nbits || !fbits || !name || !m_die)
+		return -1;
+
+	if (!get_die_from_offset((Dwarf_Off) die_off, &result)) {
+		ERRMSG("Can't find the DIE.\n");
+		return -1;
+	}
+
+	die = &result;
+	tag = dwarf_tag(die);
+	if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
+		ERRMSG("DIE is not of structure or union type.\n");
+		return -1;
+	}
+
+	if (dwarf_child(die, &child) != 0)
+		return -1;
+
+	/* Find the correct field in the structure */
+	die = &child;
+	do {
+		tag = dwarf_tag(die);
+		if (tag == DW_TAG_member) {
+			if (nfields == index)
+				break;
+			else
+				nfields++;
+		}
+	} while (!dwarf_siblingof(die, die));
+
+	if (nfields != index) {
+		ERRMSG("No member found at index %d.\n", index);
+		return -1;
+	}
+
+	/* Fill in the required info for the member */
+	if (!get_data_member_location(die, offset))
+		*offset = 0;
+
+	*name = dwarf_diename(die);
+	*m_die = dwarf_dieoffset(die);
+
+	get_die_type(die, &die_base);
+	if (dwarf_tag(&die_base) == DW_TAG_array_type) {
+		dwarf_info.array_length = 0;
+		get_data_array_length(die);
+		size = dwarf_info.array_length;
+	} else {
+		size = dwarf_bytesize(&die_base);
+	}
+
+	/* TODO
+	 * Correctly update fbits and nbits
+	 */
+	*nbits = *fbits = 0;
+
+	if (size < 0)
+		return 0;
+	else
+		return size;
+}
+
+/*
+ * Get the die attribute type
+ */
+int
+get_die_attr_type(unsigned long long die_off, int *type_flag,
+		unsigned long long *die_attr_off)
+{
+	Dwarf_Die result;
+
+	if (!die_attr_off)
+		return FALSE;
+
+	if (!get_die_from_offset((Dwarf_Off) die_off, &result)) {
+		ERRMSG("Can't find the DIE.\n");
+		return FALSE;
+	}
+
+	if (!get_die_type(&result, &result))
+		return FALSE;
+
+	*die_attr_off = dwarf_dieoffset(&result);
+	*type_flag = dwarf_tag(&result);
+	return TRUE;
+}
+
+/*
+ * Get name attribute given the die offset
+ */
+char *
+get_die_name(unsigned long long die_off)
+{
+	Dwarf_Die result;
+
+	if (!die_off)
+		return NULL;
+
+	if (!get_die_from_offset((Dwarf_Off) die_off, &result)) {
+		ERRMSG("Can't find the DIE.\n");
+		return NULL;
+	}
+
+	return dwarf_diename(&result);
+}
+
+/*
+ * Get length attribute given the die offset
+ */
+int
+get_die_length(unsigned long long die_off, int flag)
+{
+	Dwarf_Die result, die_base;
+
+	if (!die_off)
+		return FALSE;
+
+	if (!get_die_from_offset((Dwarf_Off) die_off, &result)) {
+		ERRMSG("Can't find the DIE.\n");
+		return FALSE;
+	}
+
+	if (flag)
+		return dwarf_bytesize(&result);
+
+	get_die_type(&result, &die_base);
+	if (dwarf_tag(&die_base) == DW_TAG_array_type) {
+		dwarf_info.array_length = 0;
+		get_data_array_length(&result);
+		return dwarf_info.array_length;
+	} else {
+		return dwarf_bytesize(&die_base);
+	}
+}
+
+/*
  * Set the dwarf_info with kernel/module debuginfo file information.
  */
 int
diff --git a/dwarf_info.h b/dwarf_info.h
index 074b5cc..d1d15a9 100644
--- a/dwarf_info.h
+++ b/dwarf_info.h
@@ -70,6 +70,13 @@ long get_array_length(char *name01, char *name02, unsigned int cmd);
 long get_enum_number(char *enum_name);
 int get_source_filename(char *structname, char *src_name, int cmd);
 long get_domain(char *symname, int cmd, unsigned long long *die);
+int get_die_nfields(unsigned long long die_off);
+int get_die_member(unsigned long long die_off, int index, long *offset,
+	char **name, int *nbits, int *fbits, unsigned long long *m_die);
+int get_die_attr_type(unsigned long long die_off, int *type_flag,
+	unsigned long long *die_attr_off);
+char *get_die_name(unsigned long long die_off);
+int get_die_length(unsigned long long die_off, int flag);
 int set_dwarf_debuginfo(char *mod_name, char *os_release, char *name_debuginfo, int fd_debuginfo);
 
 #endif  /* DWARF_INFO_H */
diff --git a/extension_eppic.c b/extension_eppic.c
index 3fa3e88..8d0027f 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -19,9 +19,11 @@
 #include <string.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <dwarf.h>
 
 #include "makedumpfile.h"
 #include "extension_eppic.h"
+#include "print_info.h"
 
 /*
  * Most of the functions included in this file performs similar
@@ -66,6 +68,35 @@ reg_callback(char *name, int load)
 }
 
 /*
+ * This function is a copy of eppic_setupidx() function in
+ * applications/crash/eppic.c file from eppic source code
+ * repository.
+ *
+ * set idx value to actual array indexes from specified size
+ */
+static void
+eppic_setupidx(TYPE_S *t, int ref, int nidx, int *idxlst)
+{
+	/* put the idxlst in index size format */
+	if (nidx) {
+		int i;
+		for (i = 0; i < nidx - 1; i++) {
+			/* kludge for array dimensions of [1] */
+			if (idxlst[i + 1] == 0)
+				idxlst[i + 1] = 1;
+			idxlst[i] = idxlst[i] / idxlst[i + 1];
+		}
+
+		/* divide by element size for last element bound */
+		if (ref)
+			idxlst[i] /= eppic_defbsize();
+		else
+			idxlst[i] /= eppic_type_getsize(t);
+		eppic_type_setidxlst(t, idxlst);
+	}
+}
+
+/*
  * Call back functions for eppic to query the dump image
  */
 
@@ -81,11 +112,151 @@ apiputmem(ull iaddr, void *p, int nbytes)
 	return 1;
 }
 
+/*
+ * Drill down the type of the member and update eppic with information
+ * about the member
+ */
 static char *
-apimember(char *mname, ull pidx, type_t *tm,
-		member_t *m, ull *lidx)
+drilldown(ull offset, type_t *t)
 {
-	return 0;
+	int type_flag, len = 0, t_len = 0, nidx = 0;
+	int fctflg = 0, ref = 0, *idxlst = 0;
+	ull die_off = offset, t_die_off;
+	char *tstr = NULL;
+
+	while (get_die_attr_type(die_off, &type_flag, &t_die_off)) {
+		switch (type_flag) {
+		/* typedef inserts a level of reference to the actual type */
+		case DW_TAG_pointer_type:
+			ref++;
+			die_off = t_die_off;
+			/*
+			 * This could be a void *, in which case the drill
+			 * down stops here
+			 */
+			if (!get_die_attr_type(die_off, &type_flag,
+						&t_die_off)) {
+				/* make it a char* */
+				eppic_parsetype("char", t, ref);
+				return eppic_strdup("");
+			}
+			break;
+		/* Handle pointer to function */
+		case DW_TAG_subroutine_type:
+			fctflg = 1;
+			die_off = t_die_off;
+			break;
+		/* Handle arrays */
+		case DW_TAG_array_type:
+			if (!idxlst) {
+				idxlst = eppic_calloc(sizeof(int) * \
+					(MAX_ARRAY_DIMENSION + 1));
+				if (!idxlst) {
+					ERRMSG("Out of memory\n");
+					return NULL;
+				}
+			}
+			if (nidx >= MAX_ARRAY_DIMENSION) {
+				ERRMSG("Too many array indexes. Max=%d\n",
+						MAX_ARRAY_DIMENSION);
+				return NULL;
+			}
+
+			/* handle multi-dimensional array */
+			len = get_die_length(die_off, FALSE);
+			t_len = get_die_length(t_die_off, FALSE);
+			if (len > 0 && t_len > 0)
+				idxlst[nidx++] = len / t_len;
+			die_off = t_die_off;
+			break;
+		/* Handle typedef */
+		case DW_TAG_typedef:
+			die_off = t_die_off;
+			break;
+		case DW_TAG_base_type:
+			eppic_parsetype(tstr = get_die_name(t_die_off), t, 0);
+			goto out;
+		case DW_TAG_union_type:
+			eppic_type_mkunion(t);
+			goto label;
+		case DW_TAG_enumeration_type:
+			eppic_type_mkenum(t);
+			goto label;
+		case DW_TAG_structure_type:
+			eppic_type_mkstruct(t);
+			goto label;
+		/* Unknown TAG ? */
+		default:
+			die_off = t_die_off;
+			break;
+		}
+	}
+
+label:
+	eppic_type_setsize(t, get_die_length(t_die_off, TRUE));
+	eppic_type_setidx(t, (ull)t_die_off);
+	tstr = get_die_name(t_die_off);
+
+out:
+	eppic_setupidx(t, ref, nidx, idxlst);
+	if (fctflg)
+		eppic_type_setfct(t, 1);
+	eppic_pushref(t, ref + (nidx ? 1 : 0));
+	if (tstr)
+		return eppic_strdup(tstr);
+	return eppic_strdup("");
+}
+
+/*
+ * Get the type, size and position information for a member of a structure.
+ */
+static char *
+apimember(char *mname, ull idx, type_t *tm, member_t *m, ull *last_index)
+{
+	int index, nfields = -1, size;
+	int nbits = 0, fbits = 0;
+	long offset;
+	ull m_die, die_off = idx;
+	char *name;
+
+	nfields = get_die_nfields(die_off);
+	/*
+	 * get_die_nfields() returns < 0 if the die is not structure type
+	 * or union type
+	 */
+	if (nfields <= 0)
+		return NULL;
+
+	/* if we're being asked the next member in a getfirst/getnext
+	 * sequence
+	 */
+	if (mname && !mname[0] && last_index && (*last_index))
+		index = *last_index;
+	else
+		index = 0;
+
+	while (index < nfields) {
+		size = get_die_member(die_off, index, &offset, &name, &nbits,
+				&fbits, &m_die);
+
+		if (size < 0)
+			return NULL;
+
+		if (!mname || !mname[0] || !strcmp(mname, name)) {
+			eppic_member_ssize(m, size);
+			if (name)
+				eppic_member_sname(m, name);
+			else
+				eppic_member_sname(m, "");
+			eppic_member_soffset(m, offset);
+			eppic_member_snbits(m, nbits);
+			eppic_member_sfbit(m, fbits);
+			*last_index = index + 1;
+			return drilldown(m_die, tm);
+		}
+		index++;
+	}
+	return NULL;
 }
 
 static int
@@ -123,7 +294,7 @@ apigetctype(int ctype, char *name, type_t *tout)
 static char *
 apigetrtype(ull idx, type_t *t)
 {
-	return "";
+	return drilldown(idx, t);
 }
 
 static int
diff --git a/extension_eppic.h b/extension_eppic.h
index beb68e4..15d7efc 100644
--- a/extension_eppic.h
+++ b/extension_eppic.h
@@ -27,6 +27,8 @@
  * for makedumpfile extension.
  */
 
+#define MAX_ARRAY_DIMENSION 16
+
 /* member information */
 typedef MEMBER_S {
 


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

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

* [PATCH v3 6/7] Extend eppic built-in functions to include memset function
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
                   ` (4 preceding siblings ...)
  2012-12-14  9:26 ` [PATCH v3 5/7] Implement apimember and apigetrtype call back functions Aravinda Prasad
@ 2012-12-14  9:26 ` Aravinda Prasad
  2012-12-14  9:27 ` [PATCH v3 7/7] Support fully typed symbol access mode Aravinda Prasad
  6 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:26 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

The memset function will be used to specify the virtual address
and the length of the data to be scrubbed in the dump file from
the eppic macro. makedumpfile will convert these requests into
filter_info nodes which will be enqueued for filtering. Existing
makedumpfile functionality reads the filter_info nodes and scrubs the
data accordingly.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 erase_info.c      |   33 ++++++++++++++++++++++++++++++++-
 erase_info.h      |    1 +
 extension_eppic.c |   20 ++++++++++++++++++++
 extension_eppic.h |    2 ++
 4 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/erase_info.c b/erase_info.c
index 0b6dcf4..cd365b1 100644
--- a/erase_info.c
+++ b/erase_info.c
@@ -68,6 +68,8 @@ struct filter_info {
 	int			erase_info_idx;	/* 0= invalid index */
 	int			size_idx;
 
+	int			erase_ch;
+
 	struct filter_info      *next;
 	unsigned short          nullify;
 };
@@ -1576,6 +1578,7 @@ update_filter_info(struct config_entry *filter_symbol,
 	fl_info->paddr   = vaddr_to_paddr(sym_addr);
 	fl_info->size    = size;
 	fl_info->nullify = filter_symbol->nullify;
+	fl_info->erase_ch = 'X';
 
 	if (insert_filter_info(fl_info)) {
 		fl_info->erase_info_idx = add_erase_info_node(filter_symbol);
@@ -1584,6 +1587,34 @@ update_filter_info(struct config_entry *filter_symbol,
 	return TRUE;
 }
 
+int
+update_filter_info_raw(unsigned long long sym_addr, int ch, int len)
+{
+	struct filter_info *fl_info;
+
+	fl_info = calloc(1, sizeof(struct filter_info));
+	if (fl_info == NULL) {
+		ERRMSG("Can't allocate filter info\n");
+		return FALSE;
+	}
+
+	fl_info->vaddr   = sym_addr;
+	fl_info->paddr   = vaddr_to_paddr(sym_addr);
+	fl_info->size    = len;
+	fl_info->nullify = 0;
+	fl_info->erase_ch = ch;
+
+	if (insert_filter_info(fl_info)) {
+		/* TODO
+		 * Add support to update erase information to the
+		 * resulting dump file
+		 */
+		fl_info->erase_info_idx = 0;
+		fl_info->size_idx = 0;
+	}
+	return TRUE;
+}
+
 static int
 initialize_iteration_entry(struct config_entry *ie,
 				char *type_name, unsigned char type_flag)
@@ -2022,7 +2053,7 @@ filter_data_buffer(unsigned char *buf, unsigned long long paddr,
 		if (fl_info.nullify)
 			memset(buf_ptr, 0, fl_info.size);
 		else
-			memset(buf_ptr, 'X', fl_info.size);
+			memset(buf_ptr, fl_info.erase_ch, fl_info.size);
 	}
 }
 
diff --git a/erase_info.h b/erase_info.h
index 636fcfa..2a9c43d 100644
--- a/erase_info.h
+++ b/erase_info.h
@@ -38,6 +38,7 @@ int gather_filter_info(void);
 void clear_filter_info(void);
 void filter_data_buffer(unsigned char *buf, unsigned long long paddr, size_t size);
 unsigned long get_size_eraseinfo(void);
+int update_filter_info_raw(unsigned long long, int, int);
 
 #endif /* _ERASE_INFO_H */
 
diff --git a/extension_eppic.c b/extension_eppic.c
index 8d0027f..85dfdcd 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -387,6 +387,22 @@ apiops icops = {
 	apifindsym
 };
 
+/* Extensions to built-in functions */
+VALUE_S *
+eppic_memset(VALUE_S *vaddr, VALUE_S *vch, VALUE_S *vlen)
+{
+	ull addr = eppic_getval(vaddr);
+	int len = eppic_getval(vlen);
+	int ch = eppic_getval(vch);
+
+	/*
+	 * Set the value at address from iaddr till iaddr + nbytes
+	 * to the value specified in variable ch
+	 */
+	update_filter_info_raw(addr, ch, len);
+	return eppic_makebtype(1);
+}
+
 
 /* Initialize eppic */
 int
@@ -400,6 +416,10 @@ _init()
 		/* set the new function callback */
 		eppic_setcallback(reg_callback);
 
+		/* Extend built-in functions to include memset */
+		eppic_builtin("int memset(char *, int, int)",
+				(bf_t *)eppic_memset);
+
 		return 0;
 	}
 	return 1;
diff --git a/extension_eppic.h b/extension_eppic.h
index 15d7efc..0a53646 100644
--- a/extension_eppic.h
+++ b/extension_eppic.h
@@ -70,4 +70,6 @@ typedef TYPE_S {
 	ull rtype;  /* type_t a reference refers too */
 } type_t;
 
+extern int update_filter_info_raw(unsigned long long, int, int);
+
 #endif /* _EXTENSION_EPPIC_H */


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

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

* [PATCH v3 7/7] Support fully typed symbol access mode
  2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
                   ` (5 preceding siblings ...)
  2012-12-14  9:26 ` [PATCH v3 6/7] Extend eppic built-in functions to include memset function Aravinda Prasad
@ 2012-12-14  9:27 ` Aravinda Prasad
  6 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-14  9:27 UTC (permalink / raw)
  To: kumagai-atsushi, kexec; +Cc: LChouinard, mahesh, tachibana, ananth, buendgen

Eppic enables access to symbols in two ways. The first, is a more
natural mode in that it makes symbols available as fully typed
entities. The second, is generic and treats all symbols as an address
to data which then needs to be cast to the proper type explicitly. The
former obviously enables an easier cut & pasting of target code into
eppic code.

Currently generic symbol access mode is supported. This patch extends
the functionality to include support for fully typed symbol access mode
(which will be the default mode) in eppic macros. User can switch to
generic symbol access mode by setting the following environmental
variable - EPPIC_LEGACY_MODE. libeppic.a will take care of handling
EPPIC_LEGACY_MODE. libeppic.a will pass NULL to VALUE_S* argument of
apigetval() call back function if EPPIC_LEGACY_MODE is set.

Refer to http://code.google.com/p/eppic/ for more information.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
 dwarf_info.c      |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 dwarf_info.h      |    2 ++
 extension_eppic.c |   24 ++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/dwarf_info.c b/dwarf_info.c
index f66d351..22c9e2f 100644
--- a/dwarf_info.c
+++ b/dwarf_info.c
@@ -119,6 +119,15 @@ is_search_domain(int cmd)
 }
 
 static int
+is_search_die(int cmd)
+{
+	if (cmd == DWARF_INFO_GET_DIE)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+static int
 process_module (Dwfl_Module *dwflmod,
 		void **userdata __attribute__ ((unused)),
 		const char *name __attribute__ ((unused)),
@@ -858,6 +867,25 @@ search_domain(Dwarf_Die *die, int *found)
 }
 
 static void
+search_die(Dwarf_Die *die, int *found)
+{
+	const char *name;
+
+	do {
+		name = dwarf_diename(die);
+
+		if ((!name) || strcmp(name, dwarf_info.symbol_name))
+			continue;
+
+		if (found)
+			*found = TRUE;
+
+		dwarf_info.die_offset = dwarf_dieoffset(die);
+		return;
+	} while (!dwarf_siblingof(die, die));
+}
+
+static void
 search_die_tree(Dwarf_Die *die, int *found)
 {
 	Dwarf_Die child;
@@ -885,6 +913,9 @@ search_die_tree(Dwarf_Die *die, int *found)
 
 	else if (is_search_domain(dwarf_info.cmd))
 		search_domain(die, found);
+
+	else if (is_search_die(dwarf_info.cmd))
+		search_die(die, found);
 }
 
 static int
@@ -1452,6 +1483,27 @@ get_die_name(unsigned long long die_off)
 }
 
 /*
+ * Get the die offset given the die name
+ */
+unsigned long long
+get_die_offset(char *sysname)
+{
+	dwarf_info.cmd         = DWARF_INFO_GET_DIE;
+	dwarf_info.symbol_name = sysname;
+	dwarf_info.type_name   = NULL;
+	dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
+	dwarf_info.die_offset  = 0;
+
+	if (!sysname)
+		return 0;
+
+	if (!get_debug_info())
+		return 0;
+
+	return (unsigned long long)dwarf_info.die_offset;
+}
+
+/*
  * Get length attribute given the die offset
  */
 int
diff --git a/dwarf_info.h b/dwarf_info.h
index d1d15a9..c5128f2 100644
--- a/dwarf_info.h
+++ b/dwarf_info.h
@@ -55,6 +55,7 @@ enum {
 	DWARF_INFO_GET_DOMAIN_REF,
 	DWARF_INFO_GET_DOMAIN_STRING,
 	DWARF_INFO_GET_DOMAIN_BASE,
+	DWARF_INFO_GET_DIE,
 };
 
 char *get_dwarf_module_name(void);
@@ -76,6 +77,7 @@ int get_die_member(unsigned long long die_off, int index, long *offset,
 int get_die_attr_type(unsigned long long die_off, int *type_flag,
 	unsigned long long *die_attr_off);
 char *get_die_name(unsigned long long die_off);
+unsigned long long get_die_offset(char *sysname);
 int get_die_length(unsigned long long die_off, int flag);
 int set_dwarf_debuginfo(char *mod_name, char *os_release, char *name_debuginfo, int fd_debuginfo);
 
diff --git a/extension_eppic.c b/extension_eppic.c
index 85dfdcd..835bd2d 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -313,6 +313,30 @@ apigetval(char *name, ull *val, VALUE_S *value)
 		return 0;
 
 	*val = ptr;
+
+	if (!value)
+		return 1;
+
+	/* Support for fully typed symbol access */
+	ull type;
+	TYPE_S *stype;
+
+	type = get_die_offset(name);
+	stype = eppic_gettype(value);
+
+	apigetrtype(type, stype);
+
+	eppic_pushref(stype, 1);
+	eppic_setmemaddr(value, *val);
+	eppic_do_deref(1, value, value);
+
+	*val = eppic_getval(value);
+
+	if (!eppic_typeislocal(stype) && eppic_type_getidx(stype) > 100) {
+		char *tname = get_die_name(eppic_type_getidx(stype));
+		if (tname)
+			eppic_chktype(stype, tname);
+	}
 	return 1;
 }
 


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

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

* Re: [PATCH v3 1/7] Initialize and setup eppic
  2012-12-14  9:26 ` [PATCH v3 1/7] Initialize and setup eppic Aravinda Prasad
@ 2012-12-20  8:45   ` Atsushi Kumagai
  2012-12-27  9:19     ` Aravinda Prasad
  0 siblings, 1 reply; 12+ messages in thread
From: Atsushi Kumagai @ 2012-12-20  8:45 UTC (permalink / raw)
  To: aravinda; +Cc: ananth, mahesh, kexec, LChouinard, tachibana, buendgen

Hello Aravinda,

Thank you for updating.
I have two comments in this mail.


On Fri, 14 Dec 2012 14:56:04 +0530
Aravinda Prasad <aravinda@linux.vnet.ibm.com> wrote:

> This patch contains routines which initialize eppic and register call
> back function which will be called whenever a new eppic macro is loaded
> using eppic_load() API. The registered call back function executes the
> eppic macro as soon as it is loaded.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  Makefile          |    5 +++
>  extension_eppic.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  extension_eppic.h |   23 +++++++++++++++
>  3 files changed, 111 insertions(+), 1 deletions(-)
>  create mode 100644 extension_eppic.c
>  create mode 100644 extension_eppic.h
> 
> diff --git a/Makefile b/Makefile
> index e6c4e5d..f123a5f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -69,7 +69,7 @@ $(OBJ_ARCH): $(SRC_ARCH)
>  	$(CC) $(CFLAGS_ARCH) -c -o ./$@ ./$(@:.o=.c) 
>  
>  makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
> -	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_PART) $(OBJ_ARCH) -o $@ $< $(LIBS)
> +	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_PART) $(OBJ_ARCH) -rdynamic -o $@ $< $(LIBS)
>  	echo .TH MAKEDUMPFILE 8 \"$(DATE)\" \"makedumpfile v$(VERSION)\" \"Linux System Administrator\'s Manual\" > temp.8
>  	grep -v "^.TH MAKEDUMPFILE 8" makedumpfile.8 >> temp.8
>  	mv temp.8 makedumpfile.8
> @@ -79,6 +79,9 @@ makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
>  	mv temp.5 makedumpfile.conf.5
>  	gzip -c ./makedumpfile.conf.5 > ./makedumpfile.conf.5.gz
>  
> +eppic_makedumpfile.so: extension_eppic.c
> +	$(CC) $(CFLAGS) -nostartfiles -shared -rdynamic -o $@ extension_eppic.c -fPIC -leppic
> +

First, I prepared eppic_makedumpfile.so with the code above, but I failed
with the message below:

  $ makedumpfile -cd31 -x vmlinux --eppic eppic_macro/mod.c vmcore dumpfile.cd31
  process_eppic_file: dlopen failed: /usr/lib64/eppic_makedumpfile.so: undefined symbol: setupterm
  
  makedumpfile Failed.
  $

so I think '-lncurses' should be specified as gcc option, or did I mistake ?


[...]
> +/* Initialize eppic */
> +int
> +_init()
> +{
> +	if (eppic_open() >= 0) {
> +
> +		/* Register call back functions */
> +		eppic_apiset(NULL, 3, sizeof(long), 0);
> +
> +		/* set the new function callback */
> +		eppic_setcallback(reg_callback);
> +
> +		return 0;
> +	}
> +	return 1;
> +}

Second, your code introduce _init() as constructor for dlopen().
I'm not sure about dlopen(), but I found the description which recommend
not to use _init() in man page:

   The obsolete symbols _init() and _fini()
       The linker recognizes special symbols _init and _fini.  If a dynamic library exports a routine named _init(), then that  code  is  executed
       after  the  loading,  before  dlopen()  returns.   If the dynamic library exports a routine named _fini(), then that routine is called just
       before the library is unloaded.  In case you need to avoid linking against the system startup files, this can be done by using  the  gcc(1)
       -nostartfiles command-line option.

       Using these routines, or the gcc -nostartfiles or -nostdlib options, is not recommended.  Their use may result in undesired behavior, since
       the constructor/destructor routines will not be executed (unless special measures are taken).

       Instead, libraries should export routines using the __attribute__((constructor)) and __attribute__((destructor)) function attributes.   See
       the  gcc  info pages for information on these.  Constructor routines are executed before dlopen() returns, and destructor routines are exe-
       cuted before dlclose() returns.

So, is it OK to continue to use _init() ?

BTW, would you send the patch to add the description of this feature
to README, man page and help message ?


Thanks
Atsushi Kumagai

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

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

* Re: [PATCH v3 4/7] Implement apigetctype call back function
  2012-12-14  9:26 ` [PATCH v3 4/7] Implement apigetctype call back function Aravinda Prasad
@ 2012-12-20  8:45   ` Atsushi Kumagai
  2012-12-27  9:11     ` Aravinda Prasad
  0 siblings, 1 reply; 12+ messages in thread
From: Atsushi Kumagai @ 2012-12-20  8:45 UTC (permalink / raw)
  To: aravinda; +Cc: ananth, mahesh, kexec, LChouinard, tachibana, buendgen

Hello Aravinda,

On Fri, 14 Dec 2012 14:56:32 +0530
Aravinda Prasad <aravinda@linux.vnet.ibm.com> wrote:

> libeppic will call apigetctype call back function whenever it
> encounters a token in the eppic macro. The call back function will use
> DWARF to query information related to the requested token and will
> pass it back to eppic using libeppic API calls. If the token does not
> exist, then apigetctype call returns 0.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
>  dwarf_info.c      |  109 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  dwarf_info.h      |    9 ++++
>  extension_eppic.c |   28 +++++++++++++-
>  3 files changed, 145 insertions(+), 1 deletions(-)
> 
> diff --git a/dwarf_info.c b/dwarf_info.c
> index 09a8e1e..a8a87e1 100644
> --- a/dwarf_info.c
> +++ b/dwarf_info.c
> @@ -51,6 +51,7 @@ struct dwarf_info {
>  	long	enum_number;		/* OUT */
>  	unsigned char	type_flag;	/* OUT */
>  	char	src_name[LEN_SRCFILE];	/* OUT */
> +	Dwarf_Off die_offset;		/* OUT */
>  };
>  static struct dwarf_info	dwarf_info;
>  
> @@ -102,6 +103,22 @@ is_search_typedef(int cmd)
>  }
>  
>  static int
> +is_search_domain(int cmd)
> +{
> +	if ((cmd == DWARF_INFO_GET_DOMAIN_STRUCT)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_TYPEDEF)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_ARRAY)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_UNION)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_ENUM)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_REF)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_STRING)
> +		|| (cmd == DWARF_INFO_GET_DOMAIN_BASE))
> +		return TRUE;
> +	else
> +		return FALSE;
> +}
> +
> +static int
>  process_module (Dwfl_Module *dwflmod,
>  		void **userdata __attribute__ ((unused)),
>  		const char *name __attribute__ ((unused)),
> @@ -750,6 +767,74 @@ search_symbol(Dwarf_Die *die, int *found)
>  }
>  
>  static void
> +search_domain(Dwarf_Die *die, int *found)
> +{
> +	int tag;
> +	const char *name;
> +	short flag = 0;
> +	Dwarf_Die die_type;
> +
> +	do {
> +		tag  = dwarf_tag(die);
> +		name = dwarf_diename(die);
> +
> +		/*
> +		 * Descend into members and search for the
> +		 * needed domain there.
> +		 */
> +		if (!name) {
> +			if (!get_die_type(die, &die_type))
> +				continue;
> +
> +			if (is_container(&die_type)) {
> +				Dwarf_Die child;
> +
> +				if (dwarf_child(&die_type, &child) != 0)
> +					continue;
> +
> +				search_domain(&child, found);
> +
> +				if (*found)
> +					return;
> +			}
> +		}
> +
> +		if ((!name) || strcmp(name, dwarf_info.symbol_name))
> +			continue;

I commented for search_domain() in v1 patch:

  http://lists.infradead.org/pipermail/kexec/2012-October/007024.html

  > I assume that search_domain() needs to descend into struct/union for
  > a nested member, like how we fixed search_member() in commit:ecff242c.
  > I want to make sure that your patches can treat even a nested member.

And I still think so, it should be fixed as below:


diff --git a/dwarf_info.c b/dwarf_info.c
index 22c9e2f..a11b6ad 100644
--- a/dwarf_info.c
+++ b/dwarf_info.c
@@ -814,7 +814,7 @@ search_domain(Dwarf_Die *die, int *found)
                 * Descend into members and search for the
                 * needed domain there.
                 */
-               if (!name) {
+               if ((!name) || strcmp(name, dwarf_info.symbol_name)) {
                        if (!get_die_type(die, &die_type))
                                continue;

Do you agree with me ?


Thanks
Atsushi Kumagai

> +
> +		switch (dwarf_info.cmd) {
> +		case DWARF_INFO_GET_DOMAIN_STRUCT:
> +			if (tag == DW_TAG_structure_type)
> +				flag = 1;
> +			break;
> +		case DWARF_INFO_GET_DOMAIN_UNION:
> +			if (tag == DW_TAG_union_type)
> +				flag = 1;
> +			break;
> +		case DWARF_INFO_GET_DOMAIN_TYPEDEF:
> +			if (tag == DW_TAG_typedef)
> +				flag = 1;
> +			break;
> +		/* TODO
> +		 * Implement functionality for the rest of the domains
> +		 */
> +		}
> +
> +		if (!flag)
> +			continue;
> +
> +		dwarf_info.struct_size = dwarf_bytesize(die);
> +
> +		if (dwarf_info.struct_size > 0) {
> +			if (found)
> +				*found = TRUE;
> +			dwarf_info.die_offset = dwarf_dieoffset(die);
> +			break;
> +		}
> +	} while (!dwarf_siblingof(die, die));
> +}
> +
> +static void
>  search_die_tree(Dwarf_Die *die, int *found)
>  {
>  	Dwarf_Die child;
> @@ -774,6 +859,9 @@ search_die_tree(Dwarf_Die *die, int *found)
>  
>  	else if (is_search_typedef(dwarf_info.cmd))
>  		search_typedef(die, found);
> +
> +	else if (is_search_domain(dwarf_info.cmd))
> +		search_domain(die, found);
>  }
>  
>  static int
> @@ -1166,6 +1254,27 @@ get_source_filename(char *structname, char *src_name, int cmd)
>  }
>  
>  /*
> + * Get the domain information of the symbol
> + */
> +long
> +get_domain(char *symname, int cmd, unsigned long long *die)
> +{
> +	dwarf_info.cmd         = cmd;
> +	dwarf_info.symbol_name = symname;
> +	dwarf_info.type_name   = NULL;
> +	dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
> +	dwarf_info.die_offset  = 0;
> +
> +	if (!get_debug_info())
> +		return 0;
> +
> +	if (die)
> +		*die = (unsigned long long) dwarf_info.die_offset;
> +
> +	return dwarf_info.struct_size;
> +}
> +
> +/*
>   * Set the dwarf_info with kernel/module debuginfo file information.
>   */
>  int
> diff --git a/dwarf_info.h b/dwarf_info.h
> index 185cbb6..074b5cc 100644
> --- a/dwarf_info.h
> +++ b/dwarf_info.h
> @@ -47,6 +47,14 @@ enum {
>  	DWARF_INFO_GET_SYMBOL_TYPE,
>  	DWARF_INFO_GET_MEMBER_TYPE,
>  	DWARF_INFO_GET_ENUMERATION_TYPE_SIZE,
> +	DWARF_INFO_GET_DOMAIN_STRUCT,
> +	DWARF_INFO_GET_DOMAIN_TYPEDEF,
> +	DWARF_INFO_GET_DOMAIN_ARRAY,
> +	DWARF_INFO_GET_DOMAIN_UNION,
> +	DWARF_INFO_GET_DOMAIN_ENUM,
> +	DWARF_INFO_GET_DOMAIN_REF,
> +	DWARF_INFO_GET_DOMAIN_STRING,
> +	DWARF_INFO_GET_DOMAIN_BASE,
>  };
>  
>  char *get_dwarf_module_name(void);
> @@ -61,6 +69,7 @@ char *get_member_type_name(char *structname, char *membername, int cmd, long *si
>  long get_array_length(char *name01, char *name02, unsigned int cmd);
>  long get_enum_number(char *enum_name);
>  int get_source_filename(char *structname, char *src_name, int cmd);
> +long get_domain(char *symname, int cmd, unsigned long long *die);
>  int set_dwarf_debuginfo(char *mod_name, char *os_release, char *name_debuginfo, int fd_debuginfo);
>  
>  #endif  /* DWARF_INFO_H */
> diff --git a/extension_eppic.c b/extension_eppic.c
> index 774d16e..3fa3e88 100644
> --- a/extension_eppic.c
> +++ b/extension_eppic.c
> @@ -91,7 +91,33 @@ apimember(char *mname, ull pidx, type_t *tm,
>  static int
>  apigetctype(int ctype, char *name, type_t *tout)
>  {
> -	return 0;
> +	long size = 0;
> +	unsigned long long die = 0;
> +
> +	switch (ctype) {
> +	case V_TYPEDEF:
> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_TYPEDEF, &die);
> +		break;
> +	case V_STRUCT:
> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
> +		break;
> +	case V_UNION:
> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
> +		break;
> +	/* TODO
> +	 * Implement for all the domains
> +	 */
> +	}
> +
> +	if (size <= 0 || !die)
> +		return 0;
> +
> +	/* populate */
> +	eppic_type_settype(tout, ctype);
> +	eppic_type_setsize(tout, size);
> +	eppic_type_setidx(tout, (ull)(unsigned long)die);
> +	eppic_pushref(tout, 0);
> +	return 1;
>  }
>  
>  static char *
> 

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

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

* Re: [PATCH v3 4/7] Implement apigetctype call back function
  2012-12-20  8:45   ` Atsushi Kumagai
@ 2012-12-27  9:11     ` Aravinda Prasad
  0 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-27  9:11 UTC (permalink / raw)
  To: Atsushi Kumagai; +Cc: ananth, mahesh, kexec, LChouinard, tachibana, buendgen

Hi Atsushi,

On 2012-12-20 14:15, Atsushi Kumagai wrote:

> Hello Aravinda,
> 
> On Fri, 14 Dec 2012 14:56:32 +0530
> Aravinda Prasad <aravinda@linux.vnet.ibm.com> wrote:
> 


[...]




> I commented for search_domain() in v1 patch:
> 
>   http://lists.infradead.org/pipermail/kexec/2012-October/007024.html
> 
>   > I assume that search_domain() needs to descend into struct/union for
>   > a nested member, like how we fixed search_member() in commit:ecff242c.
>   > I want to make sure that your patches can treat even a nested member.
> 
> And I still think so, it should be fixed as below:
> 
> 
> diff --git a/dwarf_info.c b/dwarf_info.c
> index 22c9e2f..a11b6ad 100644
> --- a/dwarf_info.c
> +++ b/dwarf_info.c
> @@ -814,7 +814,7 @@ search_domain(Dwarf_Die *die, int *found)
>                  * Descend into members and search for the
>                  * needed domain there.
>                  */
> -               if (!name) {
> +               if ((!name) || strcmp(name, dwarf_info.symbol_name)) {
>                         if (!get_die_type(die, &die_type))
>                                 continue;
> 
> Do you agree with me ?


Yes, I think this should be fine. I will modify and test the patch with
the above change.

> 
> 
> Thanks
> Atsushi Kumagai
> 
>> +
>> +		switch (dwarf_info.cmd) {
>> +		case DWARF_INFO_GET_DOMAIN_STRUCT:
>> +			if (tag == DW_TAG_structure_type)
>> +				flag = 1;
>> +			break;
>> +		case DWARF_INFO_GET_DOMAIN_UNION:
>> +			if (tag == DW_TAG_union_type)
>> +				flag = 1;
>> +			break;
>> +		case DWARF_INFO_GET_DOMAIN_TYPEDEF:
>> +			if (tag == DW_TAG_typedef)
>> +				flag = 1;
>> +			break;
>> +		/* TODO
>> +		 * Implement functionality for the rest of the domains
>> +		 */
>> +		}
>> +
>> +		if (!flag)
>> +			continue;
>> +
>> +		dwarf_info.struct_size = dwarf_bytesize(die);
>> +
>> +		if (dwarf_info.struct_size > 0) {
>> +			if (found)
>> +				*found = TRUE;
>> +			dwarf_info.die_offset = dwarf_dieoffset(die);
>> +			break;
>> +		}
>> +	} while (!dwarf_siblingof(die, die));
>> +}
>> +
>> +static void
>>  search_die_tree(Dwarf_Die *die, int *found)
>>  {
>>  	Dwarf_Die child;
>> @@ -774,6 +859,9 @@ search_die_tree(Dwarf_Die *die, int *found)
>>  
>>  	else if (is_search_typedef(dwarf_info.cmd))
>>  		search_typedef(die, found);
>> +
>> +	else if (is_search_domain(dwarf_info.cmd))
>> +		search_domain(die, found);
>>  }
>>  
>>  static int
>> @@ -1166,6 +1254,27 @@ get_source_filename(char *structname, char *src_name, int cmd)
>>  }
>>  
>>  /*
>> + * Get the domain information of the symbol
>> + */
>> +long
>> +get_domain(char *symname, int cmd, unsigned long long *die)
>> +{
>> +	dwarf_info.cmd         = cmd;
>> +	dwarf_info.symbol_name = symname;
>> +	dwarf_info.type_name   = NULL;
>> +	dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
>> +	dwarf_info.die_offset  = 0;
>> +
>> +	if (!get_debug_info())
>> +		return 0;
>> +
>> +	if (die)
>> +		*die = (unsigned long long) dwarf_info.die_offset;
>> +
>> +	return dwarf_info.struct_size;
>> +}
>> +
>> +/*
>>   * Set the dwarf_info with kernel/module debuginfo file information.
>>   */
>>  int
>> diff --git a/dwarf_info.h b/dwarf_info.h
>> index 185cbb6..074b5cc 100644
>> --- a/dwarf_info.h
>> +++ b/dwarf_info.h
>> @@ -47,6 +47,14 @@ enum {
>>  	DWARF_INFO_GET_SYMBOL_TYPE,
>>  	DWARF_INFO_GET_MEMBER_TYPE,
>>  	DWARF_INFO_GET_ENUMERATION_TYPE_SIZE,
>> +	DWARF_INFO_GET_DOMAIN_STRUCT,
>> +	DWARF_INFO_GET_DOMAIN_TYPEDEF,
>> +	DWARF_INFO_GET_DOMAIN_ARRAY,
>> +	DWARF_INFO_GET_DOMAIN_UNION,
>> +	DWARF_INFO_GET_DOMAIN_ENUM,
>> +	DWARF_INFO_GET_DOMAIN_REF,
>> +	DWARF_INFO_GET_DOMAIN_STRING,
>> +	DWARF_INFO_GET_DOMAIN_BASE,
>>  };
>>  
>>  char *get_dwarf_module_name(void);
>> @@ -61,6 +69,7 @@ char *get_member_type_name(char *structname, char *membername, int cmd, long *si
>>  long get_array_length(char *name01, char *name02, unsigned int cmd);
>>  long get_enum_number(char *enum_name);
>>  int get_source_filename(char *structname, char *src_name, int cmd);
>> +long get_domain(char *symname, int cmd, unsigned long long *die);
>>  int set_dwarf_debuginfo(char *mod_name, char *os_release, char *name_debuginfo, int fd_debuginfo);
>>  
>>  #endif  /* DWARF_INFO_H */
>> diff --git a/extension_eppic.c b/extension_eppic.c
>> index 774d16e..3fa3e88 100644
>> --- a/extension_eppic.c
>> +++ b/extension_eppic.c
>> @@ -91,7 +91,33 @@ apimember(char *mname, ull pidx, type_t *tm,
>>  static int
>>  apigetctype(int ctype, char *name, type_t *tout)
>>  {
>> -	return 0;
>> +	long size = 0;
>> +	unsigned long long die = 0;
>> +
>> +	switch (ctype) {
>> +	case V_TYPEDEF:
>> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_TYPEDEF, &die);
>> +		break;
>> +	case V_STRUCT:
>> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
>> +		break;
>> +	case V_UNION:
>> +		size = get_domain(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
>> +		break;
>> +	/* TODO
>> +	 * Implement for all the domains
>> +	 */
>> +	}
>> +
>> +	if (size <= 0 || !die)
>> +		return 0;
>> +
>> +	/* populate */
>> +	eppic_type_settype(tout, ctype);
>> +	eppic_type_setsize(tout, size);
>> +	eppic_type_setidx(tout, (ull)(unsigned long)die);
>> +	eppic_pushref(tout, 0);
>> +	return 1;
>>  }
>>  
>>  static char *
>>
> 


-- 
Regards,
Aravinda


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

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

* Re: [PATCH v3 1/7] Initialize and setup eppic
  2012-12-20  8:45   ` Atsushi Kumagai
@ 2012-12-27  9:19     ` Aravinda Prasad
  0 siblings, 0 replies; 12+ messages in thread
From: Aravinda Prasad @ 2012-12-27  9:19 UTC (permalink / raw)
  To: Atsushi Kumagai; +Cc: ananth, mahesh, kexec, LChouinard, tachibana, buendgen

Hi Atsushi,

On 2012-12-20 14:15, Atsushi Kumagai wrote:

> Hello Aravinda,
> 
> Thank you for updating.
> I have two comments in this mail.
> 
> 
> On Fri, 14 Dec 2012 14:56:04 +0530
> Aravinda Prasad <aravinda@linux.vnet.ibm.com> wrote:
> 
>> This patch contains routines which initialize eppic and register call
>> back function which will be called whenever a new eppic macro is loaded
>> using eppic_load() API. The registered call back function executes the
>> eppic macro as soon as it is loaded.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>>  Makefile          |    5 +++
>>  extension_eppic.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  extension_eppic.h |   23 +++++++++++++++
>>  3 files changed, 111 insertions(+), 1 deletions(-)
>>  create mode 100644 extension_eppic.c
>>  create mode 100644 extension_eppic.h
>>
>> diff --git a/Makefile b/Makefile
>> index e6c4e5d..f123a5f 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -69,7 +69,7 @@ $(OBJ_ARCH): $(SRC_ARCH)
>>  	$(CC) $(CFLAGS_ARCH) -c -o ./$@ ./$(@:.o=.c) 
>>  
>>  makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
>> -	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_PART) $(OBJ_ARCH) -o $@ $< $(LIBS)
>> +	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_PART) $(OBJ_ARCH) -rdynamic -o $@ $< $(LIBS)
>>  	echo .TH MAKEDUMPFILE 8 \"$(DATE)\" \"makedumpfile v$(VERSION)\" \"Linux System Administrator\'s Manual\" > temp.8
>>  	grep -v "^.TH MAKEDUMPFILE 8" makedumpfile.8 >> temp.8
>>  	mv temp.8 makedumpfile.8
>> @@ -79,6 +79,9 @@ makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
>>  	mv temp.5 makedumpfile.conf.5
>>  	gzip -c ./makedumpfile.conf.5 > ./makedumpfile.conf.5.gz
>>  
>> +eppic_makedumpfile.so: extension_eppic.c
>> +	$(CC) $(CFLAGS) -nostartfiles -shared -rdynamic -o $@ extension_eppic.c -fPIC -leppic
>> +
> 
> First, I prepared eppic_makedumpfile.so with the code above, but I failed
> with the message below:
> 
>   $ makedumpfile -cd31 -x vmlinux --eppic eppic_macro/mod.c vmcore dumpfile.cd31
>   process_eppic_file: dlopen failed: /usr/lib64/eppic_makedumpfile.so: undefined symbol: setupterm
>   
>   makedumpfile Failed.
>   $
> 
> so I think '-lncurses' should be specified as gcc option, or did I mistake ?


-ltinfo was missing in the gcc option.

>

> 
> [...]
>> +/* Initialize eppic */
>> +int
>> +_init()
>> +{
>> +	if (eppic_open() >= 0) {
>> +
>> +		/* Register call back functions */
>> +		eppic_apiset(NULL, 3, sizeof(long), 0);
>> +
>> +		/* set the new function callback */
>> +		eppic_setcallback(reg_callback);
>> +
>> +		return 0;
>> +	}
>> +	return 1;
>> +}
> 
> Second, your code introduce _init() as constructor for dlopen().
> I'm not sure about dlopen(), but I found the description which recommend
> not to use _init() in man page:
> 
>    The obsolete symbols _init() and _fini()
>        The linker recognizes special symbols _init and _fini.  If a dynamic library exports a routine named _init(), then that  code  is  executed
>        after  the  loading,  before  dlopen()  returns.   If the dynamic library exports a routine named _fini(), then that routine is called just
>        before the library is unloaded.  In case you need to avoid linking against the system startup files, this can be done by using  the  gcc(1)
>        -nostartfiles command-line option.
> 
>        Using these routines, or the gcc -nostartfiles or -nostdlib options, is not recommended.  Their use may result in undesired behavior, since
>        the constructor/destructor routines will not be executed (unless special measures are taken).
> 
>        Instead, libraries should export routines using the __attribute__((constructor)) and __attribute__((destructor)) function attributes.   See
>        the  gcc  info pages for information on these.  Constructor routines are executed before dlopen() returns, and destructor routines are exe-
>        cuted before dlclose() returns.
> 
> So, is it OK to continue to use _init() ?


I am planning to change _init() to eppic_init() and then explicitly call
it after dlopen(), as using _init() is not recommended.

Apart from this I am facing some minor issues with dlopen(). With static
makedumpfile, dlopen is not able to resolve some symbols in dwarf_info.c
and is failing, while it is working when compiled with LINKTYPE=dynamic.
I am looking into it.

> 
> BTW, would you send the patch to add the description of this feature
> to README, man page and help message ?
> 
> 
> Thanks
> Atsushi Kumagai
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 


-- 
Regards,
Aravinda


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

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

end of thread, other threads:[~2012-12-27  9:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-14  9:25 [PATCH v3 0/7] makedumpfile security key filtering with eppic Aravinda Prasad
2012-12-14  9:26 ` [PATCH v3 1/7] Initialize and setup eppic Aravinda Prasad
2012-12-20  8:45   ` Atsushi Kumagai
2012-12-27  9:19     ` Aravinda Prasad
2012-12-14  9:26 ` [PATCH v3 2/7] makedumpfile and eppic interface layer Aravinda Prasad
2012-12-14  9:26 ` [PATCH v3 3/7] Eppic call back functions to query a dump image Aravinda Prasad
2012-12-14  9:26 ` [PATCH v3 4/7] Implement apigetctype call back function Aravinda Prasad
2012-12-20  8:45   ` Atsushi Kumagai
2012-12-27  9:11     ` Aravinda Prasad
2012-12-14  9:26 ` [PATCH v3 5/7] Implement apimember and apigetrtype call back functions Aravinda Prasad
2012-12-14  9:26 ` [PATCH v3 6/7] Extend eppic built-in functions to include memset function Aravinda Prasad
2012-12-14  9:27 ` [PATCH v3 7/7] Support fully typed symbol access mode Aravinda Prasad

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.