makedumpfile security key filtering with eppic
Subsystems (3)
v3 cover makedumpfile security key filtering with eppic
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
Signature · 7 lines
Aravinda Prasad _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 1/7 Initialize and setup eppic
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.
--- 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
Makefile +4 -1
@@ -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
extension_eppic.c new file +84 -0
84 lines not on this page · raw message
extension_eppic.h new file +23 -0
@@ -0,0 +1,23 @@ +/* +* extension_eppic.h +* +* Created by: Aravinda Prasad <[email protected]> +* +* 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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 1/7] Initialize and setup eppic
Hello Aravinda,
Thank you for updating.
I have two comments in this mail.
Quoted 28 lines · On Fri, 14 Dec 2012 14:56:04 +0530 Aravinda Prasad…
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 <[email protected]>--- 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.hMakefile +1
-1@@ -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
Makefile makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH) · line 84
Quoted 6 lines
Makefile +3
-0@@ -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 ?
[...]
Quoted 6 lines
Makefile +6
-0+/* Initialize eppic */ +int +_init() +{ + if (eppic_open() >= 0) { +
Makefile makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH)
Quoted 10 lines
Makefile +10
-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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 1/7] Initialize and setup eppic
Hi Atsushi,
Quoted 47 lines · Atsushi Kumagai
Hello Aravinda,
Thank you for updating.
I have two comments in this mail.Quoted 28 lines · On Fri, 14 Dec 2012 14:56:04 +0530 Aravinda Prasad…
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 <[email protected]>--- 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.hMakefile +1
-1@@ -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.8Makefile makedumpfile: $(SRC) $(OBJ_PART) $(OBJ_ARCH) · line 84
Quoted 6 lines
Makefile +3
-0@@ -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:
Quoted 7 lines
$ makedumpfile -cd31 -x vmlinux --eppic eppic_macro/mod.c vmcore dumpfile.cd31 process_eppic_file: dlopen failed: /usr/lib64/eppic_makedumpfile.so: undefined symbol: setuptermmakedumpfile Failed.
$so I think '-lncurses' should be specified as gcc option, or did I mistake ?
-ltinfo was missing in the gcc option.
Quoted 31 lines
[...]
Quoted 6 lines
Makefile +6
-0+/* Initialize eppic */ +int +_init() +{ + if (eppic_open() >= 0) { +Makefile
Quoted 10 lines
Makefile +10
-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 fordlopen(). I'm not sure aboutdlopen(), 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_initand_fini. If a dynamic library exports a routine named_init(), then that code is executed
after the loading, beforedlopen()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.
Quoted 8 lines
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 beforedlopen()returns, and destructor routines are exe- cuted beforedlclose()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.
Quoted 13 lines
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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Signature · 8 lines
Regards, Aravinda _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 2/7 makedumpfile and eppic interface layer
In reply to Aravinda PrasadThis 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.
--- erase_info.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-- extension_eppic.h | 1 + makedumpfile.c | 7 +++++- makedumpfile.h | 6 +++++ 4 files changed, 69 insertions(+), 3 deletions(-)
erase_info.c +56 -2
@@ -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.
extension_eppic.h +1 -0
@@ -21,3 +21,4 @@#include "eppic_api.h" #endif /* _EXTENSION_EPPIC_H */ +
makedumpfile.c +6 -1
@@ -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 ;
makedumpfile.h +6 -0
@@ -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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 3/7 Eppic call back functions to query a dump image
In reply to Aravinda PrasadThis 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.
--- extension_eppic.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ extension_eppic.h | 49 ++++++++++++++++++++ 2 files changed, 175 insertions(+), 2 deletions(-)
extension_eppic.c +127 -1
@@ -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);
extension_eppic.h +48 -1
53 lines not on this page · raw message
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 4/7 Implement apigetctype call back function
In reply to Aravinda Prasadlibeppic 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.
--- dwarf_info.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dwarf_info.h | 9 ++++ extension_eppic.c | 28 +++++++++++++- 3 files changed, 145 insertions(+), 1 deletions(-)
dwarf_info.c +109 -0
@@ -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
dwarf_info.h +9 -0
@@ -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 *silong 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 */
extension_eppic.c +27 -1
@@ -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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/7] Implement apigetctype call back function
Hello Aravinda,
Quoted 76 lines · On Fri, 14 Dec 2012 14:56:32 +0530 Aravinda Prasad…
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 <[email protected]>--- dwarf_info.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dwarf_info.h | 9 ++++ extension_eppic.c | 28 +++++++++++++- 3 files changed, 145 insertions(+), 1 deletions(-)dwarf_info.c +41
-0@@ -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;
dwarf_info.c search_symbol(Dwarf_Die *die, int *found) · line 803
Quoted 10 lines
dwarf_info.c +10
-0+ +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
Quoted 3 lines
I assume that
search_domain()needs to descend into struct/union for a nested member, like how we fixedsearch_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:
dwarf_info.c +1 -1
@@ -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
Quoted 132 lines
dwarf_info.c +58
-0+ +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 dwarf_info.h +9
-0@@ -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 *silong 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 */ extension_eppic.c +20
-1@@ -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 ;
extension_eppic.c apimember(char *mname, ull pidx, type_t *tm, · line 123
Quoted 10 lines
extension_eppic.c +7
-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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/7] Implement apigetctype call back function
Hi Atsushi,
Quoted 5 lines · Atsushi Kumagai
Hello Aravinda,
On Fri, 14 Dec 2012 14:56:32 +0530
Aravinda Prasad <[email protected]> wrote:
[...]
Quoted 24 lines
I commented for
search_domain()in v1 patch:http://lists.infradead.org/pipermail/kexec/2012-October/007024.html
Quoted 3 lines
I assume that
search_domain()needs to descend into struct/union for a nested member, like how we fixedsearch_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:
dwarf_info.c +1
-1@@ -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 ;
Quoted 1 line
Do you agree with me ?
Yes, I think this should be fine. I will modify and test the patch with the above change.
Quoted 148 lines
Thanks
Atsushi KumagaiQuoted 142 lines
(quoted diff) +58
-0+ + 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. */ intdwarf_info.h +9
-0@@ -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 *silong 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 */ extension_eppic.c +27
-1@@ -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 *
Signature · 8 lines
Regards, Aravinda _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 5/7 Implement apimember and apigetrtype call back functions
In reply to Aravinda PrasadThe 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.
--- dwarf_info.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dwarf_info.h | 7 ++ extension_eppic.c | 179 +++++++++++++++++++++++++++++++++++++++++++++- extension_eppic.h | 2 + 4 files changed, 390 insertions(+), 4 deletions(-)
dwarf_info.c +206 -0
@@ -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
dwarf_info.h +7 -0
@@ -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 */
extension_eppic.c +175 -4
208 lines not on this page · raw message
extension_eppic.h +2 -0
@@ -27,6 +27,8 @@* for makedumpfile extension. */ +#define MAX_ARRAY_DIMENSION 16 +/* member information */ typedef MEMBER_S {
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 6/7 Extend eppic built-in functions to include memset function
In reply to Aravinda PrasadThe 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.
--- erase_info.c | 33 ++++++++++++++++++++++++++++++++- erase_info.h | 1 + extension_eppic.c | 20 ++++++++++++++++++++ extension_eppic.h | 2 ++ 4 files changed, 55 insertions(+), 1 deletions(-)
erase_info.c +32 -1
@@ -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); } }
erase_info.h +1 -0
@@ -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 */
extension_eppic.c +20 -0
@@ -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 ;
extension_eppic.h +2 -0
@@ -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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 7/7 Support fully typed symbol access mode
In reply to Aravinda PrasadEppic 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.
--- dwarf_info.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ dwarf_info.h | 2 ++ extension_eppic.c | 24 ++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 0 deletions(-)
dwarf_info.c +52 -0
@@ -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
dwarf_info.h +2 -0
@@ -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);
extension_eppic.c +24 -0
@@ -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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec