diff options
author | 2025-03-18 05:59:29 -0700 | |
---|---|---|
committer | 2025-03-18 05:59:29 -0700 | |
commit | 6c65610f9f3dab05d2a39b883578845234bdbcda (patch) | |
tree | d22948d5ef8eafd33069b6fa8836d8fe1beb47ab | |
parent | 3ea3bd3ec2615db4b748eec9ff05ea0a11dbdc89 (diff) | |
parent | 7827597532707582b082679cd845111b0b61f2f2 (diff) |
Merge "libvulkan: refactor for _FORTIFY_SOURCE=3 support." into main am: 7827597532
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/3542879
Change-Id: I390d6f24d160f747aeaa7cf24e0f1c1515fb29f0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | vulkan/libvulkan/Android.bp | 40 | ||||
-rw-r--r-- | vulkan/libvulkan/allocator.cpp | 113 | ||||
-rw-r--r-- | vulkan/libvulkan/allocator.h | 25 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 75 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.h | 2 |
5 files changed, 171 insertions, 84 deletions
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp index 879d2d0fa7..7e7fdc4932 100644 --- a/vulkan/libvulkan/Android.bp +++ b/vulkan/libvulkan/Android.bp @@ -41,14 +41,9 @@ cc_aconfig_library { aconfig_declarations: "libvulkan_flags", } -cc_library_shared { - name: "libvulkan", - llndk: { - symbol_file: "libvulkan.map.txt", - export_llndk_headers: [ - "vulkan_headers", - ], - }, +cc_defaults { + name: "libvulkan_defaults", + sanitize: { misc_undefined: ["integer"], }, @@ -81,6 +76,34 @@ cc_library_shared { "-Wno-global-constructors", "-Wno-zero-length-array", ], +} + +cc_library { + name: "libvulkanallocator", + defaults: ["libvulkan_defaults"], + cflags: [ + // This code uses malloc_usable_size(), + // and thus can't be built with _FORTIFY_SOURCE=3. + "-U_FORTIFY_SOURCE", + "-D_FORTIFY_SOURCE=2", + ], + srcs: [ + "allocator.cpp", + ], + header_libs: [ + "vulkan_headers", + ], +} + +cc_library_shared { + name: "libvulkan", + defaults: ["libvulkan_defaults"], + llndk: { + symbol_file: "libvulkan.map.txt", + export_llndk_headers: [ + "vulkan_headers", + ], + }, srcs: [ "api.cpp", @@ -124,6 +147,7 @@ cc_library_shared { ], static_libs: [ "libgrallocusage", + "libvulkanallocator", "libvulkanflags", ], } diff --git a/vulkan/libvulkan/allocator.cpp b/vulkan/libvulkan/allocator.cpp new file mode 100644 index 0000000000..2ca0586a14 --- /dev/null +++ b/vulkan/libvulkan/allocator.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include "allocator.h" + +#include <stdlib.h> + +#include <algorithm> + +#include <log/log.h> + +// #define ENABLE_ALLOC_CALLSTACKS 1 +#if ENABLE_ALLOC_CALLSTACKS +#include <utils/CallStack.h> +#define ALOGD_CALLSTACK(...) \ + do { \ + ALOGD(__VA_ARGS__); \ + android::CallStack callstack; \ + callstack.update(); \ + callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \ + } while (false) +#else +#define ALOGD_CALLSTACK(...) \ + do { \ + } while (false) +#endif + +namespace vulkan { +namespace driver { + +namespace { + +VKAPI_ATTR void* DefaultAllocate(void*, + size_t size, + size_t alignment, + VkSystemAllocationScope) { + void* ptr = nullptr; + // Vulkan requires 'alignment' to be a power of two, but posix_memalign + // additionally requires that it be at least sizeof(void*). + int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size); + ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment, + ret, ptr); + return ret == 0 ? ptr : nullptr; +} + +// This function is marked `noinline` so that LLVM can't infer an object size +// for FORTIFY through it, given that it's abusing malloc_usable_size(). +__attribute__((__noinline__)) +VKAPI_ATTR void* DefaultReallocate(void*, + void* ptr, + size_t size, + size_t alignment, + VkSystemAllocationScope) { + if (size == 0) { + free(ptr); + return nullptr; + } + + // TODO(b/143295633): Right now we never shrink allocations; if the new + // request is smaller than the existing chunk, we just continue using it. + // Right now the loader never reallocs, so this doesn't matter. If that + // changes, or if this code is copied into some other project, this should + // probably have a heuristic to allocate-copy-free when doing so will save + // "enough" space. + size_t old_size = ptr ? malloc_usable_size(ptr) : 0; + if (size <= old_size) + return ptr; + + void* new_ptr = nullptr; + if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0) + return nullptr; + if (ptr) { + memcpy(new_ptr, ptr, std::min(old_size, size)); + free(ptr); + } + return new_ptr; +} + +VKAPI_ATTR void DefaultFree(void*, void* ptr) { + ALOGD_CALLSTACK("Free: %p", ptr); + free(ptr); +} + +} // anonymous namespace + +const VkAllocationCallbacks& GetDefaultAllocator() { + static const VkAllocationCallbacks kDefaultAllocCallbacks = { + .pUserData = nullptr, + .pfnAllocation = DefaultAllocate, + .pfnReallocation = DefaultReallocate, + .pfnFree = DefaultFree, + }; + + return kDefaultAllocCallbacks; +} + +} // namespace driver +} // namespace vulkan diff --git a/vulkan/libvulkan/allocator.h b/vulkan/libvulkan/allocator.h new file mode 100644 index 0000000000..9095e921c5 --- /dev/null +++ b/vulkan/libvulkan/allocator.h @@ -0,0 +1,25 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <vulkan/vulkan.h> + +namespace vulkan { +namespace driver { + +const VkAllocationCallbacks& GetDefaultAllocator(); + +} // namespace driver +} // namespace vulkan diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 7d0f545774..28c1b5f663 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -50,22 +50,6 @@ using namespace com::android::graphics::libvulkan; extern "C" android_namespace_t* android_get_exported_namespace(const char*); -// #define ENABLE_ALLOC_CALLSTACKS 1 -#if ENABLE_ALLOC_CALLSTACKS -#include <utils/CallStack.h> -#define ALOGD_CALLSTACK(...) \ - do { \ - ALOGD(__VA_ARGS__); \ - android::CallStack callstack; \ - callstack.update(); \ - callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \ - } while (false) -#else -#define ALOGD_CALLSTACK(...) \ - do { \ - } while (false) -#endif - namespace vulkan { namespace driver { @@ -829,54 +813,6 @@ void CreateInfoWrapper::FilterExtension(const char* name) { } } -VKAPI_ATTR void* DefaultAllocate(void*, - size_t size, - size_t alignment, - VkSystemAllocationScope) { - void* ptr = nullptr; - // Vulkan requires 'alignment' to be a power of two, but posix_memalign - // additionally requires that it be at least sizeof(void*). - int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size); - ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment, - ret, ptr); - return ret == 0 ? ptr : nullptr; -} - -VKAPI_ATTR void* DefaultReallocate(void*, - void* ptr, - size_t size, - size_t alignment, - VkSystemAllocationScope) { - if (size == 0) { - free(ptr); - return nullptr; - } - - // TODO(b/143295633): Right now we never shrink allocations; if the new - // request is smaller than the existing chunk, we just continue using it. - // Right now the loader never reallocs, so this doesn't matter. If that - // changes, or if this code is copied into some other project, this should - // probably have a heuristic to allocate-copy-free when doing so will save - // "enough" space. - size_t old_size = ptr ? malloc_usable_size(ptr) : 0; - if (size <= old_size) - return ptr; - - void* new_ptr = nullptr; - if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0) - return nullptr; - if (ptr) { - memcpy(new_ptr, ptr, std::min(old_size, size)); - free(ptr); - } - return new_ptr; -} - -VKAPI_ATTR void DefaultFree(void*, void* ptr) { - ALOGD_CALLSTACK("Free: %p", ptr); - free(ptr); -} - InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) { void* data_mem = allocator.pfnAllocation( allocator.pUserData, sizeof(InstanceData), alignof(InstanceData), @@ -916,17 +852,6 @@ bool OpenHAL() { return Hal::Open(); } -const VkAllocationCallbacks& GetDefaultAllocator() { - static const VkAllocationCallbacks kDefaultAllocCallbacks = { - .pUserData = nullptr, - .pfnAllocation = DefaultAllocate, - .pfnReallocation = DefaultReallocate, - .pfnFree = DefaultFree, - }; - - return kDefaultAllocCallbacks; -} - PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { const ProcHook* hook = GetProcHook(pName); if (!hook) diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 4b855e5999..fa85dd5b55 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -27,6 +27,7 @@ #include <vulkan/vulkan.h> #include <hardware/hwvulkan.h> +#include "allocator.h" #include "api_gen.h" #include "driver_gen.h" #include "debug_report.h" @@ -102,7 +103,6 @@ struct DeviceData { }; bool OpenHAL(); -const VkAllocationCallbacks& GetDefaultAllocator(); void QueryPresentationProperties( VkPhysicalDevice physicalDevice, |