Vasilis Efthymiou

91 papers A* 5A 1B 10Misc 1Journal 34Unranked 28
YearRankTypeTitle / Venue / Authors
2026 conf
EDBT/ICDT Workshops
Yingqi Zhao, Vasilis Efthymiou, Jyrki Nummenmaa, Kostas Stefanidis
2026 J jnl
CoRR
Panagiotis Koletsis, Vasilis Efthymiou, Maria Vakalopoulou, Nikos Komodakis, Anastasios Doulamis, Georgios Th. Papadopoulos
2026 B conf
EDBT
Emmanouil Limnaios, Markos Stergiopoulos, George T. Stamatiou, Efthymios Papageorgiou, Vasilis Efthymiou, Dimitrios Loupas, Dimitrios Tsourounis, Kostas Blekos, Aggelos Tsikas, Dimitris Plexousakis, Kostas Magoutis, Yannis Tzitzikas, Haridimos Kondylakis
2026 ed.
IJCKG
Hideaki Takeda, Yannis Tzitzikas, Giorgos Flouris, Shizhu He, Dimitris Plexousakis, Sébastien Ferré, Ran Yu, Vasilis Efthymiou, Eleni Ilkou, Ernesto Jiménez-Ruiz, Xin Wang
2026 B conf
EDBT
Sophia Sideri, Georgia Troullinou, Elisjana Ymeralli, Vasilis Efthymiou, Dimitris Plexousakis, Haridimos Kondylakis
2025 J jnl
IEEE Access
Konstantinos Nikoletos, Vasilis Efthymiou, George Papadakis, Kostas Stefanidis
2025 J jnl
CoRR
Konstantinos Nikoletos, Vasilis Efthymiou, George Papadakis, Kostas Stefanidis
2025 J jnl
Proc. VLDB Endow.
Luca Zecchini, Vasilis Efthymiou, Felix Naumann, Giovanni Simonini
2025 J jnl
CoRR
Spyridon Evangelatos, Eleni Veroni, Vasilis Efthymiou, Christos D. Nikolopoulos, Georgios Th. Papadopoulos, Panagiotis G. Sarigiannidis
2025 J jnl
IEEE Access
Tiago Brasileiro Araújo, Vasilis Efthymiou, Kostas Stefanidis
2025 conf
IJCKG
Sophia Sideri, Iosif Oikonomakis, Petros Tsirmakos, Giorgos Flouris, Vasilis Efthymiou, Emmanouil Eleftherios Rompogiannakis, Elias Kyritsis, Ioanna Leonidaki, Andreas Zezas
2025 J jnl
ACM Trans. Web
Spyridon Evangelatos, Eleni Veroni, Vasilis Efthymiou, Christos D. Nikolopoulos
2025 J jnl
CoRR
Sophia Sideri, Georgia Troullinou, Elisjana Ymeralli, Vasilis Efthymiou, Dimitris Plexousakis, Haridimos Kondylakis
2025 conf
IJCKG
Sophia Sideri, Vasilis Efthymiou, Dimitris Plexousakis, Haridimos Kondylakis
2025 ed.
SemTab@ISWC
Oktie Hassanzadeh, Nora Abdelmageed, Marco Cremaschi, Vincenzo Cutrona, Fabio D'Adda, Vasilis Efthymiou, Benno Kruit, Elita A. Lobo, Nandana Mihindukulasooriya, Nhan H. Pham
2025 J jnl
Proc. VLDB Endow.
Haridimos Kondylakis, Stefania Dumbrava, Matteo Lissandrini, Nikolay Yakovets, Angela Bonifati, Vasilis Efthymiou, George Fletcher, Dimitris Plexousakis, Riccardo Tommasini, Georgia Troullinou, Elisjana Ymeralli
2025 J jnl
Proc. VLDB Endow.
Luca Zecchini, Ziawasch Abedjan, Vasilis Efthymiou, Giovanni Simonini
2025 conf
ADBIS (Short Papers)
Yingqi Zhao, Vasilis Efthymiou, Jyrki Nummenmaa, Kostas Stefanidis
2025 J jnl
CoRR
Panagiotis Koletsis, Christos Panagiotopoulos, Georgios Th. Papadopoulos, Vasilis Efthymiou
2025 J jnl
Inf. Syst.
Tiago Brasileiro Araújo, Vasilis Efthymiou, Vassilis Christophides, Evaggelia Pitoura, Kostas Stefanidis
2024 conf
VLDB Workshops
Vasilis Efthymiou, Sainyam Galhotra, Oktie Hassanzadeh, Chuan Lei, Kavitha Srinivas
2024 B conf
IEEE Big Data
Panagiotis Koletsis, Panagiotis-Konstantinos Gemos, Christos Chronis, Iraklis Varlamis, Vasilis Efthymiou, Georgios Th. Papadopoulos
2024 J jnl
CoRR
Panagiotis Koletsis, Panagiotis-Konstantinos Gemos, Christos Chronis, Iraklis Varlamis, Vasilis Efthymiou, Georgios Th. Papadopoulos
2024 J jnl
J. Web Semant.
Alexandros Vassiliades, Theodore Patkos, Vasilis Efthymiou, Antonis Bikakis, Nick Bassiliades, Dimitris Plexousakis
2024 J jnl
CoRR
Nikolaos Fanourakis, Fatia Lekbour, Vasilis Efthymiou, Guillaume Renton, Vassilis Christophides
2024 conf
CAiSE Workshops
Haridimos Kondylakis, Vasilis Efthymiou, Georgia Troullinou, Elisjana Ymeralli, Dimitris Plexousakis
2023 J jnl
VLDB J.
George Papadakis, Vasilis Efthymiou, Emmanouil Thanos, Oktie Hassanzadeh, Peter Christen
2023 conf
ESWC (Satellite Events)
Katerina Papantoniou, Vasilis Efthymiou, Dimitris Plexousakis
2023 conf
VLDB Workshops
Eva Chrysostomaki, Maria Stratigi, Vasilis Efthymiou, Kostas Stefanidis, Dimitris Plexousakis
2023 conf
ISWC (Posters/Demos/Industry)
Nikolaos Fanourakis, Christos Kontousias, Vasilis Efthymiou, Vassilis Christophides, Dimitris Plexousakis
2023 J jnl
Proc. VLDB Endow.
Georgia Koutrika, Jun Yang, Manos Athanassoulis, Kostas Stefanidis, Ju Fan, Abdul Quamar, Yuanyan Tian, Alekh Jindal, Carsten Binnig, Jennie Rogers, Senjuti Basu Roy, Steven Euijong Whang, Matthias Boehm, Aaron J. Elmore, Vasilis Efthymiou, Xiao Hu, Xiaofang Zhou, Alan D. Fekete
2023 J jnl
VLDB J.
Chuan Lei, Abdul Quamar, Vasilis Efthymiou, Fatma Özcan, Rana Alotaibi
2023 ed.
VLDB Workshops
Rajesh Bordawekar, Cinzia Cappiello, Vasilis Efthymiou, Lisa Ehrlinger, Vijay Gadepally, Sainyam Galhotra, Sandra Geisler, Sven Groppe, Le Gruenwald, Alon Y. Halevy, Hazar Harmouch, Oktie Hassanzadeh, Ihab F. Ilyas, Ernesto Jiménez-Ruiz, Sanjay Krishnan, Tirthankar Lahiri, Guoliang Li, Jiaheng Lu, Wolfgang Mauerer, Umar Farooq Minhas, Felix Naumann, M. Tamer Özsu, El Kindi Rezig, Kavitha Srinivas, Michael Stonebraker, Satyanarayana R. Valluri, Maria-Esther Vidal, Haixun Wang, Jiannan Wang, Yingjun Wu, Xun Xue, Mohamed Zaït, Kai Zeng
2023 J jnl
Data Min. Knowl. Discov.
Nikolaos Fanourakis, Vasilis Efthymiou, Dimitris Kotzinos, Vassilis Christophides
2023 conf
VLDB Workshops
Vasilis Efthymiou, Oktie Hassanzadeh, Ernesto Jiménez-Ruiz, Kavitha Srinivas
2023 ed.
SemTab@ISWC
Vasilis Efthymiou, Ernesto Jiménez-Ruiz, Jiaoyan Chen, Vincenzo Cutrona, Oktie Hassanzadeh, Juan Sequeda, Kavitha Srinivas, Nora Abdelmageed, Madelon Hulsebos
2023 ed.
SemTab@ISWC
Vasilis Efthymiou, Ernesto Jiménez-Ruiz, Jiaoyan Chen, Vincenzo Cutrona, Oktie Hassanzadeh, Juan Sequeda, Kavitha Srinivas, Nora Abdelmageed, Madelon Hulsebos, Aamod Khatiwada, Keti Korini, Benno Kruit
2023 ed.
PhD@VLDB
Vasilis Efthymiou, Xiao Hu
2023 conf
SemTab@ISWC
Oktie Hassanzadeh, Nora Abdelmageed, Vasilis Efthymiou, Jiaoyan Chen, Vincenzo Cutrona, Madelon Hulsebos, Ernesto Jiménez-Ruiz, Aamod Khatiwada, Keti Korini, Benno Kruit, Juan Sequeda, Kavitha Srinivas
2023 B conf
IEEE Big Data
Vasilis Efthymiou, Ekaterini Ioannou, Manos Karvounis, Manolis Koubarakis, Jakub Maciejewski, Konstantinos Nikoletos, George Papadakis, Dimitrios Skoutas, Yannis Velegrakis, Alexandros Zeakis
2023 B conf
ESWC
Nikolaos Fanourakis, Vasilis Efthymiou, Vassilis Christophides, Dimitris Kotzinos, Evaggelia Pitoura, Kostas Stefanidis
2023 ed.
ESWC (Satellite Events)
Catia Pesquita, Hala Skaf-Molli, Vasilis Efthymiou, Sabrina Kirrane, Axel Ngonga, Diego Collarana, Renato Cerqueira, Mehwish Alam, Cássia Trojahn, Sven Hertling
2022 B conf
EDBT
George Papadakis, Vasilis Efthymiou, Emmanouil Thanos, Oktie Hassanzadeh
2022 conf
DL4KG@ISWC
Vasilis Efthymiou
2022 J jnl
CoRR
Nikolaos Fanourakis, Vasilis Efthymiou, Dimitris Kotzinos, Vassilis Christophides
2022 J jnl
CoRR
Abdul Quamar, Vasilis Efthymiou, Chuan Lei, Fatma Özcan
2022 J jnl
Found. Trends Databases
Abdul Quamar, Vasilis Efthymiou, Chuan Lei, Fatma Özcan
2022 ed.
SemTab@ISWC
Ernesto Jiménez-Ruiz, Vasilis Efthymiou, Jiaoyan Chen, Vincenzo Cutrona, Oktie Hassanzadeh, Juan Sequeda, Kavitha Srinivas, Nora Abdelmageed, Madelon Hulsebos, Daniela Oliveira, Catia Pesquita
2022 conf
SemTab@ISWC
Nora Abdelmageed, Jiaoyan Chen, Vincenzo Cutrona, Vasilis Efthymiou, Oktie Hassanzadeh, Madelon Hulsebos, Ernesto Jiménez-Ruiz, Juan Sequeda, Kavitha Srinivas
2021 J jnl
ACM Comput. Surv.
Vassilis Christophides, Vasilis Efthymiou, Themis Palpanas, George Papadakis, Kostas Stefanidis
2021 J jnl
CoRR
Venkata Vamsikrishna Meduri, Abdul Quamar, Chuan Lei, Vasilis Efthymiou, Fatma Ozcan
2021 J jnl
CoRR
George Papadakis, Vasilis Efthymiou, Emanouil Thanos, Oktie Hassanzadeh
2021 conf
ISWC (Posters/Demos/Industry)
Katerina Papantoniou, Vasilis Efthymiou, Giorgos Flouris
2021 A conf
CIKM
Vasilis Efthymiou, Kostas Stefanidis, Evaggelia Pitoura, Vassilis Christophides
2021 A* conf
KDD
Junheng Hao, Chuan Lei, Vasilis Efthymiou, Abdul Quamar, Fatma Özcan, Yizhou Sun, Wei Wang
2021 conf
SIGMOD Conference
Alina Vretinaris, Chuan Lei, Vasilis Efthymiou, Xiao Qin, Fatma Özcan
2021 J jnl
CoRR
Alina Vretinaris, Chuan Lei, Vasilis Efthymiou, Xiao Qin, Fatma Özcan
2021 Misc conf
SEMANTiCS
Alexandros Vassiliades, Theodore Patkos, Vasilis Efthymiou, Antonis Bikakis, Nick Bassiliades, Dimitris Plexousakis
2021 A* conf
AAAI
Shqiponja Ahmetaj, Vasilis Efthymiou, Ronald Fagin, Phokion G. Kolaitis, Chuan Lei, Fatma Özcan, Lucian Popa
2021 A* conf
ICDE
Rana Alotaibi, Chuan Lei, Abdul Quamar, Vasilis Efthymiou, Fatma Özcan
2021 conf
SemTab@ISWC
Vincenzo Cutrona, Jiaoyan Chen, Vasilis Efthymiou, Oktie Hassanzadeh, Ernesto Jiménez-Ruiz, Juan Sequeda, Kavitha Srinivas, Nora Abdelmageed, Madelon Hulsebos, Daniela Oliveira, Catia Pesquita
2021 conf
DEEM@SIGMOD
Fatma Özcan, Chuan Lei, Abdul Quamar, Vasilis Efthymiou
2020 J jnl
Proc. VLDB Endow.
Jaydeep Sen, Chuan Lei, Abdul Quamar, Fatma Özcan, Vasilis Efthymiou, Ayushi Dalmia, Greg Stager, Ashish R. Mittal, Diptikalyan Saha, Karthik Sankaranarayanan
2020 conf
SIGMOD Conference
Abdul Quamar, Chuan Lei, Dorian Miller, Fatma Ozcan, Jeffrey T. Kreulen, Robert J. Moore, Vasilis Efthymiou
2020 J jnl
CoRR
Vasilis Efthymiou, Kostas Stefanidis, Vassilis Christophides
2020 J jnl
IEEE Trans. Big Data
Vasilis Efthymiou, Kostas Stefanidis, Vassilis Christophides
2020 conf
SCC
Xue Han, Lianxue Hu, Jaydeep Sen, Yabin Dang, Buyu Gao, Vatche Isahagian, Chuan Lei, Vasilis Efthymiou, Fatma Özcan, Abdul Quamar, Ziming Huang, Vinod Muthusamy
2020 B conf
EDBT
Chuan Lei, Vasilis Efthymiou, Rebecca Geis, Fatma Ozcan
2020 ed.
SemTab@ISWC
Ernesto Jiménez-Ruiz, Oktie Hassanzadeh, Vasilis Efthymiou, Jiaoyan Chen, Kavitha Srinivas, Vincenzo Cutrona
2020 ed.
SemTab@ISWC
Ernesto Jiménez-Ruiz, Oktie Hassanzadeh, Kavitha Srinivas, Vasilis Efthymiou, Jiaoyan Chen
2020 J jnl
CoRR
Chuan Lei, Rana Alotaibi, Abdul Quamar, Vasilis Efthymiou, Fatma Özcan
2020 conf
SemTab@ISWC
Ernesto Jiménez-Ruiz, Oktie Hassanzadeh, Vasilis Efthymiou, Jiaoyan Chen, Kavitha Srinivas, Vincenzo Cutrona
2020 B conf
ESWC
Ernesto Jiménez-Ruiz, Oktie Hassanzadeh, Vasilis Efthymiou, Jiaoyan Chen, Kavitha Srinivas
2020 conf
SIGMOD Conference
Fatma Ozcan, Abdul Quamar, Jaydeep Sen, Chuan Lei, Vasilis Efthymiou
2019 J jnl
CoRR
Vassilis Christophides, Vasilis Efthymiou, Themis Palpanas, George Papadakis, Kostas Stefanidis
2019 B conf
EDBT
Vasilis Efthymiou, George Papadakis, Kostas Stefanidis, Vassilis Christophides
2019 J jnl
CoRR
Vasilis Efthymiou, George Papadakis, Kostas Stefanidis, Vassilis Christophides
2018 A* conf
ICDE
Vasilis Efthymiou, George Papadakis, Kostas Stefanidis, Vassilis Christophides
2017
Vasilis Efthymiou
2017 conf
ISWC (1)
Vasilis Efthymiou, Oktie Hassanzadeh, Mariano Rodriguez-Muro, Vassilis Christophides
2017 J jnl
Inf. Syst.
Vasilis Efthymiou, George Papadakis, George Papastefanatos, Kostas Stefanidis, Themis Palpanas
2017 A* conf
ICDE
Kostas Stefanidis, Vassilis Christophides, Vasilis Efthymiou
2016 conf
OM@ISWC
Vasilis Efthymiou, Oktie Hassanzadeh, Mohammad Sadoghi, Mariano Rodriguez-Muro
2016 B conf
EDBT
Vasilis Efthymiou, Kostas Stefanidis, Vassilis Christophides
2016 J jnl
J. Ambient Intell. Smart Environ.
Patrice Caire, Assaad Moawad, Vasilis Efthymiou, Antonis Bikakis, Yves Le Traon
2015 conf
IEEE BigData
Vasilis Efthymiou, Kostas Stefanidis, Vassilis Christophides
2015 book
Vassilis Christophides, Vasilis Efthymiou, Kostas Stefanidis
2015 conf
IEEE BigData
Vasilis Efthymiou, George Papadakis, George Papastefanatos, Kostas Stefanidis, Themis Palpanas
2015 conf
IEEE BigData
Vasilis Efthymiou, Kostas Stefanidis, Eirini Ntoutsi
2014 conf
WWW (Companion Volume)
Kostas Stefanidis, Vasilis Efthymiou, Melanie Herschel, Vassilis Christophides
2012 conf
ISAmI
Maria Koutraki, Vasilis Efthymiou, Grigoris Antoniou
tests/unit/test_decompile_decompiler.py
← Index tests/unit/test_decompile_decompiler.py python
"""Unit tests (mocked BN) for bninja/decompiler.py — BinaryNinjaDecompiler."""
import sys
import json
import time
import pytest
from unittest.mock import MagicMock, patch, mock_open

