summaryrefslogtreecommitdiff
path: root/view/sharedcache
diff options
context:
space:
mode:
authorkat <kat@vector35.com>2024-10-30 08:39:09 -0400
committerkat <kat@vector35.com>2024-11-05 09:03:12 -0500
commitf4a4b17b9e30cf603eb614e153d68226a3b24520 (patch)
treee33d18742c1a9e9b47af04df24bf88248c17f06a /view/sharedcache
parentfd8eb478a7a3bbc848da37bd33e62c2d8cf26b99 (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.txt42
-rw-r--r--view/sharedcache/api/CMakeLists.txt32
-rw-r--r--view/sharedcache/api/python/_sharedcachecore.py17
-rw-r--r--view/sharedcache/api/python/sharedcache.py45
-rw-r--r--view/sharedcache/api/sharedcachecore.h1
-rw-r--r--view/sharedcache/core/CMakeLists.txt41
-rw-r--r--view/sharedcache/core/DSCView.cpp15
-rw-r--r--view/sharedcache/core/SharedCache.cpp22
-rw-r--r--view/sharedcache/core/SharedCache.h26
-rw-r--r--view/sharedcache/ui/CMakeLists.txt31
-rw-r--r--view/sharedcache/ui/dsctriage.cpp6
-rw-r--r--view/sharedcache/workflow/CMakeLists.txt30
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