(self, function)
inspect the given function to determine the frame layout and set references appropriately.

        args:
          function (Dict[str, any]): function instance.
inspect the given function to determine the frame layout and set references appropriately.
inspect the given function to determine the frame layout and set references appropriately .
def analyze_function_frame(self, function):
        '''
        inspect the given function to determine the frame layout and set references appropriately.

        args:
          function (Dict[str, any]): function instance.
        '''
        # given a function prologue like the following:
        #
        #     23 80 80 80 80 00       get_global          $global0
        #     21 04                   set_local           $local4
        #     41 20                   i32.const           0x20
        #     21 05                   set_local           $local5
        #     20 04                   get_local           $local4
        #     20 05                   get_local           $local5
        #     6B                      i32.sub
        #     21 06                   set_local           $local6
        #
        # recognize that the function frame is 0x20 bytes.

        if not self.has_llvm_prologue(function):
            return

        buf = ida_bytes.get_many_bytes(function['offset'], self.PROLOGUE_SIZE)
        bc = list(itertools.islice(wasm.decode.decode_bytecode(buf), 8))

        global_frame_pointer = bc[0].imm.global_index
        frame_size = bc[2].imm.value
        local_frame_pointer = bc[7].imm.local_index

        # add a frame structure to the function
        f = ida_funcs.get_func(function['offset'])
        ida_frame.add_frame(f, 0x0, 0x0, frame_size)
        ida_struct.set_struc_name(f.frame, ('frame%d' % function['index']).encode('utf-8'))

        # ensure global variable $frame_stack is named appropriately
        ida_name.set_name(self.proc.globals[global_frame_pointer]['offset'], '$frame_stack')

        # re-map local variable to $frame_pointer
        ida_frame.add_regvar(f,
                             function['offset'],
                             function['offset'] + function['size'],
                             '$local%d' % local_frame_pointer,
                             '$frame_pointer',
                             '')

        # define the frame structure layout by scanning for references within this function
        frame_references = self.find_function_frame_references(function, local_frame_pointer)
        for frame_offset, refs in frame_references.items():

            member_name = 'field_%x' % (frame_offset)
            for ref in refs:
                if 'parameter' in ref:
                    member_name = 'param%d' % (ref['parameter'])

            # pick largest element size for the element type
            flags = 0
            size = 0
            for ref in refs:
                fl = {'i8':  ida_bytes.FF_BYTE   | ida_bytes.FF_DATA,
                      'i16': ida_bytes.FF_WORD   | ida_bytes.FF_DATA,
                      'i32': ida_bytes.FF_DWORD  | ida_bytes.FF_DATA,
                      'i64': ida_bytes.FF_QWORD  | ida_bytes.FF_DATA,
                      'f32': ida_bytes.FF_FLOAT  | ida_bytes.FF_DATA,
                      'f64': ida_bytes.FF_DOUBLE | ida_bytes.FF_DATA,}[ref['element_size']]

                s = {'i8':  1,
                     'i16': 2,
                     'i32': 4,
                     'i64': 8,
                     'f32': 4,
                     'f64': 8,}[ref['element_size']]

                # by luck, FF_BYTE < FF_WORD < FF_DWORD < FF_QWORD,
                # so we can order flag values.
                if fl > flags:
                    flags = fl
                    size = s

            logger.debug('adding frame member %s to function %d', member_name, function['index'])
            ida_struct.add_struc_member(ida_struct.get_struc(f.frame),
                                        member_name,
                                        frame_offset,
                                        flags & 0xFFFFFFFF,
                                        None,
                                        size)

        # mark struct references
        for refs in frame_references.values():
            for ref in refs:
                # set type of operand 0 to function frame structure offset
                # ref: https://github.com/idapython/src/blob/a3855ab969fd16758b3de007525feeba3a920344/tools/inject_pydoc/bytes.py#L5
                insn = ida_ua.insn_t()
                if not ida_ua.decode_insn(insn, ref['offset']):
                    continue

                path = ida_pro.tid_array(1)
                path[0] = f.frame
                ida_bytes.op_stroff(insn, 0, path.cast(), 1, 0)