from tests.unit.conftest_binja_stubs import (
    install_binja_stubs,
    MockFunction,
    MockBasicBlock,
    MockDisassemblyLine,
    MockToken,
    MockSymbol,
    MockBinaryView,
    MockEdge,
    SymbolType,
    InstructionTextTokenType,
    BranchType,
)

install_binja_stubs()

from redb.extractors.decompiler.bninja.decompiler import (
    BinaryNinjaDecompiler,
    is_lib_or_thunk,
)
from redb.extractors.decompiler.bninja.function_type import FunctionType


# ============================================================================
# 10a. BinaryNinjaDecompiler
# ============================================================================


class TestBinaryNinjaDecompilerLogError:
    def _make_decompiler(self):
        with patch.object(BinaryNinjaDecompiler, "__init__", lambda self, *a, **kw: None):
            d = BinaryNinjaDecompiler.__new__(BinaryNinjaDecompiler)
            d.log = MagicMock()
            d.errors = []
            d.filepath = "/fake/binary"
            d.bv = None
            d.analysis_results = None
            d.exporters = []
            d.index_prefix = None
            d.filetype = None
            d.goresym = None
            d.BNINJA_TIMEOUT = 60
            return d

    def test_log_error_appends(self):
        d = self._make_decompiler()
        d.log_error("test error", "func1", 0x1000, Exception("boom"), "extract")
        assert len(d.errors) == 1

    def test_log_error_schema(self):
        d = self._make_decompiler()
        d.log_error("test error", "func1", 0x1000, Exception("boom"), "extract")
        error = d.errors[0]
        expected_keys = [
            "function_name",
            "function_address",
            "error_location",
            "error_message",
            "error_details",
            "error_type",
            "timestamp",
        ]
        for key in expected_keys:
            assert key in error, f"Missing key: {key}"


