(self,
                                               functions,
                                               predetermined_function_addrs,
                                               blockaddr_to_function)
return functions_to_remove
Sometimes compilers will optimize "cold" code regions, make them separate functions, mark them as cold, which
        conflicts with how angr handles jumps to these functions (because they weren't functions to start with). Here
        is an example (in function version_etc_arn() from gllib)::

        switch (n_authors) {
          case 0:
            abort();
          case 1:
            ...
        }

        GCC may decide to move the `abort();` block under case 0 into a separate function (usually named
        "version_etc_arn_cold") and mark it as "cold." When loading function hints from eh frame is enabled, this
        function will be identified, and the recovered switch-case structure will have a jump to a function. It's
        usually not a problem until we need to decompile this function, where (at least for now) angr decompiler
        requires all switch-case entry blocks must belong to the same function.

        The temporary solution is identifying functions that (a) have no call predecessors, and (b) are used as
        jump targets for identified jump tables. Remove these functions so that they can be treated as part of the
        source function where the corresponding jump table belongs.
Sometimes compilers will optimize "cold" code regions, make them separate functions, mark them as cold, which
        conflicts with how angr handles jumps to these functions (because they weren't functions to start with). Here
        is an example (in function version_etc_arn() from gllib)::
Sometimes compilers will optimize cold code regions make them separate functions mark them as cold which conflicts with how angr handles jumps to these functions ( because they weren t functions to start with ) . Here is an example ( in function version_etc_arn () from gllib ) ::
def _process_jump_table_targeted_functions(self,
                                               functions,
                                               predetermined_function_addrs,
                                               blockaddr_to_function) -> Set[int]:
        """
        Sometimes compilers will optimize "cold" code regions, make them separate functions, mark them as cold, which
        conflicts with how angr handles jumps to these functions (because they weren't functions to start with). Here
        is an example (in function version_etc_arn() from gllib)::

        switch (n_authors) {
          case 0:
            abort();
          case 1:
            ...
        }

        GCC may decide to move the `abort();` block under case 0 into a separate function (usually named
        "version_etc_arn_cold") and mark it as "cold." When loading function hints from eh frame is enabled, this
        function will be identified, and the recovered switch-case structure will have a jump to a function. It's
        usually not a problem until we need to decompile this function, where (at least for now) angr decompiler
        requires all switch-case entry blocks must belong to the same function.

        The temporary solution is identifying functions that (a) have no call predecessors, and (b) are used as
        jump targets for identified jump tables. Remove these functions so that they can be treated as part of the
        source function where the corresponding jump table belongs.
        """

        jumptable_entries: Set[int] = set()
        for jt in self.model.jump_tables.values():
            jumptable_entries |= set(jt.jumptable_entries)

        if not jumptable_entries:
            return set()

        functions_to_remove = set()

        for func_addr in functions.keys():
            if func_addr in predetermined_function_addrs:
                continue
            if func_addr in jumptable_entries:
                # is there any call edge pointing to it?
                func_node = self.get_any_node(func_addr)
                if func_node is not None:
                    in_edges = self.graph.in_edges(func_node, data=True)
                    has_transition_pred = None
                    has_non_transition_pred = None
                    for _, _, data in in_edges:
                        if data.get("jumpkind", None) == "Ijk_Boring":
                            has_transition_pred = True
                        else:
                            has_non_transition_pred = True
                    if has_transition_pred is True and not has_non_transition_pred:
                        # all predecessors are transition-only
                        # remove this function
                        functions_to_remove.add(func_addr)

        for to_remove in functions_to_remove:
            del functions[to_remove]
            if to_remove in blockaddr_to_function:
                del blockaddr_to_function[to_remove]

        return functions_to_remove
def _process_jump_table_targeted_functions ( self , functions , predetermined_function_addrs , blockaddr_to_function ) -> Set [ int ] : jumptable_entries : Set [ int ] = set ( ) for jt in self . model . jump_tables . values ( ) : jumptable_entries |= set ( jt . jumptable_entries ) if not jumptable_entries : return set ( ) functions_to_remove = set ( ) for func_addr in functions . keys ( ) : if func_addr in predetermined_function_addrs : continue if func_addr in jumptable_entries : # is there any call edge pointing to it? func_node = self . get_any_node ( func_addr ) if func_node is not None : in_edges = self . graph . in_edges ( func_node , data = True ) has_transition_pred = None has_non_transition_pred = None for _ , _ , data in in_edges : if data . get ( "jumpkind" , None ) == "Ijk_Boring" : has_transition_pred = True else : has_non_transition_pred = True if has_transition_pred is True and not has_non_transition_pred : # all predecessors are transition-only # remove this function functions_to_remove . add ( func_addr ) for to_remove in functions_to_remove : del functions [ to_remove ] if to_remove in blockaddr_to_function : del blockaddr_to_function [ to_remove ] return functions_to_remove