diff options
| author | kat <kat@vector35.com> | 2024-10-30 08:39:09 -0400 |
|---|---|---|
| committer | kat <kat@vector35.com> | 2024-11-05 09:03:12 -0500 |
| commit | f4a4b17b9e30cf603eb614e153d68226a3b24520 (patch) | |
| tree | e33d18742c1a9e9b47af04df24bf88248c17f06a /view/sharedcache | |
| parent | fd8eb478a7a3bbc848da37bd33e62c2d8cf26b99 (diff) | |
[SharedCache] Implement LoadedImage API, Fix serialized image names, more robust system for out-of-date databases
Diffstat (limited to 'view/sharedcache')
| -rw-r--r-- | view/sharedcache/CMakeLists.txt | 42 | ||||
| -rw-r--r-- | view/sharedcache/api/CMakeLists.txt | 32 | ||||
| -rw-r--r-- | view/sharedcache/api/python/_sharedcachecore.py | 17 | ||||
| -rw-r--r-- | view/sharedcache/api/python/sharedcache.py | 45 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcachecore.h | 1 | ||||
| -rw-r--r-- | view/sharedcache/core/CMakeLists.txt | 41 | ||||
| -rw-r--r-- | view/sharedcache/core/DSCView.cpp | 15 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 22 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.h | 26 | ||||
| -rw-r--r-- | view/sharedcache/ui/CMakeLists.txt | 31 | ||||
| -rw-r--r-- | view/sharedcache/ui/dsctriage.cpp | 6 | ||||
| -rw-r--r-- | view/sharedcache/workflow/CMakeLists.txt | 30 |
12 files changed, 217 insertions, 91 deletions
diff --git a/view/sharedcache/CMakeLists.txt b/view/sharedcache/CMakeLists.txt index 2d073204..79ec65b0 100644 --- a/view/sharedcache/CMakeLists.txt +++ b/view/sharedcache/CMakeLists.txt @@ -30,6 +30,7 @@ endif() set(HARD_FAIL_MODE OFF CACHE BOOL "Enable hard fail mode") set(SLIDEINFO_DEBUG_TAGS OFF CACHE BOOL "Enable debug tags in slideinfo") set(VIEW_NAME "DSCViewAlpha" CACHE STRING "Name of the view") +set(METADATA_VERSION 1 CACHE STRING "Version of the metadata") add_subdirectory(core) add_subdirectory(api) @@ -62,27 +63,46 @@ target_include_directories(sharedcache PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMA target_link_libraries(sharedcache PUBLIC sharedcacheapi binaryninjaapi sharedcachecore sharedcacheworkflow) + +set(COMPILE_DEFS "") + if (HARD_FAIL_MODE) - target_compile_definitions(sharedcache PRIVATE ABORT_FAILURES) + set(COMPILE_DEFS "${COMPILE_DEFS} ABORT_FAILURES;") +endif() + +if (BN_REF_COUNT_DEBUG) + set(COMPILE_DEFS "${COMPILE_DEFS} BN_REF_COUNT_DEBUG;") endif() if (SLIDEINFO_DEBUG_TAGS) - target_compile_definitions(sharedcache PRIVATE SLIDEINFO_DEBUG_TAGS) + set(COMPILE_DEFS "${COMPILE_DEFS} SLIDEINFO_DEBUG_TAGS;") +endif() + +if (METADATA_VERSION) + set(COMPILE_DEFS "${COMPILE_DEFS} METADATA_VERSION=${METADATA_VERSION};") +else() + message(FATAL_ERROR "No metadata version provided. Fatal.") +endif() + +if (VIEW_NAME) + set(COMPILE_DEFS "${COMPILE_DEFS} VIEW_NAME=\"${VIEW_NAME}\";") +else() + message(FATAL_ERROR "No view name provided. Fatal.") endif() -target_compile_definitions(sharedcache PRIVATE VIEW_NAME="${VIEW_NAME}") +target_compile_definitions(sharedcache PRIVATE ${COMPILE_DEFS}) if(NOT HEADLESS) add_subdirectory(ui) endif() message(" -▓█████▄ ██████ ▄████▄ -▒██▀ ██▌ ▒██ ▒ ▒██▀ ▀█ Shared Cache Plugin -░██ █▌ ░ ▓██▄ ▒▓█ ▄ -░▓█▄ █▌ ▒ ██▒ ▒▓▓▄ ▄██▒ CMake Prefix Path: ${CMAKE_PREFIX_PATH} -░▒████▓ ▒██████▒▒▒ ▓███▀ ░ Qt Version: ${QT_VERSION} - ▒▒▓ ▒ ▒ ▒▓▒ ▒ ░░ ░▒ ▒ ░ Crash on Failure: ${HARD_FAIL_MODE} - ░ ▒ ▒ ░ ░▒ ░ ░ ░ ▒ Slideinfo Debug Tags: ${SLIDEINFO_DEBUG_TAGS} - ░ ░ ░ ░ ░ ░ ░ REFCOUNT_DEBUG: ${BN_REF_COUNT_DEBUG} +▓█████▄ ██████ ▄████▄ Shared Cache Plugin +▒██▀ ██▌ ▒██ ▒ ▒██▀ ▀█ +░██ █▌ ░ ▓██▄ ▒▓█ ▄ Metadata Version: ${METADATA_VERSION} +░▓█▄ █▌ ▒ ██▒ ▒▓▓▄ ▄██▒ CMake Prefix Path: ${CMAKE_PREFIX_PATH} +░▒████▓ ▒██████▒▒▒ ▓███▀ ░ Qt Version: ${QT_VERSION} + ▒▒▓ ▒ ▒ ▒▓▒ ▒ ░░ ░▒ ▒ ░ Crash on Failure: ${HARD_FAIL_MODE} + ░ ▒ ▒ ░ ░▒ ░ ░ ░ ▒ Slideinfo Debug Tags: ${SLIDEINFO_DEBUG_TAGS} + ░ ░ ░ ░ ░ ░ ░ REFCOUNT_DEBUG: ${BN_REF_COUNT_DEBUG} ")
\ No newline at end of file diff --git a/view/sharedcache/api/CMakeLists.txt b/view/sharedcache/api/CMakeLists.txt index 1766352d..c14674a7 100644 --- a/view/sharedcache/api/CMakeLists.txt +++ b/view/sharedcache/api/CMakeLists.txt @@ -4,16 +4,36 @@ project(sharedcacheapi) file(GLOB BN_MACHO_API_SOURCES *.cpp *.h) add_library(sharedcacheapi OBJECT ${BN_MACHO_API_SOURCES}) + +set(COMPILE_DEFS "") + +if (HARD_FAIL_MODE) + set(COMPILE_DEFS "${COMPILE_DEFS} ABORT_FAILURES;") +endif() + +if (BN_REF_COUNT_DEBUG) + set(COMPILE_DEFS "${COMPILE_DEFS} BN_REF_COUNT_DEBUG;") +endif() + +if (SLIDEINFO_DEBUG_TAGS) + set(COMPILE_DEFS "${COMPILE_DEFS} SLIDEINFO_DEBUG_TAGS;") +endif() + +if (METADATA_VERSION) + set(COMPILE_DEFS "${COMPILE_DEFS} METADATA_VERSION=${METADATA_VERSION};") +else() + message(FATAL_ERROR "No metadata version provided. Fatal.") +endif() + if (VIEW_NAME) - if (BN_REF_COUNT_DEBUG) - target_compile_definitions(sharedcacheapi PRIVATE VIEW_NAME="${VIEW_NAME}" BN_REF_COUNT_DEBUG) - else() - target_compile_definitions(sharedcacheapi PRIVATE VIEW_NAME="${VIEW_NAME}") - endif() + set(COMPILE_DEFS "${COMPILE_DEFS} VIEW_NAME=\"${VIEW_NAME}\";") else() - error("VIEW_NAME must be defined") + message(FATAL_ERROR "No view name provided. Fatal.") endif() +target_compile_definitions(sharedcacheapi PRIVATE ${COMPILE_DEFS}) + + function(get_recursive_include_dirs target result) # Initialize an empty list to store include directories set(include_dirs "") diff --git a/view/sharedcache/api/python/_sharedcachecore.py b/view/sharedcache/api/python/_sharedcachecore.py index 93228468..d208048b 100644 --- a/view/sharedcache/api/python/_sharedcachecore.py +++ b/view/sharedcache/api/python/_sharedcachecore.py @@ -578,23 +578,6 @@ def BNDSCViewLoadSectionAtAddress( # ------------------------------------------------------- -# _BNDSCViewLoadedImageCount - -_BNDSCViewLoadedImageCount = core.BNDSCViewLoadedImageCount -_BNDSCViewLoadedImageCount.restype = ctypes.c_ulonglong -_BNDSCViewLoadedImageCount.argtypes = [ - ctypes.POINTER(BNSharedCache), - ] - - -# noinspection PyPep8Naming -def BNDSCViewLoadedImageCount( - cache: ctypes.POINTER(BNSharedCache) - ) -> int: - return _BNDSCViewLoadedImageCount(cache) - - -# ------------------------------------------------------- # _BNFreeSharedCacheReference _BNFreeSharedCacheReference = core.BNFreeSharedCacheReference diff --git a/view/sharedcache/api/python/sharedcache.py b/view/sharedcache/api/python/sharedcache.py index ca031e03..54745ed5 100644 --- a/view/sharedcache/api/python/sharedcache.py +++ b/view/sharedcache/api/python/sharedcache.py @@ -12,17 +12,15 @@ from .sharedcache_enums import * @dataclasses.dataclass class DSCMemoryMapping: - filePath: str name: str vmAddress: int - rawViewOffset: int size: int def __str__(self): return repr(self) def __repr__(self): - return f"<DSCMemoryMapping '{self.name}' {os.path.basename(self.filePath)} raw<{self.rawViewOffset:x}>: {self.vmAddress:x}+{self.size:x}>" + return f"<DSCMemoryMapping '{self.name}': {self.vmAddress:x}+{self.size:x}>" @dataclasses.dataclass @@ -176,31 +174,32 @@ class SharedCache: return result @property - def loaded_images(self): + def loaded_regions(self): + """ + Get all loaded regions in the shared cache + + The internal logic for loading images treats a region as 'loaded' whenever + that region has been mapped into memory, and, if it's located within an image, header information has been applied to that region. + + Individual segments within an image can be loaded independently of the image itself. + + Only once all regions of an image are loaded will the header processor refuse to run on that region. + :return: + """ count = ctypes.c_ulonglong() - value = sccore.BNDSCViewGetLoadedImages(self.handle, count) + value = sccore.BNDSCViewGetLoadedRegions(self.handle, count) if value is None: return [] result = [] for i in range(count.value): - mappings = [] - for j in range(value[i].mappingCount): - mapping = DSCMemoryMapping( - value[i].mappings[j].filePath, - value[i].mappings[j].name, - value[i].mappings[j].vmAddress, - value[i].mappings[j].rawViewOffset, - value[i].mappings[j].size - ) - mappings.append(mapping) - result.append(LoadedRegion( + mapping = DSCMemoryMapping( value[i].name, - value[i].headerAddress, - mappings - )) - - sccore.BNDSCViewFreeLoadedImages(value, count) + value[i].vmAddress, + value[i].size, + ) + result.append(mapping) + sccore.BNDSCViewFreeLoadedRegions(value, count) return result def load_all_symbols_and_wait(self): @@ -235,10 +234,6 @@ class SharedCache: return result @property - def image_count(self): - return sccore.BNDSCViewLoadedImageCount(self.handle) - - @property def state(self): return DSCViewState(sccore.BNDSCViewGetState(self.handle)) diff --git a/view/sharedcache/api/sharedcachecore.h b/view/sharedcache/api/sharedcachecore.h index 1c382e48..9fc33275 100644 --- a/view/sharedcache/api/sharedcachecore.h +++ b/view/sharedcache/api/sharedcachecore.h @@ -119,7 +119,6 @@ extern "C" SHAREDCACHE_FFI_API void BNFreeSharedCacheReference(BNSharedCache* cache); SHAREDCACHE_FFI_API char** BNDSCViewGetInstallNames(BNSharedCache* cache, size_t* count); - SHAREDCACHE_FFI_API uint64_t BNDSCViewLoadedImageCount(BNSharedCache* cache); SHAREDCACHE_FFI_API bool BNDSCViewLoadImageWithInstallName(BNSharedCache* cache, char* name); SHAREDCACHE_FFI_API bool BNDSCViewLoadSectionAtAddress(BNSharedCache* cache, uint64_t name); diff --git a/view/sharedcache/core/CMakeLists.txt b/view/sharedcache/core/CMakeLists.txt index 9cf3fa9d..22c7ea28 100644 --- a/view/sharedcache/core/CMakeLists.txt +++ b/view/sharedcache/core/CMakeLists.txt @@ -46,25 +46,36 @@ endfunction() get_recursive_include_dirs(binaryninjaapi INCLUDES) +set(COMPILE_DEFS "") + +if (HARD_FAIL_MODE) + set(COMPILE_DEFS "${COMPILE_DEFS} ABORT_FAILURES;") +endif() + +if (BN_REF_COUNT_DEBUG) + set(COMPILE_DEFS "${COMPILE_DEFS} BN_REF_COUNT_DEBUG;") +endif() + +if (SLIDEINFO_DEBUG_TAGS) + set(COMPILE_DEFS "${COMPILE_DEFS} SLIDEINFO_DEBUG_TAGS;") +endif() + if (VIEW_NAME) - if (SLIDEINFO_DEBUG_TAGS) - if (BN_REF_COUNT_DEBUG) - target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY SLIDEINFO_DEBUG_TAGS BN_REF_COUNT_DEBUG) - else() - target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY SLIDEINFO_DEBUG_TAGS) - endif() - else() - if (BN_REF_COUNT_DEBUG) - target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY BN_REF_COUNT_DEBUG) - else() - target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY) - endif() - endif() - message(STATUS "VIEW_NAME: ${VIEW_NAME}") + set(COMPILE_DEFS "${COMPILE_DEFS} VIEW_NAME=\"${VIEW_NAME}\";") +else() + message(FATAL_ERROR "No view name provided. Fatal.") +endif() + +if (METADATA_VERSION) + set(COMPILE_DEFS "${COMPILE_DEFS} METADATA_VERSION=${METADATA_VERSION};") else() - error("VIEW_NAME must be defined") + message(FATAL_ERROR "No metadata version provided. Fatal.") endif() +target_compile_definitions(sharedcachecore PRIVATE ${COMPILE_DEFS}) + + +target_compile_definitions(sharedcachecore PRIVATE SHAREDCACHE_LIBRARY ${COMPILE_DEFS}) target_include_directories(sharedcachecore PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${INCLUDES}) diff --git a/view/sharedcache/core/DSCView.cpp b/view/sharedcache/core/DSCView.cpp index 7a1b3677..80456fc7 100644 --- a/view/sharedcache/core/DSCView.cpp +++ b/view/sharedcache/core/DSCView.cpp @@ -629,6 +629,21 @@ bool DSCView::Init() ss.str(data); rapidjson::Document result(rapidjson::kObjectType); + if (result.HasMember("metadataVersion")) + { + if (result["metadataVersion"].GetInt() != METADATA_VERSION) + { + LogError("Shared cache metadata version mismatch: expected %d, got %d", METADATA_VERSION, + result["metadataVersion"].GetInt()); + return false; + } + } + else + { + LogError("Shared cache metadata version not found"); + return false; + } + result.Parse(data.c_str()); for (auto& imgV : result["regionsMappedIntoMemory"].GetArray()) { diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 49aa3174..ec0db6e7 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -164,7 +164,14 @@ uint64_t readValidULEB128(DataBuffer& buffer, size_t& cursor) uint64_t SharedCache::FastGetBackingCacheCount(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView) { - auto baseFile = MMappedFileAccessor::Open(dscView->GetFile()->GetSessionId(), dscView->GetFile()->GetOriginalFilename())->lock(); + std::shared_ptr<MMappedFileAccessor> baseFile; + try { + baseFile = MMappedFileAccessor::Open(dscView->GetFile()->GetSessionId(), dscView->GetFile()->GetOriginalFilename())->lock(); + } + catch (...){ + LogError("SharedCache preload: Failed to open file"); + return 0; + } dyld_cache_header header {}; size_t header_size = baseFile->ReadUInt32(16); @@ -749,7 +756,7 @@ void SharedCache::PerformInitialLoad() memcpy(segName, segment.segname, 16); segName[16] = 0; MemoryRegion sectionRegion; - sectionRegion.prettyName = std::string(segName); + sectionRegion.prettyName = imageHeader.value().identifierPrefix + "::" + std::string(segName); sectionRegion.start = segment.vmaddr; sectionRegion.size = segment.vmsize; uint32_t flags = 0; @@ -983,14 +990,21 @@ void SharedCache::DeserializeFromRawView() m_baseFilePath = c.m_baseFilePath; m_exportInfos = c.m_exportInfos; m_symbolInfos = c.m_symbolInfos; + m_metadataValid = true; } else { LoadFromString(m_dscView->GetStringMetadata(SharedCacheMetadataTag)); } + if (!m_metadataValid) + { + m_logger->LogError("Failed to deserialize Shared Cache metadata"); + m_viewState = DSCViewStateUnloaded; + } } else { + m_metadataValid = true; m_viewState = DSCViewStateUnloaded; m_images.clear(); // fixme ?? } @@ -1343,6 +1357,8 @@ SharedCache::SharedCache(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView) : m_ INIT_SHAREDCACHE_API_OBJECT() m_logger = LogRegistry::GetLogger("SharedCache", dscView->GetFile()->GetSessionId()); DeserializeFromRawView(); + if (!m_metadataValid) + return; if (m_viewState == DSCViewStateUnloaded) { if (m_viewState == DSCViewStateUnloaded) @@ -2935,6 +2951,8 @@ bool SharedCache::SaveToDSCView() c.m_symbolInfos = m_symbolInfos; viewStateCache[m_dscView->GetFile()->GetSessionId()] = c; + m_metadataValid = true; + return true; } return false; diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 2f099773..9e9688bd 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -940,6 +940,8 @@ namespace SharedCacheCore { void Store() override { + m_activeContext.doc.AddMember("metadataVersion", METADATA_VERSION, m_activeContext.allocator); + MSS(m_viewState); MSS_CAST(m_cacheFormat, uint8_t); MSS(m_imageStarts); @@ -1026,6 +1028,19 @@ namespace SharedCacheCore { } void Load() override { + if (m_activeDeserContext.doc.HasMember("metadataVersion")) + { + if (m_activeDeserContext.doc["metadataVersion"].GetUint() != METADATA_VERSION) + { + m_logger->LogError("SharedCache metadata version mismatch"); + return; + } + } + else + { + m_logger->LogError("SharedCache metadata version missing"); + return; + } m_viewState = MSL_CAST(m_viewState, uint8_t, DSCViewState); m_cacheFormat = MSL_CAST(m_cacheFormat, uint8_t, SharedCacheFormat); m_headers.clear(); @@ -1101,6 +1116,8 @@ namespace SharedCacheCore { si.LoadFromValue(siV); m_nonImageRegions.push_back(si); } + + m_metadataValid = true; } private: @@ -1108,7 +1125,7 @@ namespace SharedCacheCore { /* VIEW STATE BEGIN -- SERIALIZE ALL OF THIS AND STORE IT IN RAW VIEW */ // Updated as the view is loaded further, more images are added, etc - DSCViewState m_viewState; + DSCViewState m_viewState = DSCViewStateUnloaded; std::unordered_map<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>> m_exportInfos; std::unordered_map<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>> @@ -1116,6 +1133,8 @@ namespace SharedCacheCore { // --- // Serialized once by PerformInitialLoad and available after m_viewState == Loaded + bool m_metadataValid = false; + std::string m_baseFilePath; SharedCacheFormat m_cacheFormat; @@ -1171,7 +1190,10 @@ namespace SharedCacheCore { void FindSymbolAtAddrAndApplyToAddr(uint64_t symbolLocation, uint64_t targetLocation, bool triggerReanalysis); - std::vector<BackingCache> BackingCaches() const { return m_backingCaches; } + std::vector<BackingCache> BackingCaches() const { + + return m_backingCaches; + } DSCViewState State() const { return m_viewState; } diff --git a/view/sharedcache/ui/CMakeLists.txt b/view/sharedcache/ui/CMakeLists.txt index 1695b8dd..88a68375 100644 --- a/view/sharedcache/ui/CMakeLists.txt +++ b/view/sharedcache/ui/CMakeLists.txt @@ -12,16 +12,35 @@ list(FILTER SOURCES EXCLUDE REGEX qrc_.*) add_library(sharedcacheui SHARED ${SOURCES}) +set(COMPILE_DEFS "") + +if (HARD_FAIL_MODE) + set(COMPILE_DEFS "${COMPILE_DEFS} ABORT_FAILURES;") +endif() + +if (BN_REF_COUNT_DEBUG) + set(COMPILE_DEFS "${COMPILE_DEFS} BN_REF_COUNT_DEBUG;") +endif() + +if (SLIDEINFO_DEBUG_TAGS) + set(COMPILE_DEFS "${COMPILE_DEFS} SLIDEINFO_DEBUG_TAGS;") +endif() + +if (METADATA_VERSION) + set(COMPILE_DEFS "${COMPILE_DEFS} METADATA_VERSION=${METADATA_VERSION};") +else() + message(FATAL_ERROR "No metadata version provided. Fatal.") +endif() + if (VIEW_NAME) - if (BN_REF_COUNT_DEBUG) - target_compile_definitions(sharedcacheui PRIVATE VIEW_NAME="${VIEW_NAME}" BN_REF_COUNT_DEBUG) - else() - target_compile_definitions(sharedcacheui PRIVATE VIEW_NAME="${VIEW_NAME}") - endif() + set(COMPILE_DEFS "${COMPILE_DEFS} VIEW_NAME=\"${VIEW_NAME}\";") else() - error("VIEW_NAME must be defined") + message(FATAL_ERROR "No view name provided. Fatal.") endif() +target_compile_definitions(sharedcacheui PRIVATE ${COMPILE_DEFS}) + + if(BN_INTERNAL_BUILD) set_target_properties(sharedcacheui PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR} diff --git a/view/sharedcache/ui/dsctriage.cpp b/view/sharedcache/ui/dsctriage.cpp index 7680317c..29bec7ec 100644 --- a/view/sharedcache/ui/dsctriage.cpp +++ b/view/sharedcache/ui/dsctriage.cpp @@ -61,6 +61,10 @@ DSCCacheBlocksView::DSCCacheBlocksView(QWidget* parent, BinaryViewRef data, Ref< ->withEasingCurve(QEasingCurve::InOutCirc) ->thenOnStart([this](QAbstractAnimation::Direction) { + if (m_backingCaches.size() < m_backingCacheCount) + { + return; + } uint64_t totalSize = 0; uint64_t sumCountForAvg = 0; for (size_t i = 0; i < m_backingCacheCount; i++) @@ -116,6 +120,8 @@ DSCCacheBlocksView::DSCCacheBlocksView(QWidget* parent, BinaryViewRef data, Ref< }) ->thenOnEnd([this](QAbstractAnimation::Direction) { + if (m_backingCaches.size() == 0) + return; emit selectionChanged(m_backingCaches[0], true); }); diff --git a/view/sharedcache/workflow/CMakeLists.txt b/view/sharedcache/workflow/CMakeLists.txt index 7648492a..7a9c157a 100644 --- a/view/sharedcache/workflow/CMakeLists.txt +++ b/view/sharedcache/workflow/CMakeLists.txt @@ -4,16 +4,34 @@ project(sharedcacheworkflow) file(GLOB SOURCES *.cpp *.h) add_library(sharedcacheworkflow OBJECT ${SOURCES}) +set(COMPILE_DEFS "") + +if (HARD_FAIL_MODE) + set(COMPILE_DEFS "${COMPILE_DEFS} ABORT_FAILURES") +endif() + +if (BN_REF_COUNT_DEBUG) + set(COMPILE_DEFS "${COMPILE_DEFS} BN_REF_COUNT_DEBUG;") +endif() + +if (SLIDEINFO_DEBUG_TAGS) + set(COMPILE_DEFS "${COMPILE_DEFS} SLIDEINFO_DEBUG_TAGS;") +endif() + +if (METADATA_VERSION) + set(COMPILE_DEFS "${COMPILE_DEFS} METADATA_VERSION=${METADATA_VERSION};") +else() + message(FATAL_ERROR "No metadata version provided. Fatal.") +endif() + if (VIEW_NAME) - if (BN_REF_COUNT_DEBUG) - target_compile_definitions(sharedcacheworkflow PRIVATE VIEW_NAME="${VIEW_NAME}" BN_REF_COUNT_DEBUG) - else() - target_compile_definitions(sharedcacheworkflow PRIVATE VIEW_NAME="${VIEW_NAME}") - endif() + set(COMPILE_DEFS "${COMPILE_DEFS} VIEW_NAME=\"${VIEW_NAME}\"") else() - error("VIEW_NAME must be defined") + message(FATAL_ERROR "No view name provided. Fatal.") endif() +target_compile_definitions(sharedcacheworkflow PRIVATE ${COMPILE_DEFS}) + function(get_recursive_include_dirs target result) # Initialize an empty list to store include directories |