class TestBinaryNinjaDecompilerIsTooFewBlocks:
    def _make_decompiler(self):
        with patch.object(BinaryNinjaDecompiler, "__init__", lambda self, *a, **kw: None):
            d = BinaryNinjaDecompiler.__new__(BinaryNinjaDecompiler)
            d.log = MagicMock()
            d.errors = []
            d.MIN_FUNCTION_SIZE = 10
            return d

    def test_is_too_few_blocks_none(self):
        d = self._make_decompiler()
        func = MagicMock()
        func.basic_blocks = None
        assert d.is_too_few_blocks(func) is False

    def test_is_too_few_blocks_empty(self):
        # Empty basic_blocks now returns True because Binja creates function
        # stubs with empty blocks before analysis completes — we no longer
        # skip these so they get filtered downstream instead.
        d = self._make_decompiler()
        func = MagicMock()
        func.basic_blocks = []
        assert d.is_too_few_blocks(func) is True

    def test_is_too_few_blocks_small_single(self):
        d = self._make_decompiler()
        block = MagicMock()
        block.disassembly_text = [MagicMock() for _ in range(5)]  # < 10
        func = MagicMock()
        func.basic_blocks = [block]
        assert d.is_too_few_blocks(func) is False

    def test_is_too_few_blocks_large_single(self):
        d = self._make_decompiler()
        block = MagicMock()
        block.disassembly_text = [MagicMock() for _ in range(15)]  # >= 10
        func = MagicMock()
        func.basic_blocks = [block]
        assert d.is_too_few_blocks(func) is True

    def test_is_too_few_blocks_multiple(self):
        d = self._make_decompiler()
        func = MagicMock()
        func.basic_blocks = [MagicMock(), MagicMock()]
        assert d.is_too_few_blocks(func) is True


class TestIsLibOrThunk:
    def test_is_lib_or_thunk_user(self):
        func = MagicMock()
        func.symbol.type = SymbolType.FunctionSymbol
        func.is_thunk = False
        assert is_lib_or_thunk(func) is True  # NOT filtered

    def test_is_lib_or_thunk_thunk(self):
        func = MagicMock()
        func.symbol.type = SymbolType.FunctionSymbol
        func.is_thunk = True
        assert is_lib_or_thunk(func) is False  # Filtered out

    def test_is_lib_or_thunk_external(self):
        func = MagicMock()
        func.symbol.type = SymbolType.ImportedFunctionSymbol
        func.is_thunk = False
        assert is_lib_or_thunk(func) is False  # Filtered out


class TestBinaryNinjaDecompilerExtract:
    def _make_decompiler(self):
        with patch.object(BinaryNinjaDecompiler, "__init__", lambda self, *a, **kw: None):
            d = BinaryNinjaDecompiler.__new__(BinaryNinjaDecompiler)
            d.log = MagicMock()
            d.errors = []
            d.filepath = "/fake/binary"
            d.bv = MagicMock()
            d.analysis_results = None
            d.exporters = []
            d.index_prefix = None
            d.filetype = None
            d.goresym = None
            d.BNINJA_TIMEOUT = 60
            d.arch = MagicMock()
            return d

    def test_extract_success(self):
        d = self._make_decompiler()
        mock_results = {
            "decompiled": [{"test": True}],
            "disassembled": [],
            "cfg": [],
            "llil": [],
            "errors": [],
            "strings": [],
            "mlil": [],
        }
        with patch.object(d, "analyze_binary", return_value=mock_results):
            result = d.extract()
            assert result is True
            assert d.analysis_results == mock_results

    def test_extract_failure(self):
        d = self._make_decompiler()
        with patch.object(d, "analyze_binary", return_value=None):
            result = d.extract()
            assert result is False

    def test_tag(self):
        d = self._make_decompiler()
        assert d.tag() == "DECOMPILED"


class TestBinaryNinjaDecompilerAnalyzeBinary:
    def _make_decompiler(self):
        with patch.object(BinaryNinjaDecompiler, "__init__", lambda self, *a, **kw: None):
            d = BinaryNinjaDecompiler.__new__(BinaryNinjaDecompiler)
            d.log = MagicMock()
            d.errors = []
            d.filepath = "/fake/binary"
            d.analysis_results = None
            d.exporters = []
            d.index_prefix = None
            d.filetype = None
            d.goresym = None
            d.BNINJA_TIMEOUT = 60
            d.arch = MagicMock()
            d.MIN_FUNCTION_SIZE = 10
            return d

    def test_analyze_binary_links_hlil_disasm(self):
        """Bi-directional hash linkage between decompiled and disassembled."""
        d = self._make_decompiler()
        d.bv = MagicMock()
        d.bv.functions = []
        # Mock methods to return controlled data
        with patch.object(d, "extract_hlil") as mock_hlil, \
             patch.object(d, "extract_disasm") as mock_disasm, \
             patch.object(d, "extract_cfg", return_value=None), \
             patch.object(d, "extract_lowlevel", return_value=None):

            mock_hlil.return_value = {
                "decompiled_function_hash": "HLIL_HASH",
                "decompiled_function_name": "test",
                "decompiled_function": "code",
            }
            mock_disasm.return_value = {
                "disassembled_function_hash": "DISASM_HASH",
                "disassembled_function_no_addresses": "asm",
            }

            # Manually feed one function
            mock_func = MagicMock()
            mock_func.symbol.type = SymbolType.FunctionSymbol
            mock_func.is_thunk = False
            mock_func.basic_blocks = [MagicMock(), MagicMock()]
            d.bv.functions = [mock_func]

            results = d.analyze_binary()
            if results and results["decompiled"]:
                hlil_r = results["decompiled"][0]
                disasm_r = results["disassembled"][0]
                assert hlil_r["disassembled_function_hash"] == "DISASM_HASH"
                assert disasm_r["decompiled_function_hash"] == "HLIL_HASH"

    def test_analyze_binary_links_llil_disasm(self):
        """Bi-directional linkage between LLIL and disassembly."""
        d = self._make_decompiler()
        d.bv = MagicMock()

        with patch.object(d, "extract_hlil", return_value=None), \
             patch.object(d, "extract_disasm") as mock_disasm, \
             patch.object(d, "extract_cfg", return_value=None), \
             patch.object(d, "extract_lowlevel") as mock_llil:

            mock_disasm.return_value = {
                "disassembled_function_hash": "DISASM_HASH",
                "disassembled_function_no_addresses": "asm",
            }
            mock_llil.return_value = {
                "sha256_llil": "LLIL_HASH",
                "tlsh_llil": "tlsh_val",
            }

            mock_func = MagicMock()
            mock_func.symbol.type = SymbolType.FunctionSymbol
            mock_func.is_thunk = False
            mock_func.basic_blocks = [MagicMock(), MagicMock()]
            d.bv.functions = [mock_func]

            results = d.analyze_binary()
            if results and results["llil"]:
                llil_r = results["llil"][0]
                assert llil_r["disassembled_function_hash"] == "DISASM_HASH"

    def test_analyze_binary_links_cfg_disasm(self):
        """CFG gets disassembled_function_hash."""
        d = self._make_decompiler()
        d.bv = MagicMock()

        with patch.object(d, "extract_hlil", return_value=None), \
             patch.object(d, "extract_disasm") as mock_disasm, \
             patch.object(d, "extract_cfg") as mock_cfg, \
             patch.object(d, "extract_lowlevel", return_value=None):

            mock_disasm.return_value = {
                "disassembled_function_hash": "DISASM_HASH",
                "disassembled_function_no_addresses": "asm",
            }
            mock_cfg.return_value = {
                "function_address": 0x1000,
                "cyclomatic_complexity": 3,
            }

            mock_func = MagicMock()
            mock_func.symbol.type = SymbolType.FunctionSymbol
            mock_func.is_thunk = False
            mock_func.basic_blocks = [MagicMock(), MagicMock()]
            d.bv.functions = [mock_func]

            results = d.analyze_binary()
            if results and results["cfg"]:
                cfg_r = results["cfg"][0]
                assert cfg_r["disassembled_function_hash"] == "DISASM_HASH"

    def test_analyze_binary_sets_cyclomatic(self):
        """cyclomatic_complexity set on disasm from CFG."""
        d = self._make_decompiler()
        d.bv = MagicMock()

        with patch.object(d, "extract_hlil", return_value=None), \
             patch.object(d, "extract_disasm") as mock_disasm, \
             patch.object(d, "extract_cfg") as mock_cfg, \
             patch.object(d, "extract_lowlevel", return_value=None):

            mock_disasm.return_value = {
                "disassembled_function_hash": "HASH",
                "disassembled_function_no_addresses": "asm",
            }
            mock_cfg.return_value = {
                "function_address": 0x1000,
                "cyclomatic_complexity": 7,
            }

            mock_func = MagicMock()
            mock_func.symbol.type = SymbolType.FunctionSymbol
            mock_func.is_thunk = False
            mock_func.basic_blocks = [MagicMock(), MagicMock()]
            d.bv.functions = [mock_func]

            results = d.analyze_binary()
            if results and results["disassembled"]:
                disasm_r = results["disassembled"][0]
                assert disasm_r.get("cyclomatic_complexity") == 7


class TestApplyGoReSym:
    def _make_decompiler(self):
        with patch.object(BinaryNinjaDecompiler, "__init__", lambda self, *a, **kw: None):
            d = BinaryNinjaDecompiler.__new__(BinaryNinjaDecompiler)
            d.log = MagicMock()
            d.errors = []
            d.bv = MagicMock()
            return d

    def test_apply_goresym_user_functions(self):
        d = self._make_decompiler()
        d.goresym = "/tmp/goresym.json"
        data = {
            "UserFunctions": [{"Start": 0x1000, "FullName": "main.main"}],
        }
        with patch("builtins.open", mock_open(read_data=json.dumps(data))):
            d._BinaryNinjaDecompiler__apply_goresym()
            d.bv.define_user_symbol.assert_called()

    def test_apply_goresym_std_functions(self):
        d = self._make_decompiler()
        d.goresym = "/tmp/goresym.json"
        data = {
            "StdFunctions": [{"Start": 0x2000, "FullName": "runtime.main"}],
        }
        with patch("builtins.open", mock_open(read_data=json.dumps(data))):
            d._BinaryNinjaDecompiler__apply_goresym()
            d.bv.define_user_symbol.assert_called()

    def test_apply_goresym_invalid_json(self):
        d = self._make_decompiler()
        d.goresym = "/tmp/goresym.json"
        with patch("builtins.open", mock_open(read_data="not json {")):
            d._BinaryNinjaDecompiler__apply_goresym()
            # Should log error but not crash
            d.log.log_error if hasattr(d.log, 'log_error') else None
            # Just verify no exception raised