# Buggy code
def _handle_CCall(self, expr):
    if not isinstance(expr.args[0], pyvex.IRExpr.Const):
        return
    cond_type_enum = expr.args[0].con.value

    if self.arch.name in ("X86", "AMD64"):
        if cond_type_enum in EXPECTED_COND_TYPES[self.arch.name]:
            self._handle_Comparison(expr.args[2], expr.args[3])
    elif is_arm_arch(self.arch):
        if cond_type_enum in EXPECTED_COND_TYPES["ARM"]:
            self._handle_Comparison(expr.args[2], expr.args[3])
    else:
        raise ValueError(
            "Unexpected ccall encountered in architecture %s." % self.arch.name
        )


# Traceback (ValueError)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-cef6a7e02e93> in <module>
----> 1 cfg = proj.analyses.CFG()

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/analysis.py in __call__(self, *args, **kwargs)
109
110         oself._show_progressbar = show_progressbar
--> 111         oself.__init__(*args, **kwargs)
112         return oself
113

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/cfg.py in __init__(self, **kwargs)
53
54         # Now initializes CFGFast :-)
---> 55         CFGFast.__init__(self, **kwargs)
56
57 from angr.analyses import AnalysesHub

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/cfg_fast.py in __init__(self, binary, objects, regions, pickle_intermediate_results, symbols, function_prologues, resolve_indirect_jumps, force_segment, force_complete_scan, indirect_jump_target_limit, data_references, cross_references, normalize, start_at_entry, function_starts, extra_memory_regions, data_type_guessing_handlers, arch_options, indirect_jump_resolvers, base_state, exclude_sparse_regions, skip_specific_regions, heuristic_plt_resolving, detect_tail_calls, low_priority, cfb, model, use_patches, start, end, collect_data_references, extra_cross_references, **extra_arch_options)
641
642         # Start working!
--> 643         self._analyze()
644
645     def __getstate__(self):

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/forward_analysis/forward_analysis.py in _analyze(self)
214             # An example is the CFG recovery.
215
--> 216             self._analysis_core_baremetal()
217
218         else:

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/forward_analysis/forward_analysis.py in _analysis_core_baremetal(self)
342
343             if not self._job_info_queue:
--> 344                 self._job_queue_empty()
345
346             if not self._job_info_queue:

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/cfg_fast.py in _job_queue_empty(self)
1134         # function 0x100006480 does not return. Hence, we resolve indirect jumps before popping undecided pending jobs.
1135         if self._resolve_indirect_jumps and self._indirect_jumps_to_resolve:
-> 1136             self._process_unresolved_indirect_jumps()
1137
1138             if self._job_info_queue:

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/cfg_base.py in _process_unresolved_indirect_jumps(self)
2207             if self._low_priority:
2208                 self._release_gil(idx, 20, 0.0001)
-> 2209             all_targets |= self._process_one_indirect_jump(jump)
2210
2211         self._indirect_jumps_to_resolve.clear()

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/cfg_base.py in _process_one_indirect_jump(self, jump)
2233                 continue
2234
-> 2235             resolved, targets = resolver.resolve(self, jump.addr, jump.func_addr, block, jump.jumpkind)
2236             if resolved:
2237                 resolved_by = resolver

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py in resolve(self, cfg, addr, func_addr, block, jumpkind)
467
468             l.debug("Try resolving %#x with a %d-level backward slice...", addr, slice_steps)
--> 469             r, targets = self._resolve(cfg, addr, func_addr, b)
470             if r:
471                 return r, targets

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py in _resolve(self, cfg, addr, func_addr, b)
521
522         try:
--> 523             stmts_to_instrument, regs_to_initialize = self._jumptable_precheck(b)
524         except NotAJumpTableNotification:
525             l.debug("Indirect jump at %#x does not look like a jump table. Skip.", addr)

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py in _jumptable_precheck(self, b)
868                 block = self.project.factory.block(block_addr, backup_state=self.base_state)
869                 stmt_whitelist = annotatedcfg.get_whitelisted_statements(block_addr)
--> 870                 engine.process(state, block=block, whitelist=stmt_whitelist)
871
872                 if state.is_jumptable:

~/Desktop/fuzzing/angr-dev/angr/angr/engines/light/engine.py in process(self, state, *args, **kwargs)
33         # we are using a completely different state. Therefore, we directly call our _process() method before
34         # SimEngine becomes flexible enough.
---> 35         self._process(state, None, block=kwargs.pop('block', None), whitelist=kwargs.pop('whitelist', None))
36
37     def _process(self, new_state, successors, *args, **kwargs):

~/Desktop/fuzzing/angr-dev/angr/angr/engines/light/engine.py in _process(self, state, successors, block, whitelist, *args, **kwargs)
68         self.tyenv = block.vex.tyenv
69
---> 70         self._process_Stmt(whitelist=whitelist)
71
72         self.stmt_idx = None

~/Desktop/fuzzing/angr-dev/angr/angr/engines/light/engine.py in _process_Stmt(self, whitelist)
89                 self.ins_addr = stmt.addr + stmt.delta
90
---> 91             self._handle_Stmt(stmt)
92
93         if self.block.vex.jumpkind == 'Ijk_Call':

~/Desktop/fuzzing/angr-dev/angr/angr/engines/light/engine.py in _handle_Stmt(self, stmt)
109         handler = "_handle_%s" % type(stmt).__name__
110         if hasattr(self, handler):
--> 111             getattr(self, handler)(stmt)
112         elif type(stmt).__name__ not in ('IMark', 'AbiHint'):
113             self.l.error('Unsupported statement type %s.', type(stmt).__name__)

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py in _handle_WrTmp(self, stmt)
145     def _handle_WrTmp(self, stmt):
146         self._tsrc = set()
--> 147         super()._handle_WrTmp(stmt)
148
149         if self._tsrc:

~/Desktop/fuzzing/angr-dev/angr/angr/engines/light/engine.py in _handle_WrTmp(self, stmt)
115     # synchronize with function _handle_WrTmpData()
116     def _handle_WrTmp(self, stmt):
--> 117         data = self._expr(stmt.data)
118         if data is None:
119             return

~/Desktop/fuzzing/angr-dev/angr/angr/engines/light/engine.py in _expr(self, expr)
141         handler = "_handle_%s" % type(expr).__name__
142         if hasattr(self, handler):
--> 143             return getattr(self, handler)(expr)
144         else:
145             self.l.error('Unsupported expression type %s.', type(expr).__name__)

~/Desktop/fuzzing/angr-dev/angr/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py in _handle_CCall(self, expr)
234                 self._handle_Comparison(expr.args[2], expr.args[3])
235         else:
--> 236             raise ValueError("Unexpected ccall encountered in architecture %s." % self.arch.name)
237
238     def _handle_Comparison(self, arg0, arg1):

ValueError: Unexpected ccall encountered in architecture AARCH64.

# Fixed code
def _handle_CCall(self, expr):
    if not isinstance(expr.args[0], pyvex.IRExpr.Const):
        return
    cond_type_enum = expr.args[0].con.value

    if self.arch.name in {"X86", "AMD64", "AARCH64"}:
        if cond_type_enum in EXPECTED_COND_TYPES[self.arch.name]:
            self._handle_Comparison(expr.args[2], expr.args[3])
    elif is_arm_arch(self.arch):
        if cond_type_enum in EXPECTED_COND_TYPES["ARM"]:
            self._handle_Comparison(expr.args[2], expr.args[3])
    else:
        raise ValueError(
            "Unexpected ccall encountered in architecture %s." % self.arch.name
        )