def type_to_reg_and_slot(node, chooser, i): '''c_ast -> fn -> int -> (reg_type, slot_type) | None''' def yield_void(): # return an empty list for (void) arglists raise StopIteration def maybe_fail(node): if type(node) is c_ast.Struct: raise StructByValueError('structs by value not yet supported') return type_to_reg_and_slot(node.type, chooser, i) def get(names): '''[str] -> (gpr|fpr, slot_ty)''' if 'void' in names: return yield_void() ti = ida.parse_decl(' '.join(names)) (ty, base, slot) = chooser(ti) return (ty(base + i), slot) sw = { c_ast.Decl: lambda x: type_to_reg_and_slot(x.type, chooser, i), c_ast.TypeDecl: lambda x: type_to_reg_and_slot(x.type, chooser, i), c_ast.Typename: lambda x: type_to_reg_and_slot(x.type, chooser, i), c_ast.IdentifierType: lambda x: get(x.names) } if i > 7: raise RegSpillError('spilling registers to stack not yet supported') # in order to use chooser we need a tinfo_t--make one suitable for an # an int (which is also suitable for a pointer on N32) dummy_ti = ida.parse_decl('int') (_, base, _) = chooser(dummy_ti) node_ty = type(node) if node_ty in [c_ast.ArrayDecl, c_ast.PtrDecl]: return (regs.gpr(base + i), ep_ct.slot_types.u64) elif node_ty is c_ast.Enum: return (regs.gpr(base + i), ep_ct.slot_types.i64) else: return utils.dictswitch(node_ty, sw, node, maybe_fail, node)
def type_to_reg_and_slot(node, chooser, i): '''c_ast -> fn -> int -> (reg_type, slot_type) | None''' def yield_void(): # return an empty list for (void) arglists raise StopIteration def maybe_fail(node): if type(node) is c_ast.Struct: raise StructByValueError('structs by value not yet supported') return type_to_reg_and_slot(node.type, chooser, i) def get(names): '''[str] -> (gpr|fpr, slot_ty)''' if 'void' in names: return yield_void() ti = ida.parse_decl(' '.join(names)) (ty, base, slot) = chooser(ti) return (ty(base + i), slot) sw = { c_ast.Decl : lambda x: type_to_reg_and_slot(x.type, chooser, i), c_ast.TypeDecl : lambda x: type_to_reg_and_slot(x.type, chooser, i), c_ast.Typename : lambda x: type_to_reg_and_slot(x.type, chooser, i), c_ast.IdentifierType : lambda x: get(x.names) } if i > 7: raise RegSpillError('spilling registers to stack not yet supported') # in order to use chooser we need a tinfo_t--make one suitable for an # an int (which is also suitable for a pointer on N32) dummy_ti = ida.parse_decl('int') (_, base, _) = chooser(dummy_ti) node_ty = type(node) if node_ty in [c_ast.ArrayDecl, c_ast.PtrDecl]: return (regs.gpr(base + i), ep_ct.slot_types.u64) elif node_ty is c_ast.Enum: return (regs.gpr(base + i), ep_ct.slot_types.i64) else: return utils.dictswitch(node_ty, sw, node, maybe_fail, node)
def get_decl_type_and_names(node): '''c_ast -> (c_ast, (str*))''' def fail(node): node_fail(ComplicatedDeclError, 'not a typedef or data declaration:\n%s', node) sw = { c_ast.Decl: lambda x: get_decl_type_and_names(x.decl), c_ast.TypeDecl: lambda x: get_decl_type_and_names(x.type), c_ast.Typename: lambda x: get_decl_type_and_names(x.names), c_ast.Struct: lambda x: (c_ast.Struct, (x.name, )), c_ast.Union: lambda x: (c_ast.Union, (x.name, )), c_ast.Enum: lambda x: (c_ast.Decl, (x.name, )), c_ast.ArrayDecl: lambda x: get_decl_type_and_names(x.type), c_ast.PtrDecl: lambda x: get_decl_type_and_names(x.type), c_ast.IdentifierType: lambda x: (c_ast.Decl, tuple(x.names)) } return utils.dictswitch(type(node), sw, node, fail, node)
def get_decl_type_and_names(node): '''c_ast -> (c_ast, (str*))''' def fail(node): node_fail(ComplicatedDeclError, 'not a typedef or data declaration:\n%s', node) sw = { c_ast.Decl: lambda x: get_decl_type_and_names(x.decl), c_ast.TypeDecl: lambda x: get_decl_type_and_names(x.type), c_ast.Typename: lambda x: get_decl_type_and_names(x.names), c_ast.Struct: lambda x: (c_ast.Struct, (x.name,)), c_ast.Union: lambda x: (c_ast.Union, (x.name,)), c_ast.Enum: lambda x: (c_ast.Decl, (x.name,)), c_ast.ArrayDecl: lambda x: get_decl_type_and_names(x.type), c_ast.PtrDecl: lambda x: get_decl_type_and_names(x.type), c_ast.IdentifierType: lambda x: (c_ast.Decl, tuple(x.names)) } return utils.dictswitch(type(node), sw, node, fail, node)