Carlos Jesus Bernardos

89 papers A* 1B 5C 6Misc 1Journal 53Unranked 23
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
David Rico-Menendez, Pablo Picazo-Martínez, Antonio de la Oliva, Carlos Jesus Bernardos, Chathura Sarathchandra, Alain Mourad
2023 J jnl
IEEE Commun. Mag.
Jorge Martín-Pérez, Nuria Molner, Francesco Malandrino, Carlos Jesus Bernardos, Antonio de la Oliva, David Gomez-Barquero
2022 J jnl
CoRR
Jorge Martín-Pérez, Nuria Molner, Francesco Malandrino, Carlos Jesus Bernardos, Antonio de la Oliva, David Gomez-Barquero
2020 A* conf
INFOCOM
Jorge Martín-Pérez, Francesco Malandrino, Carla-Fabiana Chiasserini, Carlos Jesus Bernardos
2018 J jnl
IEEE Commun. Mag.
Antonio de la Oliva, Xi Li, Xavier Pérez Costa, Carlos Jesus Bernardos, Philippe Bertin, Paola Iovanna, Thomas Deiß, Josep Mangues, Alain Mourad, Claudio Casetti, Jose Enrique Gonzalez, Arturo Azcorra
2018 J jnl
RFC
Jonas Ahlberg, Min Ye, Xi Li, Luis Miguel Contreras Murillo, Carlos Jesus Bernardos
2018 conf
BMSB
Luis M. Contreras, Hitoshi Asaeda, Carlos Jesus Bernardos, Nic Leymann
2018 conf
EM-5G@CoNEXT
Kiril Antevski, Milan Groshev, Luca Cominardi, Carlos Jesus Bernardos, Alain Mourad, Robert Gazda
2018 J jnl
Comput. Stand. Interfaces
Luca Cominardi, Carlos Jesus Bernardos, Pablo Serrano, Albert Banchs, Antonio de la Oliva
2018 C conf
ISNCC
Juhoon Kim, Luis M. Contreras, Pierluigi Greto, Hilmar Magnusson, Hagen Woesner, Daniel Fritzsche, Luca Cominardi, Carlos Jesus Bernardos
2018 conf
OFC
Ajmal Muhammad, Andrea Sgambelluri, Olivier Dugeon, Jorge Martín-Pérez, Francesco Paolucci, Óscar González de Dios, Fabio Ubaldi, Teresa Pepe, Carlos Jesus Bernardos, Paolo Monti
2018 B conf
NOMS
Ishan Vaishnavi, János Czentye, Molka Gharbaoui, Giovanni Giuliani, Dávid Haja, János Harmatos, Dávid Jocha, Yoonhee Kim, Barbara Martini, Javier Melian, Paolo Monti, Balázs Németh, Wint Yi Poe, Aurora Ramos, Andrea Sgambelluri, Balázs Sonkoly, László Toka, Francesco Tusa, Carlos Jesus Bernardos, Róbert Szabó
2018 conf
WCNC Workshops
Xi Li, Josep Mangues-Bafalluy, Iñaki Pascual, Giada Landi, Francesca Moscatelli, Kiril Antevski, Carlos Jesus Bernardos, Luca Valcarenghi, Barbara Martini, Carla-Fabiana Chiasserini, Claudio Casetti, Dmitriy Andrushko, Nicolas A. Serrano, Adlen Ksentini
2018 conf
BMSB
Sergio González, Antonio de la Oliva, Carlos Jesus Bernardos, Luis M. Contreras
2018 conf
BMSB
Luca Cominardi, Luis M. Contreras, Carlos Jesus Bernardos, Ignacio Berberana
2017 J jnl
Trans. Emerg. Telecommun. Technol.
Riccardo Guerzoni, Ishan Vaishnavi, David Pérez-Caparrós, Alex Galis, Francesco Tusa, Paolo Monti, Andrea Sgambelluri, Gergely Biczók, Balázs Sonkoly, László Toka, Aurora Ramos, Javier Melian, Olivier Dugeon, Filippo Cugini, Barbara Martini, Paola Iovanna, Giovanni Giuliani, Ricardo Figueiredo, Luis Miguel Contreras Murillo, Carlos Jesus Bernardos, Cristina Santana, Róbert Szabó
2017 J jnl
Comput. Networks
Luca Cominardi, Fabio Giust, Carlos Jesus Bernardos, Antonio de la Oliva
2017 conf
EuCNC
Andrea Sgambelluri, Francesco Tusa, Molka Gharbaoui, Elisa Maini, László Toka, Jorge Martín-Pérez, Francesco Paolucci, Barbara Martini, Wint Yi Poe, Javier Melian Hernandes, Ajmal Muhammed, Aurora Ramos, Óscar González de Dios, Balázs Sonkoly, Paolo Monti, Ishan Vaishnavi, Carlos Jesus Bernardos, Róbert Szabó
2017 B conf
NetSoft
Luis M. Contreras, Carlos Jesus Bernardos, Antonio de la Oliva, Xavier Costa-Pérez
2017 J jnl
Comput. Stand. Interfaces
Diego R. López, Hosnieh Rafiee, Carlos Jesus Bernardos, Gabriel López Millán, Rafael Marín López
2017 J jnl
Trans. Emerg. Telecommun. Technol.
Dario Bega, Marco Gramaglia, Carlos Jesus Bernardos, Albert Banchs, Xavier Pérez Costa
2016 J jnl
Trans. Emerg. Telecommun. Technol.
Carlos Jesus Bernardos, Balázs Péter Gero, Marco Di Girolamo, András Kern, Barbara Martini, Ishan Vaishnavi
2016 J jnl
Comput. Networks
M. Isabel Sanchez, Antonio de la Oliva, Carlos Jesus Bernardos
2016 J jnl
Comput. Commun.
M. Isabel Sanchez, Engin Zeydan, Antonio de la Oliva, Ahmet Serdar Tan, Utku Yabas, Carlos Jesus Bernardos
2016 conf
EuCNC
Luis M. Contreras, Carlos Jesus Bernardos, Antonio de la Oliva, Xavier Costa-Pérez, Riccardo Guerzoni
2016 J jnl
Mob. Networks Appl.
Luis M. Contreras, Luca Cominardi, Haiyang Qian, Carlos Jesus Bernardos
2015 J jnl
IEEE Netw.
Carlos Donato, Pablo Serrano, Antonio de la Oliva, Albert Banchs, Carlos Jesus Bernardos
2015 conf
VTC Spring
Fabio Giust, Gerald Kunzmann, Daniele Munaretto, Carlos Jesus Bernardos, Bessem Sayadi
2015 J jnl
RFC
Dapeng Liu, Juan Carlos Zúñiga, Pierrick Seite, H. Anthony Chan, Carlos Jesus Bernardos
2015 J jnl
IEEE Commun. Mag.
Fabio Giust, Luca Cominardi, Carlos Jesus Bernardos
2015 J jnl
Telecommun. Syst.
Fabio Giust, Carlos Jesus Bernardos, Antonio de la Oliva
2015 conf
EuCNC
Dongyao Wang, Efstathios Katranaras, Atta ul Quddus, Nikolaos Sapountzis, Luca Cominardi, Fang-Chun Kuo, Peter Rost, Carlos Jesus Bernardos, Ignacio Berberana
2015 J jnl
Mob. Networks Appl.
Dudu Bercovich, Luis M. Contreras, Yoram Haddad, Ariel Adam, Carlos Jesus Bernardos
2015 conf
CSCN
Carlos Jesus Bernardos, Juan Carlos Zúñiga, Piers O'Hanlon
2014 J jnl
IEEE Wirel. Commun.
Carlos Jesus Bernardos, Antonio de la Oliva, Pablo Serrano, Albert Banchs, Luis M. Contreras, Hao Jin, Juan Carlos Zúñiga
2014 J jnl
IEEE Trans. Mob. Comput.
Fabio Giust, Carlos Jesus Bernardos, Antonio de la Oliva
2014 J jnl
IEEE Commun. Mag.
Peter Rost, Carlos Jesus Bernardos, Antonio De Domenico, Marco Di Girolamo, Massinissa Lalam, Andreas Mäder, Dario Sabella, Dirk Wübben
2014 J jnl
Ad Hoc Networks
M. Isabel Sanchez, Marco Gramaglia, Carlos Jesus Bernardos, Antonio de la Oliva, María Calderón
2014 J jnl
RFC
Xingyue Zhou, Jouni Korhonen, Carl Williams, Sri Gundavelli, Carlos Jesus Bernardos
2014 J jnl
RFC
Luis Miguel Contreras Murillo, Carlos Jesus Bernardos, Ignacio Soto
2013 conf
Future Network & Mobile Summit
Carlos Jesus Bernardos, Antonio De Domenico, Jorge Ortín, Peter Rost, Dirk Wübben
2013 J jnl
Ad Hoc Networks
Victor Sandonis, María Calderón, Ignacio Soto, Carlos Jesus Bernardos
2013 J jnl
IEEE Commun. Mag.
Juan Carlos Zúñiga, Carlos Jesus Bernardos, Antonio de la Oliva, Telemaco Melia, Rui Pedro Ferreira Da Costa, Alex Reznik
2013 conf
VTC Fall
M. Isabel Sanchez, Carlos Jesus Bernardos, Antonio de la Oliva, Pablo Serrano
2013 C conf
WOWMOM
Fabio Giust, Antonio de la Oliva, Carlos Jesus Bernardos
2013 J jnl
RFC
Juan Carlos Zúñiga, Luis Miguel Contreras Murillo, Carlos Jesus Bernardos, Seil Jeon, Younghan Kim
2013 J jnl
IEEE Commun. Mag.
M. Isabel Sanchez, Manuel Urueña, Antonio de la Oliva, José Alberto Hernández, Carlos Jesus Bernardos
2013 J jnl
J. Netw. Comput. Appl.
Sardar Muhammad Bilal, Carlos Jesus Bernardos, Carmen Guerrero
2013 J jnl
Comput. Stand. Interfaces
Antonio de la Oliva, Ignacio Soto, María Calderón, Carlos Jesus Bernardos, M. Isabel Sanchez
2013 J jnl
IEEE Netw.
Carlos Jesus Bernardos, Ulas C. Kozat, Joerg Widmer, Michele Zorzi
2013 J jnl
Sensors
Marco Gramaglia, Carlos Jesus Bernardos, María Calderón
2012 J jnl
IEEE Wirel. Commun.
Antonio de la Oliva, María Calderón, Carlos Jesus Bernardos, Ryuji Wakikawa
2012 J jnl
EURASIP J. Wirel. Commun. Netw.
Marco Gramaglia, Carlos Jesus Bernardos, Ignacio Soto, María Calderón, Roberto Baldessari
2012 conf
ICC
Carlos Jesus Bernardos, Juan Carlos Zúñiga, Alex Reznik
2012 conf
MONAMI
Rui Pedro Ferreira Da Costa, Telemaco Melia, Lucas Eznarriaga, Fabio Giust, Antonio de la Oliva, Carlos Jesus Bernardos
2011 C conf
ISCC
Fabio Giust, Carlos Jesus Bernardos, Sérgio Figueiredo, Pedro Neves, Telemaco Melia
2011 conf
WPMC
Fabio Giust, Antonio de la Oliva, Carlos Jesus Bernardos, Rui Pedro Ferreira Da Costa
2011 J jnl
RFC
Ralph E. Droms, Pascal Thubert, Francis Dupont, Wassim Michel Haddad, Carlos Jesus Bernardos
2011 conf
Future Network & Mobile Summit
Telemaco Melia, Fabio Giust, Riccardo Manfrin, Antonio de la Oliva, Carlos Jesus Bernardos, Michelle Wetterwald
2011 conf
Future Network & Mobile Summit
Antonio de la Oliva, Lucas Eznarriaga, Carlos Jesus Bernardos, Pablo Serrano, Albert Vidal
2011 J jnl
Wirel. Pers. Commun.
Telemaco Melia, Carlos Jesus Bernardos, Antonio de la Oliva, Fabio Giust, María Calderón
2011 J jnl
IEEE Commun. Mag.
Antonio de la Oliva, Carlos Jesus Bernardos, María Calderón, Telemaco Melia, Juan Carlos Zúñiga
2011 conf
MONAMI
Daniel Corujo, Carlos Jesus Bernardos, Telemaco Melia, Michelle Wetterwald, Leonardo Badia, Rui L. Aguiar
2011 C conf
WOWMOM
Marco Gramaglia, Pablo Serrano, José Alberto Hernández, María Calderón, Carlos Jesus Bernardos
2011 J jnl
IEEE Trans. Veh. Technol.
Marco Gramaglia, Ignacio Soto, Carlos Jesus Bernardos, María Calderón
2011 J jnl
J. Wirel. Mob. Networks Ubiquitous Comput. Dependable Appl.
Luis M. Contreras, Carlos Jesus Bernardos, Ignacio Soto
2011 J jnl
EURASIP J. Wirel. Commun. Netw.
Marco Gramaglia, Carlos Jesus Bernardos, María Calderón
2011 conf
VTC Spring
Marco Gramaglia, María Calderón, Carlos Jesus Bernardos
2010 J jnl
IEEE Netw.
Carlos Jesus Bernardos, Andreas Festag, Nicholas F. Maxemchuk, Carolina Pinart, C. Weib
2010 J jnl
Comput. Networks
Carlos Jesus Bernardos, María Calderón, Ignacio Soto, Ana Beatriz Solana, Kilian Weniger
2010 J jnl
EURASIP J. Wirel. Commun. Netw.
Pablo Serrano, Carlos Jesus Bernardos, Antonio de la Oliva, Albert Banchs, Ignacio Soto, Michael Zink
2010 J jnl
J. Wirel. Mob. Networks Ubiquitous Comput. Dependable Appl.
Carlos Jesus Bernardos, Marco Gramaglia, Luis M. Contreras, María Calderón, Ignacio Soto
2009 C conf
WOWMOM
Pablo Serrano, Antonio de la Oliva, Carlos Jesus Bernardos, Ignacio Soto, Albert Banchs, Arturo Azcorra
2009 J jnl
IEEE Commun. Mag.
Ignacio Soto, Carlos Jesus Bernardos, María Calderón, Albert Banchs, Arturo Azcorra
2008 B conf
PIMRC
Roberto Baldessari, Carlos Jesus Bernardos, María Calderón
2007 J jnl
ACM SIGMOBILE Mob. Comput. Commun. Rev.
Antonio de la Oliva, Telemaco Melia, Albert Vidal, Carlos Jesus Bernardos, Ignacio Soto, Albert Banchs
2007 J jnl
Comput. Networks
Pablo Vidales, Carlos Jesus Bernardos, Ignacio Soto, David Naveen Cottingham, Javier Baliosian, Jon Crowcroft
2007 conf
VTC Spring
Rubén Cuevas Rumín, Carmen Guerrero, Ángel Cuevas, María Calderón, Carlos Jesus Bernardos
2007 J jnl
Comput. Commun.
Carlos Jesus Bernardos, Ignacio Soto, María Calderón, Fernando Boavida, Arturo Azcorra
2006 conf
ICUC
Carlos Jesus Bernardos, María Calderón
2006 B conf
GLOBECOM
Telemaco Melia, Antonio de la Oliva, Ignacio Soto, Carlos Jesus Bernardos, Albert Vidal
2006 J jnl
IEEE J. Sel. Areas Commun.
María Calderón, Carlos Jesus Bernardos, Marcelo Bagnulo, Ignacio Soto, Antonio de la Oliva
2006 J jnl
IEEE Commun. Mag.
Rui L. Aguiar, Susana Sargento, Albert Banchs, Carlos Jesus Bernardos, María Calderón, Ignacio Soto, Marco Liebsch, Telemaco Melia, Piotr Pacyna
2005 Misc conf
TRIDENTCOM
Pablo Vidales, Glenford E. Mapp, Frank Stajano, Jon Crowcroft, Carlos Jesus Bernardos
2005 J jnl
Eur. Trans. Telecommun.
Carlos Jesus Bernardos, Ignacio Soto, José Ignacio Moreno, Telemaco Melia, Marco Liebsch, Ralf Schmitz
2005 conf
EUNICE
Antonio de la Oliva, Carlos Jesus Bernardos, María Calderón
2005 B conf
WiOpt
María Calderón, Carlos Jesus Bernardos, Marcelo Bagnulo, Ignacio Soto
2005 C conf
ISCC
Marcelo Bagnulo, Alberto García-Martínez, Carlos Jesus Bernardos, Isaías Martinez-Yelmo, Arturo Azcorra
2005 J jnl
J. Commun. Networks
Antonio Cuevas, Pablo Serrano, José Ignacio Moreno, Carlos Jesus Bernardos, Jürgen Jähnert, Rui L. Aguiar, Victor Marques
redb/extractors/decompiler/bninja/analysis/cfg-old.py
← Index redb/extractors/decompiler/bninja/analysis/cfg-old.py python
from collections import deque
from enum import Enum

