diff --git a/gdb-port/parser-type-instrumentation-gdb.py b/gdb-port/parser-type-instrumentation-gdb.py index ee9b45b70315bb9243f91afde7aa8e3323ad8c5f..35ecd65f8f9b105a045a263f786943b44bc2b501 100644 --- a/gdb-port/parser-type-instrumentation-gdb.py +++ b/gdb-port/parser-type-instrumentation-gdb.py @@ -147,12 +147,17 @@ class ButNotEnv(HParserEnv): self.parser = parser super().__init__(parser, top_level_parse) - p1_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p1") + htwoparsers_t = gdb.lookup_type("HTwoParsers") + htwoparsers_p_t = htwoparsers_t.pointer() + + 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: 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 = 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) ) @@ -165,8 +170,11 @@ 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() - member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p") + #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 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) ) @@ -216,7 +224,9 @@ class CharsetEnv(HParserEnv): def __str__(self): return str(self.charset_arg) -# TODO: numeric parameter passed to parse_and_eval +# 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) @@ -450,10 +460,9 @@ class OptionalEnv(HParserEnv): def __str__(self): return str(self.member_parser) -# TODO: numeric parameter passed to parse_and_eval class PermutationEnv(HParserEnv): def __init__(self, parser, top_level_parse): - super().__init__(parser, top_level_parse) # TODO: maybe move self.parser to base class. otherwise, is this needed? + super().__init__(parser, top_level_parse) self.parser = parser self.member_parsers = [] @@ -684,6 +693,7 @@ class ParserDecombinator: def decompose_parser(self, parser, top_level_parse): # Sadly, this is stringly typed for now + # TODO: use gdb.Value! parser_addr = parser.address vtable_p = gdb.parse_and_eval("((HParser*) " + str(parser_addr) + ")->vtable") try: