From 7383d2571373350f72d74fdb296ecc4cd770398b Mon Sep 17 00:00:00 2001 From: pompolic <pompolic@special-circumstanc.es> Date: Thu, 9 Sep 2021 20:58:24 +0200 Subject: [PATCH] (WIP) Decoupling env init from debugger state --- gdb-port/parser-type-instrumentation-gdb.py | 125 +++++++++++++------- 1 file changed, 83 insertions(+), 42 deletions(-) diff --git a/gdb-port/parser-type-instrumentation-gdb.py b/gdb-port/parser-type-instrumentation-gdb.py index 23fe25e..5555e87 100644 --- a/gdb-port/parser-type-instrumentation-gdb.py +++ b/gdb-port/parser-type-instrumentation-gdb.py @@ -57,6 +57,8 @@ class VTTypes: class HParserEnv: def __init__(self, parser, top_level_parse): self.top_level_parse = top_level_parse + self.hparser_t = gdb.lookup_type("HParser") + self.hparser_p_t = self.hparser_t.pointer() # parser is expected to be a Parser object def name_from_vtable(self, parser): @@ -101,14 +103,21 @@ class AttrBoolEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + hattrbool_t = gdb.lookup_type("HAttrBool") + hattrbool_p_t = hattrbool_t.pointer() + p_env = parser_val['env'].cast(hattrbool_p_t).dereference() - member_parser_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->p") - parser_obj = top_level_parse.add_or_get_parser(member_parser_p) + #member_parser_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->p") + member_parser_p = p_env['p'] + parser_obj = top_level_parse.add_or_get_parser(member_parser_p) # For clarity: parser_obj here is the Python object representing parser->env->p if parser_obj.name is None: parser_obj.name_parser( self.name_from_vtable(parser_obj) ) self.member_parser = parser_obj - self.predicate_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->pred") - self.user_data_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->user_data") + #self.predicate_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->pred") + self.predicate_p = p_env['pred'] + #self.user_data_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->user_data") + self.user_data_p = p_env['user_data'] def __str__(self): return str(self.member_parser) @@ -117,15 +126,22 @@ class BindEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + bindenv_t = gdb.lookup_type("BindEnv") # If performance becomes a problem, the type lookups could be factored out into a dict filled out ahead of time + bindenv_p_t = bindenv_t.pointer() + p_env = parser_val['env'].cast(bindenv_p_t).dereference() - member_parser_p = gdb.parse_and_eval("((BindEnv *) parser->env)->p") + #member_parser_p = gdb.parse_and_eval("((BindEnv *) parser->env)->p") + member_parser_p = p_env['p'] parser_obj = top_level_parse.add_or_get_parser(member_parser_p) if parser_obj.name is None: parser_obj.name_parser( self.name_from_vtable(parser_obj) ) self.member_parser = parser_obj - continuation_p = gdb.parse_and_eval("((BindEnv *) parser->env)->k") - self.continuation = int(continuation_p) - env_p = gdb.parse_and_eval("((BindEnv *) parser->env)->env") + #continuation_p = gdb.parse_and_eval("((BindEnv *) parser->env)->k") + continuation_p = p_env['k'] + self.continuation = int(continuation_p) # TODO: stop casting to int and just store the gdb.Value + #env_p = gdb.parse_and_eval("((BindEnv *) parser->env)->env") + env_p = p_env['env'] self.env = int(env_p) def __str__(self): @@ -134,10 +150,16 @@ class BindEnv(HParserEnv): class BitsEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser - - self.length = gdb.parse_and_eval("((struct bits_env *) parser->env)->length") - self.signedp = gdb.parse_and_eval("((struct bits_env *) parser->env)->signedp") super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + bits_env_t = gdb.lookup_type("struct bits_env") + bits_env_p_t = bits_env_t.pointer() + p_env = parser_val['env'].cast(bits_env_p_t).dereference() + + #self.length = gdb.parse_and_eval("((struct bits_env *) parser->env)->length") + self.length = p_env['length'] + #self.signedp = gdb.parse_and_eval("((struct bits_env *) parser->env)->signedp") + self.signedp = p_env['signedp'] def __str__(self): return str([str(self.length), str(self.signedp)]) @@ -146,12 +168,11 @@ class ButNotEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) - + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() htwoparsers_t = gdb.lookup_type("HTwoParsers") htwoparsers_p_t = htwoparsers_t.pointer() + p_env = parser_val['env'].cast(htwoparsers_p_t).dereference() - parser_obj = gdb.parse_and_eval("*parser") - p_env = parser_obj['env'].cast(htwoparsers_p_t).dereference() p1_p = p_env['p1'] p1_obj = top_level_parse.add_or_get_parser(p1_p) if p1_obj.name is None: @@ -170,20 +191,23 @@ class ActionEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) - parser_t = gdb.lookup_type("HParser") # TODO: maybe move this into TopLevelParse - parser_p_t = parser_t.pointer() + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + hparseaction_t = gdb.lookup_type("HParseAction") + hparseaction_p_t = hparseaction_t.pointer() + p_env = parser_val['env'].cast(hparseaction_p_t).dereference() #member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p") - member_parser_p = gdb.Value(parser.address).cast(parser_p_t) #TODO: shuffling around pointers may not be necessary after all, if using Value objects + member_parser_p = p_env['p'] #TODO: shuffling around pointers may not be necessary after all, if using Value objects parser_obj = top_level_parse.add_or_get_parser(member_parser_p) if parser_obj.name is None: parser_obj.name_parser( self.name_from_vtable(parser_obj) ) self.member_parser = parser_obj - # should return a HAction - action = gdb.parse_and_eval("((HParseAction*) parser->env)->action") + #action = gdb.parse_and_eval("((HParseAction*) parser->env)->action") + action = p_env['action'] self.action = int(action) - user_data_p = gdb.parse_and_eval("((HParseAction*) parser->env)->user_data") + #user_data_p = gdb.parse_and_eval("((HParseAction*) parser->env)->user_data") + user_data_p = p_env['user_data'] self.user_data_p = int(user_data_p) def __str__(self): @@ -192,13 +216,15 @@ class ActionEnv(HParserEnv): class AndEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser + super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() - member_parser_p = gdb.parse_and_eval("(HParser*) parser->env") + #member_parser_p = gdb.parse_and_eval("(HParser*) parser->env") + member_parser_p = parser_val['env'].cast(self.hparser_p_t) parser_obj = top_level_parse.add_or_get_parser(member_parser_p) if parser_obj.name is None: parser_obj.name_parser( self.name_from_vtable(parser_obj) ) self.member_parser = parser_obj - super().__init__(parser, top_level_parse) def __str__(self): return str([str(self.member_parser)]) @@ -206,10 +232,13 @@ class AndEnv(HParserEnv): class ChEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser + super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + uint8_t = gdb.lookup_type("uint8_t") - self.ch_arg = gdb.parse_and_eval("(uint8_t) parser->env") + #self.ch_arg = gdb.parse_and_eval("(uint8_t) parser->env") + self.ch_arg = parser_val['env'].cast(uint8_t) self.ch_value = int(self.ch_arg) - super().__init__(parser, top_level_parse) def __str__(self): return str(self.ch_value) @@ -217,28 +246,27 @@ class ChEnv(HParserEnv): class CharsetEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser - - self.charset_arg = gdb.parse_and_eval("(HCharset) parser->env") super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + hcharset_t = gdb.lookup_type("HCharset") + + #self.charset_arg = gdb.parse_and_eval("(HCharset) parser->env") + self.charset_arg = parser_val['env'].cast(hcharset_t) def __str__(self): return str(self.charset_arg) -# TODO: this assumes the parser parameter passed to init and the parser value returned by GDB are the same -# they should be, but parse_and_eval could be removed entirely if the code just used the parameter -# This would also make initialization independent of being at specific breakpoints when executing class ChoiceEnv(HParserEnv): def __init__(self, parser, top_level_parse): super().__init__(parser, top_level_parse) self.parser = parser self.member_parsers = [] + parser_obj = gdb.Value(parser).cast(self.hparser_p_t).dereference() #frame = gdb.selected_frame() h_sequence_t = gdb.lookup_type("HSequence") h_sequence_p_t = h_sequence_t.pointer() - # Get the parser object - parser_obj = gdb.parse_and_eval("*parser") # Get parser_obj.env, cast it to HSequence *, then dereference p_env = parser_obj['env'].cast(h_sequence_p_t).dereference() # Get length of HSequence @@ -260,14 +288,20 @@ class DifferenceEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + htwoparsers_t = gdb.lookup_type("HTwoParsers") + htwoparsers_p_t = htwoparsers_t.pointer() + p_env = parser_val['env'].cast(htwoparsers_p_t).dereference() #TODO: maybe have a class for HTwoParsers-based envs - p1_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p1") + #p1_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p1") + p1_p = p_env['p1'] p1_obj = top_level_parse.add_or_get_parser(p1_p) if p1_obj.name is None: p1_obj.name_parser( self.name_from_vtable(p1_obj) ) self.p1 = p1_obj - p2_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p2") + #p2_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p2") + p2_p = p_env['p2'] p2_obj = top_level_parse.add_or_get_parser(p2_p) if p2_obj.name is None: p2_obj.name_parser( self.name_from_vtable(p2_obj) ) @@ -288,13 +322,19 @@ class EndiannessEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() + hparseendianness_t = gdb.lookup_type("HParseEndianness") + hparseendianness_p_t = hparseendianness_t.pointer() + p_env = parser_val['env'].cast(hparseendianness_p_t).dereference() - member_parser_p = gdb.parse_and_eval("((HParseEndianness *) parser->env)->p") + #member_parser_p = gdb.parse_and_eval("((HParseEndianness *) parser->env)->p") + member_parser_p = p_env['p'] parser_obj = top_level_parse.add_or_get_parser(member_parser_p) if parser_obj.name is None: parser_obj.name_parser( self.name_from_vtable(parser_obj) ) self.member_parser = parser_obj - endianness_val = gdb.parse_and_eval("((HParseEndianness *) parser->env)->endianness") + #endianness_val = gdb.parse_and_eval("((HParseEndianness *) parser->env)->endianness") + endianness_val = p_env['endianness'] self.endianness = int(endianness_val) def __str__(self): @@ -312,8 +352,10 @@ class IgnoreEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser super().__init__(parser, top_level_parse) + parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference() - ignored_p = gdb.parse_and_eval("(HParser*) parser->env") + #ignored_p = gdb.parse_and_eval("(HParser*) parser->env") + ignored_p = parser_val['env'].cast(self.hparser_p_t) ignore_obj = top_level_parse.add_or_get_parser(ignored_p) if ignore_obj.name is None: @@ -323,25 +365,24 @@ class IgnoreEnv(HParserEnv): def __str__(self): return str([str(self.member_parser)]) -# TODO: numeric parameter passed to parse_and_eval class IgnoreSeqEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser self.member_parsers = [] + super().__init__(parser, top_level_parse) - h_ignoreseq_t = gdb.lookup_type("HIgnoreSeq") - h_ignoreseq_p_t = h_ignoreseq_t.pointer() + hignoreseq_t = gdb.lookup_type("HIgnoreSeq") + hignoreseq_p_t = h_ignoreseq_t.pointer() parser_obj = gdb.parse_and_eval("*parser") - p_env = parser_obj['env'].cast(h_ignoreseq_p_t).dereference() - ignoreseq_p = gdb.parse_and_eval("(HIgnoreSeq*) parser->env") + p_env = parser_obj['env'].cast(hignoreseq_p_t).dereference() + #ignoreseq_p = gdb.parse_and_eval("(HIgnoreSeq*) parser->env") #seq_len = gdb.parse_and_eval("((HIgnoreSeq*) parser->env)->len") seq_len = p_env['len'] #which = gdb.parse_and_eval("((HIgnoreSeq*) parser->env)->which") which = p_env['which'] self.which = int(which) parsers = p_env['parsers'] - super().__init__(parser, top_level_parse) for index in range(0, seq_len): parser_p = parsers[index] -- GitLab