# Buggy code
def _create_job_call(
    self,
    addr,
    irsb,
    cfg_node,
    stmt_idx,
    ins_addr,
    current_function_addr,
    target_addr,
    jumpkind,
    is_syscall=False,
):
    """
    Generate a CFGJob for target address, also adding to _pending_entries
    if returning to succeeding position (if irsb arg is populated)

    :param int addr:            Address of the predecessor node
    :param pyvex.IRSB irsb:     IRSB of the predecessor node
    :param CFGNode cfg_node:    The CFGNode instance of the predecessor node
    :param int stmt_idx:        ID of the source statement
    :param int ins_addr:        Address of the source instruction
    :param int current_function_addr: Address of the current function
    :param int target_addr:     Destination of the call
    :param str jumpkind:        The jumpkind of the edge going to this node
    :param bool is_syscall:     Is the jump kind (and thus this) a system call
    :return:                    A list of CFGJobs
    :rtype:                     list
    """

    jobs = []

    if is_syscall:
        # Fix the target_addr for syscalls
        tmp_state = self.project.factory.blank_state(
            mode="fastpath", addr=cfg_node.addr
        )
        succ = self.project.factory.successors(tmp_state).flat_successors[0]
        try:
            syscall_stub = self.project.simos.syscall(succ)
            if syscall_stub:  # can be None if simos is not a subclass of SimUserspac
                syscall_addr = syscall_stub.addr
                target_addr = syscall_addr
            else:
                target_addr = self._unresolvable_target_addr
        except AngrUnsupportedSyscallError:
            target_addr = self._unresolvable_target_addr

    new_function_addr = target_addr
    if irsb is None:
        return_site = None
    else:
        return_site = (
            addr + irsb.size
        )  # We assume the program will always return to the succeeding position

    if new_function_addr is not None:
        r = self._function_add_call_edge(
            new_function_addr,
            cfg_node,
            return_site,
            current_function_addr,
            syscall=is_syscall,
            stmt_idx=stmt_idx,
            ins_addr=ins_addr,
        )
        if not r:
            return []

    if new_function_addr is not None:
        # Keep tracing from the call
        ce = CFGJob(
            target_addr,
            new_function_addr,
            jumpkind,
            last_addr=addr,
            src_node=cfg_node,
            src_stmt_idx=stmt_idx,
            src_ins_addr=ins_addr,
            syscall=is_syscall,
        )
        jobs.append(ce)

    if return_site is not None:
        # Also, keep tracing from the return site
        ce = CFGJob(
            return_site,
            current_function_addr,
            "Ijk_FakeRet",
            last_addr=addr,
            src_node=cfg_node,
            src_stmt_idx=stmt_idx,
            src_ins_addr=ins_addr,
            returning_source=new_function_addr,
            syscall=is_syscall,
        )
        self._pending_jobs.add_job(ce)
        # register this job to this function
        self._register_analysis_job(current_function_addr, ce)

    if new_function_addr is not None:
        callee_function = self.kb.functions.function(
            addr=new_function_addr, syscall=is_syscall
        )

        if callee_function.returning is True:
            if return_site is not None:
                self._function_add_fakeret_edge(
                    return_site, cfg_node, current_function_addr, confirmed=True
                )
                self._function_add_return_edge(
                    new_function_addr, return_site, current_function_addr
                )
        elif callee_function.returning is False:
            # The function does not return - there is no fake ret edge
            pass
        else:
            if return_site is not None:
                self._function_add_fakeret_edge(
                    return_site, cfg_node, current_function_addr, confirmed=None
                )
                fr = FunctionReturn(
                    new_function_addr, current_function_addr, addr, return_site
                )
                if fr not in self._function_returns[new_function_addr]:
                    self._function_returns[new_function_addr].append(fr)

    return jobs