def analyze_function_frame ( self , function ) : # given a function prologue like the following: # #     23 80 80 80 80 00       get_global          $global0 #     21 04                   set_local           $local4 #     41 20                   i32.const           0x20 #     21 05                   set_local           $local5 #     20 04                   get_local           $local4 #     20 05                   get_local           $local5 #     6B                      i32.sub #     21 06                   set_local           $local6 # # recognize that the function frame is 0x20 bytes. if not self . has_llvm_prologue ( function ) : return buf = ida_bytes . get_many_bytes ( function [ 'offset' ] , self . PROLOGUE_SIZE ) bc = list ( itertools . islice ( wasm . decode . decode_bytecode ( buf ) , 8 ) ) global_frame_pointer = bc [ 0 ] . imm . global_index frame_size = bc [ 2 ] . imm . value local_frame_pointer = bc [ 7 ] . imm . local_index # add a frame structure to the function f = ida_funcs . get_func ( function [ 'offset' ] ) ida_frame . add_frame ( f , 0x0 , 0x0 , frame_size ) ida_struct . set_struc_name ( f . frame , ( 'frame%d' % function [ 'index' ] ) . encode ( 'utf-8' ) ) # ensure global variable $frame_stack is named appropriately ida_name . set_name ( self . proc . globals [ global_frame_pointer ] [ 'offset' ] , '$frame_stack' ) # re-map local variable to $frame_pointer ida_frame . add_regvar ( f , function [ 'offset' ] , function [ 'offset' ] + function [ 'size' ] , '$local%d' % local_frame_pointer , '$frame_pointer' , '' ) # define the frame structure layout by scanning for references within this function frame_references = self . find_function_frame_references ( function , local_frame_pointer ) for frame_offset , refs in frame_references . items ( ) : member_name = 'field_%x' % ( frame_offset ) for ref in refs : if 'parameter' in ref : member_name = 'param%d' % ( ref [ 'parameter' ] ) # pick largest element size for the element type flags = 0 size = 0 for ref in refs : fl = { 'i8' : ida_bytes . FF_BYTE | ida_bytes . FF_DATA , 'i16' : ida_bytes . FF_WORD | ida_bytes . FF_DATA , 'i32' : ida_bytes . FF_DWORD | ida_bytes . FF_DATA , 'i64' : ida_bytes . FF_QWORD | ida_bytes . FF_DATA , 'f32' : ida_bytes . FF_FLOAT | ida_bytes . FF_DATA , 'f64' : ida_bytes . FF_DOUBLE | ida_bytes . FF_DATA , } [ ref [ 'element_size' ] ] s = { 'i8' : 1 , 'i16' : 2 , 'i32' : 4 , 'i64' : 8 , 'f32' : 4 , 'f64' : 8 , } [ ref [ 'element_size' ] ] # by luck, FF_BYTE < FF_WORD < FF_DWORD < FF_QWORD, # so we can order flag values. if fl > flags : flags = fl size = s logger . debug ( 'adding frame member %s to function %d' , member_name , function [ 'index' ] ) ida_struct . add_struc_member ( ida_struct . get_struc ( f . frame ) , member_name , frame_offset , flags & 0xFFFFFFFF , None , size ) # mark struct references for refs in frame_references . values ( ) : for ref in refs : # set type of operand 0 to function frame structure offset # ref: https://github.com/idapython/src/blob/a3855ab969fd16758b3de007525feeba3a920344/tools/inject_pydoc/bytes.py#L5 insn = ida_ua . insn_t ( ) if not ida_ua . decode_insn ( insn , ref [ 'offset' ] ) : continue path = ida_pro . tid_array ( 1 ) path [ 0 ] = f . frame ida_bytes . op_stroff ( insn , 0 , path . cast ( ) , 1 , 0 )