from binaryninja.enums import (
    BranchType,
    InstructionTextTokenType,
)

# Support both package and standalone imports
try:
    from ..utils.hashes import calculate_md5, calculate_sha256
except ImportError:
    # Fallback to absolute imports (for multiprocessing spawned processes)
    from redb.extractors.decompiler.bninja.utils.hashes import calculate_md5, calculate_sha256


class CFGAnalysis:
    def __init__(self, function):
        self.function = function

    def determine_block_type(self, block) -> str:
        """Determine the type of a basic block."""
        # Check if it's a thunk function (usually just a jump or call)
        if len(block.disassembly_text) <= 2 and any(
            "jmp" in line.tokens[0].text.lower() for line in block.disassembly_text
        ):
            return "THUNK"

        # Check if it contains only data (no valid instructions)
        if all(not line.tokens for line in block.disassembly_text):
            return "DATA"

        # Default to code
        return "CODE"

    def extract_cyclomatic_complexity(self):
        """
        Cyclomatic complexity (McCabe’s metric) measures the number of linearly independent paths
        through a function’s control flow graph (CFG).
        The standard formula is:

            M = E - N + 2

        where:
            - E = number of edges in the CFG
            - N = number of nodes (basic blocks)
            - 2 accounts for the entry and exit nodes of a single connected graph
        """
        if self.function is None:
            return 0

        # number of basic blocks
        num_blocks = len(self.function.basic_blocks)
        # number of edges in the graph
        num_edges = sum(
            len(basic_block.outgoing_edges)
            for basic_block in self.function.basic_blocks
        )
        return num_edges - num_blocks + 2

    def extract_function_cfg(self):
        """Extract information about a function CFG and return it as a dictionary."""

        function = self.function
        function_data = {
            "function_address": self.function.start,
            "blocks": [],
            "measures": {
                "cyclomatic_complexity": self.extract_cyclomatic_complexity(),
            },
        }

        if self.function is None:
            return function_data

        # Get the map of the depth associated to every block
        depths = self.get_map_depth()

        # Get the map of the positions associated to every block
        id_maps = self.get_block_id_map()

        # Extract block data with graph structure information
        for block in function.basic_blocks:
            # dominators per every block translated
            dominators = sorted(self.extract_dominators(block, id_maps))

            # post dominators
            post_dominators = sorted(self.extract_post_dominators(block, id_maps))

            # Build block instructions string
            block_instructions = "\n".join(str(line) for line in block.disassembly_text)

            # Determine block type
            block_type = self.determine_block_type(block)

            # Extract successors directly from basic block
            successor_blocks = [edge.target.start for edge in block.outgoing_edges]
            # We ensure a canonical order and we sort the edges
            successor_blocks.sort()

            # Extract predecessors directly from basic block
            predecessor_blocks = [edge.source.start for edge in block.incoming_edges]
            # We ensure a canonical order and we sort the edges
            predecessor_blocks.sort()

            # Determine branch type from outgoing edges
            branch_type = self.determine_branch_type(block)

            instructions_count = len(block.disassembly_text)

            # Create block record
            block_json = {
                "function_address": self.function.start,
                "block_start_address": block.start,
                "block_end_address": block.end,
                "block_size": block.end - block.start,
                "instructions_count": instructions_count,
                "block_instructions_hash": calculate_sha256(block_instructions),
                "predecessor_blocks": predecessor_blocks,
                "successor_blocks": successor_blocks,
                "depth": depths[block.start],
                "position": id_maps[block.start],
                "branch_type": branch_type,
                "block_type": block_type,
                "flags": self.extract_block_flags(block),
                "dominators": dominators,
                "post_dominators": post_dominators,
            }
            function_data["blocks"].append(block_json)

        return function_data

    def extract_dominators(self, bb, id_maps):
        """Extract the dominators normalized"""
        dom_idx = [id_maps[d.start] for d in bb.dominators]
        return dom_idx

    def extract_post_dominators(self, bb, id_maps):
        """Extract the post-dominators normalized"""
        post_dom_idx = [id_maps[d.start] for d in bb.post_dominators]
        return post_dom_idx

    def determine_branch_type(self, block):
        """
        Determine the type of branch at the end of a basic block.
        This combines edge type information with instruction analysis.
        """
        # If no outgoing edges, it might be a return or terminal block
        if not block.outgoing_edges:
            # Check if the last instruction is a return
            for line in reversed(list(block.disassembly_text)):
                if line.tokens and any(
                    token.text.lower() in ["ret", "retn"] for token in line.tokens
                ):
                    return "RETURN"
            return "UNKNOWN"

        # Collect branch types from all outgoing edges
        branch_types = []
        for edge in block.outgoing_edges:
            edge_type = edge.type
            # Map edge type to our branch type enum
            if isinstance(edge_type, str):
                if edge_type == "IndirectCall":
                    branch_types.append("CALL")
                else:
                    branch_types.append("UNKNOWN")
            else:
                # Use our mapping for integer/enum values
                type_mapping = {
                    BranchType.UnconditionalBranch: "DIRECT",
                    BranchType.FalseBranch: "CONDITIONAL",
                    BranchType.TrueBranch: "CONDITIONAL",
                    BranchType.CallDestination: "CALL",
                    BranchType.FunctionReturn: "RETURN",
                    BranchType.SystemCall: "CALL",
                    BranchType.IndirectBranch: "INDIRECT",
                    BranchType.ExceptionBranch: "UNKNOWN",
                    BranchType.UnresolvedBranch: "UNKNOWN",
                    BranchType.UserDefinedBranch: "UNKNOWN",
                }
                branch_types.append(type_mapping.get(edge_type, "UNKNOWN"))

        # Determine overall branch type (prioritize CALL > RETURN > CONDITIONAL > DIRECT)
        if "CALL" in branch_types:
            return "CALL"
        elif "RETURN" in branch_types:
            return "RETURN"
        elif "CONDITIONAL" in branch_types:
            return "CONDITIONAL"
        elif "DIRECT" in branch_types:
            return "DIRECT"
        elif len(block.outgoing_edges) == 1:
            return "FALLTHROUGH"

        # If edge analysis was inconclusive, fall back to instruction analysis
        last_instr = None
        for line in reversed(list(block.disassembly_text)):
            if line.tokens:
                last_instr = line
                break

        if last_instr:
            mnemonic = None
            for token in last_instr.tokens:
                if token.type == InstructionTextTokenType.InstructionToken:
                    mnemonic = token.text.lower()
                    break

            if mnemonic:
                if mnemonic == "call":
                    return "CALL"
                elif mnemonic == "jmp":
                    return "DIRECT"
                elif mnemonic.startswith("j") and mnemonic != "jmp":
                    return "CONDITIONAL"
                elif mnemonic in ["ret", "retn"]:
                    return "RETURN"

        return "UNKNOWN"

    def get_map_depth(self):
        """
        Run a BFS on the basic blocks of the function to assign a depth to every block
        """

        depths = {}
        entry = self.function.get_basic_block_at(self.function.start)

        ### Simple BFS
        q = deque()
        q.append(entry)
        depths[entry.start] = 0

        while q:
            b = q.popleft()
            b_depth = depths[b.start]
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in depths:
                    depths[tgt.start] = b_depth + 1
                    q.append(tgt)

        return depths

    def get_block_id_map(self):
        """
        Assign a unique, sequential ID to each basic block of the function using a BFS starting from the entry block.
        """

        id_map = {}
        entry = self.function.get_basic_block_at(self.function.start)

        q = deque()
        q.append(entry)

        current_id = 0
        id_map[entry.start] = current_id

        while q:
            b = q.popleft()
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in id_map:
                    current_id += 1
                    id_map[tgt.start] = current_id
                    q.append(tgt)

        return id_map

    def extract_block_flags(self, block):
        """
        Get the flags for every basic block. Currently, we implemented these heuristics:
            - if a basic block is the entry node for a function
            - if a basic block is the exit block for a function
            - if a basic block is part of a natural loop
        """
        flags = []

        if block.start == self.function.start:
            flags.append(BlockFlags.EntryBlock.value)

        if any(edge.type == BranchType.FunctionReturn for edge in block.outgoing_edges):
            flags.append(BlockFlags.ExitBlock.value)

        # if this block is in its dominance frontier, then it's part of a natural loop
        if block in block.dominance_frontier:
            flags.append(BlockFlags.LoopBlock.value)

        return flags


class BlockFlags(Enum):
    # generally, the basic block identifying the entry point of the function
    EntryBlock = "EntryBlock"
    # any basic blocks that makes the control flow exiting from the current function
    ExitBlock = "ExitBlock"
    # any block is in a natural loop if it is in its own dominance frontier
    LoopBlock = "LoopBlock"


class BlockType(Enum):
    THUNK = "THUNK"
    DATA = "DATA"
    PADDING = "PADDING"
    CODE = "CODE"