# Traceback (angr.errors.AngrSyscallError)
ERROR   | 2018-04-28 18:12:46,695 | angr.engines.vex.statements.dirty | Unsupported dirty helper amd64g_dirtyhelper_FSTENV
ERROR   | 2018-04-28 18:12:46,696 | angr.engines.vex.statements.dirty | Unsupported dirty helper amd64g_dirtyhelper_FLDENV
WARNING | 2018-04-28 18:12:46,704 | angr.procedures.definitions | unsupported syscall: rt_sigprocmask
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/analysis.py", line 96, in make_analysis
oself.__init__(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg.py", line 58, in __init__
CFGFast.__init__(self, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg_fast.py", line 819, in __init__
self._analyze()
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/forward_analysis.py", line 508, in _analyze
self._analysis_core_baremetal()
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/forward_analysis.py", line 633, in _analysis_core_baremetal
self._process_job_and_get_successors(job_info)
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/forward_analysis.py", line 651, in _process_job_and_get_successors
successors = self._get_successors(job)
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg_fast.py", line 1210, in _get_successors
jobs = self._scan_block(addr, current_function_addr, jumpkind, src_node, src_ins_addr, src_stmt_idx)
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg_fast.py", line 1484, in _scan_block
previous_src_ins_addr, previous_src_stmt_idx)
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg_fast.py", line 1656, in _scan_irsb
stmt_idx
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg_fast.py", line 1818, in _create_jobs
target_addr, jumpkind, is_syscall=is_syscall
File "/usr/local/lib/python2.7/dist-packages/angr/analyses/cfg/cfg_fast.py", line 1886, in _create_job_call
syscall_stub = self.project.simos.syscall(succ)
File "/usr/local/lib/python2.7/dist-packages/angr/simos/userland.py", line 55, in syscall
abi = self.syscall_abi(state)
File "/usr/local/lib/python2.7/dist-packages/angr/simos/linux.py", line 147, in syscall_abi
raise AngrSyscallError("Unknown syscall jumpkind %s" % state.history.jumpkind)
angr.errors.AngrSyscallError: Unknown syscall jumpkind Ijk_EmWarn

# Fixed code
def _create_job_call(
    self,
    addr,
    irsb,
    cfg_node,
    stmt_idx,
    ins_addr,
    current_function_addr,
    target_addr,
    jumpkind,
    is_syscall=False,
):
    """
    Generate a CFGJob for target address, also adding to _pending_entries
    if returning to succeeding position (if irsb arg is populated)

    :param int addr:            Address of the predecessor node
    :param pyvex.IRSB irsb:     IRSB of the predecessor node
    :param CFGNode cfg_node:    The CFGNode instance of the predecessor node
    :param int stmt_idx:        ID of the source statement
    :param int ins_addr:        Address of the source instruction
    :param int current_function_addr: Address of the current function
    :param int target_addr:     Destination of the call
    :param str jumpkind:        The jumpkind of the edge going to this node
    :param bool is_syscall:     Is the jump kind (and thus this) a system call
    :return:                    A list of CFGJobs
    :rtype:                     list
    """

    jobs = []

    if is_syscall:
        # Fix the target_addr for syscalls
        tmp_state = self.project.factory.blank_state(
            mode="fastpath", addr=cfg_node.addr
        )
        # Find the first successor with a syscall jumpkind
        succ = next(
            iter(
                succ
                for succ in self.project.factory.successors(tmp_state).flat_successors
                if succ.jumpkind and succ.jumpkind.startswith("Ijk_Sys")
            ),
            None,
        )
        if succ is None:
            # For some reason, there is no such successor with a syscall jumpkind
            target_addr = self._unresolvable_target_addr
        else:
            try:
                syscall_stub = self.project.simos.syscall(succ)
                if (
                    syscall_stub
                ):  # can be None if simos is not a subclass of SimUserspac
                    syscall_addr = syscall_stub.addr
                    target_addr = syscall_addr
                else:
                    target_addr = self._unresolvable_target_addr
            except AngrUnsupportedSyscallError:
                target_addr = self._unresolvable_target_addr

    new_function_addr = target_addr
    if irsb is None:
        return_site = None
    else:
        return_site = (
            addr + irsb.size
        )  # We assume the program will always return to the succeeding position

    if new_function_addr is not None:
        r = self._function_add_call_edge(
            new_function_addr,
            cfg_node,
            return_site,
            current_function_addr,
            syscall=is_syscall,
            stmt_idx=stmt_idx,
            ins_addr=ins_addr,
        )
        if not r:
            return []

    if new_function_addr is not None:
        # Keep tracing from the call
        ce = CFGJob(
            target_addr,
            new_function_addr,
            jumpkind,
            last_addr=addr,
            src_node=cfg_node,
            src_stmt_idx=stmt_idx,
            src_ins_addr=ins_addr,
            syscall=is_syscall,
        )
        jobs.append(ce)

    if return_site is not None:
        # Also, keep tracing from the return site
        ce = CFGJob(
            return_site,
            current_function_addr,
            "Ijk_FakeRet",
            last_addr=addr,
            src_node=cfg_node,
            src_stmt_idx=stmt_idx,
            src_ins_addr=ins_addr,
            returning_source=new_function_addr,
            syscall=is_syscall,
        )
        self._pending_jobs.add_job(ce)
        # register this job to this function
        self._register_analysis_job(current_function_addr, ce)

    if new_function_addr is not None:
        callee_function = self.kb.functions.function(
            addr=new_function_addr, syscall=is_syscall
        )

        if callee_function.returning is True:
            if return_site is not None:
                self._function_add_fakeret_edge(
                    return_site, cfg_node, current_function_addr, confirmed=True
                )
                self._function_add_return_edge(
                    new_function_addr, return_site, current_function_addr
                )
        elif callee_function.returning is False:
            # The function does not return - there is no fake ret edge
            pass
        else:
            if return_site is not None:
                self._function_add_fakeret_edge(
                    return_site, cfg_node, current_function_addr, confirmed=None
                )
                fr = FunctionReturn(
                    new_function_addr, current_function_addr, addr, return_site
                )
                if fr not in self._function_returns[new_function_addr]:
                    self._function_returns[new_function_addr].append(fr)

    return jobs