Merge remote-tracking branch 'upstream/sdk-1.1.121' into HEAD

Change-Id: I2816e26a12bcf86799b67f1604ef16b61dc0399f
diff --git a/.appveyor.yml b/.appveyor.yml
index b60097d..65999b7 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -55,7 +55,7 @@
   - echo Generating CMake files for %PLATFORM%
   - mkdir build
   - cd build
-  - cmake -A %PLATFORM% -C../external/helper.cmake ..
+  - cmake -A %PLATFORM% -C../external/helper.cmake -DWDK_VERSION=10.0.17763.0 ..
   - echo Building platform=%PLATFORM% configuration=%CONFIGURATION%
 
 platform:
diff --git a/BUILD.gn b/BUILD.gn
index 7cef22b..4fe391d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -59,7 +59,7 @@
     "loader/generated",
     "loader",
   ]
-  defines = [ "API_NAME=\"Vulkan\"" ] + vulkan_loader_extra_defines
+  defines = [ "API_NAME=\"Vulkan\"" ]
 
   if (is_win) {
     cflags = [ "/wd4201" ]
diff --git a/BUILD.md b/BUILD.md
index 026298a..5fc7075 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -391,8 +391,8 @@
 ### Linux Development Environment Requirements
 
 This repository has been built and tested on the two most recent Ubuntu LTS
-versions. Currently, the oldest supported version is Ubuntu 14.04, meaning
-that the minimum supported compiler versions are GCC 4.8.2 and Clang 3.4,
+versions. Currently, the oldest supported version is Ubuntu 16.04, meaning
+that the minimum officially supported C++11 compiler version is GCC 5.4.0,
 although earlier versions may work. It should be straightforward to adapt this
 repository to other Linux distributions.
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 85bddd6..81532fd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@
 
 if (TARGET Vulkan::Headers)
     message(STATUS "Using Vulkan headers from Vulkan::Headers target")
+    get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
     get_target_property(VulkanRegistry_DIR Vulkan::Registry INTERFACE_INCLUDE_DIRECTORIES)
 else()
     find_package(VulkanHeaders)
diff --git a/build-gn/secondary/build_overrides/vulkan_loader.gni b/build-gn/secondary/build_overrides/vulkan_loader.gni
index 4b248e2..c826fc1 100644
--- a/build-gn/secondary/build_overrides/vulkan_loader.gni
+++ b/build-gn/secondary/build_overrides/vulkan_loader.gni
@@ -19,6 +19,5 @@
 vulkan_gen_subdir = "" 
 
 # Vulkan loader build options
-vulkan_loader_extra_defines = []
 vulkan_loader_shared = true
 
diff --git a/cmake/FindWDK.cmake b/cmake/FindWDK.cmake
index 1f8c6f1..5868343 100644
--- a/cmake/FindWDK.cmake
+++ b/cmake/FindWDK.cmake
@@ -41,21 +41,33 @@
 #   WDK_INCLUDE_DIRS             - include directories for the WDK
 #
 
-if(NOT DEFINED WDK_FULL_PATH)
-    if(NOT DEFINED WDK_BASE)
+if(DEFINED WDK_FULL_PATH)
+    find_path(WDK_VERSION_INCLUDE_DIR
+        NAMES km/d3dkmthk.h shared/d3dkmdt.h
+        PATHS "${WDK_FULL_PATH}"
+    )
+else()
+    if(NOT DEFINED WDK_BASE AND DEFINED "$ENV{UniversalCRTSdkDir}")
         set(WDK_BASE "$ENV{UniversalCRTSdkDir}")
+    elseif(NOT DEFINED WDK_BASE)
+        set(WDK_BASE "C:/Program Files (x86)/Windows Kits/10/")
     endif()
-    if(NOT DEFINED WDK_VERSION)
-        set(WDK_VERSION "$ENV{UCRTVersion}")
-        string(REPLACE \\ "" WDK_VERSION "${WDK_VERSION}")
-    endif()
-    set(WDK_FULL_PATH "${WDK_BASE}/Include/${WDK_VERSION}")
-endif()
 
-find_path(WDK_VERSION_INCLUDE_DIR
-    NAMES km/d3dkmthk.h shared/d3dkmdt.h
-    PATHS "${WDK_FULL_PATH}"
-)
+    if(DEFINED WDK_VERSION)
+        set(SUBDIRS "Include/${WDK_VERSION}")
+    else()
+        file(GLOB DIR_LIST RELATIVE "C:/Program Files (x86)/Windows Kits/10/" "C:/Program Files (x86)/Windows Kits/10/Include/*")
+        list(REVERSE DIR_LIST)
+        foreach(DIR IN ITEMS "${DIR_LIST}")
+            set(SUBDIRS "${SUBDIRS}" "${DIR}")
+        endforeach()
+    endif()
+    find_path(WDK_VERSION_INCLUDE_DIR
+        NAMES km/d3dkmthk.h shared/d3dkmdt.h
+        PATHS "${WDK_BASE}"
+        PATH_SUFFIXES ${SUBDIRS}
+    )
+endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(WDK DEFAULT_MSG WDK_VERSION_INCLUDE_DIR)
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index a9401db..f357100 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -19,6 +19,8 @@
 
 # Check for the existance of the secure_getenv or __secure_getenv commands
 include(CheckFunctionExists)
+include(CheckIncludeFile)
+
 check_function_exists(secure_getenv HAVE_SECURE_GETENV)
 check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/loader_cmake_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/loader_cmake_config.h)
@@ -146,25 +148,23 @@
     set_source_files_properties(${OPT_LOADER_SRCS} PROPERTIES COMPILE_FLAGS -O)
     add_custom_target(loader_asm_gen_files) # This causes no assembly files to be generated.
 else(UNIX AND NOT APPLE) # i.e.: Linux
-    enable_language(ASM-ATT)
-    set(CMAKE_ASM-ATT_COMPILE_FLAGS "${CMAKE_ASM-ATT_COMPILE_FLAGS} $ENV{ASFLAGS}")
-    set(CMAKE_ASM-ATT_COMPILE_FLAGS "${CMAKE_ASM-ATT_COMPILE_FLAGS} -I\"${CMAKE_CURRENT_BINARY_DIR}\"")
+    enable_language(ASM)
+    set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
 
-    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.asm
+    check_include_file("cet.h" HAVE_CET_H)
+    if(HAVE_CET_H)
+        add_definitions(-DHAVE_CET_H)
+    endif()
+    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.S
                ".intel_syntax noprefix\n.text\n.global sample\nsample:\nmov ecx, [eax + 16]\n")
-    # try_compile uses the C/C++ linker flags even for ASM,
-    # while they're not valid for ASM and making linking fail.
-    set(TMP_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
-    set(CMAKE_EXE_LINKER_FLAGS "")
-    try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/asm_test.asm)
-    set(CMAKE_EXE_LINKER_FLAGS ${TMP_EXE_LINKER_FLAGS})
-    file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.asm)
+    set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+    try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/asm_test.S)
+    file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/asm_test.S)
     if(ASSEMBLER_WORKS)
-        set(CMAKE_ASM-ATT_FLAGS "$ENV{ASFLAGS} -I\"${CMAKE_CURRENT_BINARY_DIR}\"")
-        set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas.asm)
+        set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas.S)
         add_executable(asm_offset asm_offset.c)
         target_link_libraries(asm_offset Vulkan::Headers)
-        add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS)
+        add_custom_command(OUTPUT gen_defines.asm DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/asm_offset COMMAND ${CMAKE_CURRENT_BINARY_DIR}/asm_offset GAS)
         add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
     else()
         message(WARNING "Could not find working x86 GAS assembler\n${ASM_FAILURE_MSG}")
@@ -174,7 +174,7 @@
 endif()
 
 if(WIN32)
-    add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c)
+    add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c dxgi_loader.c)
     target_compile_options(loader-norm PUBLIC "$<$<CONFIG:DEBUG>:${LOCAL_C_FLAGS_DBG}>")
     target_compile_options(loader-norm PUBLIC ${MSVC_LOADER_COMPILE_OPTIONS})
     target_include_directories(loader-norm PRIVATE "$<TARGET_PROPERTY:Vulkan::Headers,INTERFACE_INCLUDE_DIRECTORIES>")
diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index d176dc6..b5828d0 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -46,7 +46,7 @@
   * [Vulkan Installable Client Driver interface with the loader](#vulkan-installable-client-driver-interface-with-the-loader)
     * [ICD Discovery](#icd-discovery)
     * [ICD Manifest File Format](#icd-manifest-file-format)
-    * [ICD Vulkan Entry Point Discovery](#icd-vulkan-entry point-discovery)
+    * [ICD Vulkan Entry Point Discovery](#icd-vulkan-entry-point-discovery)
     * [ICD API Version](#icd-api-version)
     * [ICD Unknown Physical Device Extensions](#icd-unknown-physical-device-extensions)
     * [ICD Dispatchable Object Creation](#icd-dispatchable-object-creation)
diff --git a/loader/dxgi_loader.c b/loader/dxgi_loader.c
new file mode 100644
index 0000000..c2a3fa5
--- /dev/null
+++ b/loader/dxgi_loader.c
@@ -0,0 +1,23 @@
+#include "dxgi_loader.h"
+
+#include <strsafe.h>
+
+static HMODULE load_dxgi_module() {
+    TCHAR systemPath[MAX_PATH] = "";
+    GetSystemDirectory(systemPath, MAX_PATH);
+    StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll"));
+
+    return LoadLibrary(systemPath);
+}
+
+typedef HRESULT (APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory);
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory) {
+    PFN_CreateDXGIFactory1 fpCreateDXGIFactory1 =
+        (PFN_CreateDXGIFactory1)GetProcAddress(load_dxgi_module(), "CreateDXGIFactory1");
+
+    if (fpCreateDXGIFactory1 != NULL)
+        return fpCreateDXGIFactory1(riid, ppFactory);
+
+    return DXGI_ERROR_NOT_FOUND;
+}
\ No newline at end of file
diff --git a/loader/dxgi_loader.h b/loader/dxgi_loader.h
new file mode 100644
index 0000000..00daf08
--- /dev/null
+++ b/loader/dxgi_loader.h
@@ -0,0 +1,8 @@
+#ifndef DXGI_LOADER_H
+#define DXGI_LOADER_H
+
+#include <dxgi1_2.h>
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory);
+
+#endif
\ No newline at end of file
diff --git a/loader/generated/vk_dispatch_table_helper.h b/loader/generated/vk_dispatch_table_helper.h
index ebd5a7b..299cb77 100644
--- a/loader/generated/vk_dispatch_table_helper.h
+++ b/loader/generated/vk_dispatch_table_helper.h
@@ -86,6 +86,9 @@
 static VKAPI_ATTR void VKAPI_CALL StubGetDescriptorSetLayoutSupportKHR(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport) {  };
 static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) {  };
 static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) {  };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutablePropertiesKHR(VkDevice                        device, const VkPipelineInfoKHR*        pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutableStatisticsKHR(VkDevice                        device, const VkPipelineExecutableInfoKHR*  pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutableInternalRepresentationsKHR(VkDevice                        device, const VkPipelineExecutableInfoKHR*  pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) { return VK_SUCCESS; };
 static VKAPI_ATTR VkResult VKAPI_CALL StubDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) { return VK_SUCCESS; };
 static VKAPI_ATTR VkResult VKAPI_CALL StubDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) { return VK_SUCCESS; };
 static VKAPI_ATTR void VKAPI_CALL StubCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) {  };
@@ -179,6 +182,7 @@
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 static VKAPI_ATTR VkResult VKAPI_CALL StubGetDeviceGroupSurfacePresentModes2EXT(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes) { return VK_SUCCESS; };
 #endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern) {  };
 static VKAPI_ATTR void VKAPI_CALL StubResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {  };
 #ifdef VK_USE_PLATFORM_FUCHSIA
 static VKAPI_ATTR VkResult VKAPI_CALL StubCreateBufferCollectionFUCHSIA(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pImportInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection) { return VK_SUCCESS; };
@@ -452,6 +456,12 @@
     if (table->CmdDrawIndirectCountKHR == nullptr) { table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)StubCmdDrawIndirectCountKHR; }
     table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR) gpa(device, "vkCmdDrawIndexedIndirectCountKHR");
     if (table->CmdDrawIndexedIndirectCountKHR == nullptr) { table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)StubCmdDrawIndexedIndirectCountKHR; }
+    table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR) gpa(device, "vkGetPipelineExecutablePropertiesKHR");
+    if (table->GetPipelineExecutablePropertiesKHR == nullptr) { table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)StubGetPipelineExecutablePropertiesKHR; }
+    table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR) gpa(device, "vkGetPipelineExecutableStatisticsKHR");
+    if (table->GetPipelineExecutableStatisticsKHR == nullptr) { table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)StubGetPipelineExecutableStatisticsKHR; }
+    table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR) gpa(device, "vkGetPipelineExecutableInternalRepresentationsKHR");
+    if (table->GetPipelineExecutableInternalRepresentationsKHR == nullptr) { table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)StubGetPipelineExecutableInternalRepresentationsKHR; }
     table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT) gpa(device, "vkDebugMarkerSetObjectTagEXT");
     if (table->DebugMarkerSetObjectTagEXT == nullptr) { table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)StubDebugMarkerSetObjectTagEXT; }
     table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT) gpa(device, "vkDebugMarkerSetObjectNameEXT");
@@ -634,6 +644,8 @@
     table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT) gpa(device, "vkGetDeviceGroupSurfacePresentModes2EXT");
     if (table->GetDeviceGroupSurfacePresentModes2EXT == nullptr) { table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)StubGetDeviceGroupSurfacePresentModes2EXT; }
 #endif // VK_USE_PLATFORM_WIN32_KHR
+    table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT) gpa(device, "vkCmdSetLineStippleEXT");
+    if (table->CmdSetLineStippleEXT == nullptr) { table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)StubCmdSetLineStippleEXT; }
     table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT) gpa(device, "vkResetQueryPoolEXT");
     if (table->ResetQueryPoolEXT == nullptr) { table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)StubResetQueryPoolEXT; }
 #ifdef VK_USE_PLATFORM_FUCHSIA
diff --git a/loader/generated/vk_layer_dispatch_table.h b/loader/generated/vk_layer_dispatch_table.h
index 54c8658..c45b0e0 100644
--- a/loader/generated/vk_layer_dispatch_table.h
+++ b/loader/generated/vk_layer_dispatch_table.h
@@ -470,6 +470,11 @@
     PFN_vkCmdDrawIndirectCountKHR CmdDrawIndirectCountKHR;
     PFN_vkCmdDrawIndexedIndirectCountKHR CmdDrawIndexedIndirectCountKHR;
 
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    PFN_vkGetPipelineExecutablePropertiesKHR GetPipelineExecutablePropertiesKHR;
+    PFN_vkGetPipelineExecutableStatisticsKHR GetPipelineExecutableStatisticsKHR;
+    PFN_vkGetPipelineExecutableInternalRepresentationsKHR GetPipelineExecutableInternalRepresentationsKHR;
+
     // ---- VK_EXT_debug_marker extension commands
     PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
     PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
@@ -631,6 +636,9 @@
     PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    PFN_vkCmdSetLineStippleEXT CmdSetLineStippleEXT;
+
     // ---- VK_EXT_host_query_reset extension commands
     PFN_vkResetQueryPoolEXT ResetQueryPoolEXT;
 
diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c
index 08006c9..1fbd17e 100644
--- a/loader/generated/vk_loader_extensions.c
+++ b/loader/generated/vk_loader_extensions.c
@@ -527,6 +527,11 @@
     table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)gdpa(dev, "vkCmdDrawIndirectCountKHR");
     table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)gdpa(dev, "vkCmdDrawIndexedIndirectCountKHR");
 
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)gdpa(dev, "vkGetPipelineExecutablePropertiesKHR");
+    table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)gdpa(dev, "vkGetPipelineExecutableStatisticsKHR");
+    table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)gdpa(dev, "vkGetPipelineExecutableInternalRepresentationsKHR");
+
     // ---- VK_EXT_debug_marker extension commands
     table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gdpa(dev, "vkDebugMarkerSetObjectTagEXT");
     table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gdpa(dev, "vkDebugMarkerSetObjectNameEXT");
@@ -688,6 +693,9 @@
     table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gdpa(dev, "vkGetDeviceGroupSurfacePresentModes2EXT");
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)gdpa(dev, "vkCmdSetLineStippleEXT");
+
     // ---- VK_EXT_host_query_reset extension commands
     table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)gdpa(dev, "vkResetQueryPoolEXT");
 
@@ -1171,6 +1179,11 @@
     if (!strcmp(name, "CmdDrawIndirectCountKHR")) return (void *)table->CmdDrawIndirectCountKHR;
     if (!strcmp(name, "CmdDrawIndexedIndirectCountKHR")) return (void *)table->CmdDrawIndexedIndirectCountKHR;
 
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    if (!strcmp(name, "GetPipelineExecutablePropertiesKHR")) return (void *)table->GetPipelineExecutablePropertiesKHR;
+    if (!strcmp(name, "GetPipelineExecutableStatisticsKHR")) return (void *)table->GetPipelineExecutableStatisticsKHR;
+    if (!strcmp(name, "GetPipelineExecutableInternalRepresentationsKHR")) return (void *)table->GetPipelineExecutableInternalRepresentationsKHR;
+
     // ---- VK_EXT_debug_marker extension commands
     if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) return (void *)table->DebugMarkerSetObjectTagEXT;
     if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) return (void *)table->DebugMarkerSetObjectNameEXT;
@@ -1332,6 +1345,9 @@
     if (!strcmp(name, "GetDeviceGroupSurfacePresentModes2EXT")) return (void *)table->GetDeviceGroupSurfacePresentModes2EXT;
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    if (!strcmp(name, "CmdSetLineStippleEXT")) return (void *)table->CmdSetLineStippleEXT;
+
     // ---- VK_EXT_host_query_reset extension commands
     if (!strcmp(name, "ResetQueryPoolEXT")) return (void *)table->ResetQueryPoolEXT;
 
@@ -1951,6 +1967,36 @@
 }
 
 
+// ---- VK_KHR_pipeline_executable_properties extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutablePropertiesKHR(
+    VkDevice                                    device,
+    const VkPipelineInfoKHR*                    pPipelineInfo,
+    uint32_t*                                   pExecutableCount,
+    VkPipelineExecutablePropertiesKHR*          pProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableStatisticsKHR(
+    VkDevice                                    device,
+    const VkPipelineExecutableInfoKHR*          pExecutableInfo,
+    uint32_t*                                   pStatisticCount,
+    VkPipelineExecutableStatisticKHR*           pStatistics) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableInternalRepresentationsKHR(
+    VkDevice                                    device,
+    const VkPipelineExecutableInfoKHR*          pExecutableInfo,
+    uint32_t*                                   pInternalRepresentationCount,
+    VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    return disp->GetPipelineExecutableInternalRepresentationsKHR(device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations);
+}
+
+
 // ---- VK_EXT_debug_marker extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(
@@ -3154,6 +3200,17 @@
 
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+// ---- VK_EXT_line_rasterization extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetLineStippleEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    lineStippleFactor,
+    uint16_t                                    lineStipplePattern) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    disp->CmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern);
+}
+
+
 // ---- VK_EXT_host_query_reset extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL ResetQueryPoolEXT(
@@ -3550,6 +3607,20 @@
         return true;
     }
 
+    // ---- VK_KHR_pipeline_executable_properties extension commands
+    if (!strcmp("vkGetPipelineExecutablePropertiesKHR", name)) {
+        *addr = (void *)GetPipelineExecutablePropertiesKHR;
+        return true;
+    }
+    if (!strcmp("vkGetPipelineExecutableStatisticsKHR", name)) {
+        *addr = (void *)GetPipelineExecutableStatisticsKHR;
+        return true;
+    }
+    if (!strcmp("vkGetPipelineExecutableInternalRepresentationsKHR", name)) {
+        *addr = (void *)GetPipelineExecutableInternalRepresentationsKHR;
+        return true;
+    }
+
     // ---- VK_EXT_debug_marker extension commands
     if (!strcmp("vkDebugMarkerSetObjectTagEXT", name)) {
         *addr = (void *)DebugMarkerSetObjectTagEXT;
@@ -4096,6 +4167,12 @@
     }
 #endif // VK_USE_PLATFORM_WIN32_KHR
 
+    // ---- VK_EXT_line_rasterization extension commands
+    if (!strcmp("vkCmdSetLineStippleEXT", name)) {
+        *addr = (void *)CmdSetLineStippleEXT;
+        return true;
+    }
+
     // ---- VK_EXT_host_query_reset extension commands
     if (!strcmp("vkResetQueryPoolEXT", name)) {
         *addr = (void *)ResetQueryPoolEXT;
diff --git a/loader/loader.c b/loader/loader.c
index d19fb4d..57d43b3 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -66,11 +66,12 @@
 #include "murmurhash.h"
 
 #if defined(_WIN32)
-#include <Cfgmgr32.h>
+#include <cfgmgr32.h>
 #include <initguid.h>
-#include <Devpkey.h>
+#include <devpkey.h>
 #include <winternl.h>
 #include <d3dkmthk.h>
+#include "dxgi_loader.h"
 
 typedef _Check_return_ NTSTATUS (APIENTRY *PFN_D3DKMTEnumAdapters2)(const D3DKMT_ENUMADAPTERS2*);
 typedef _Check_return_ NTSTATUS (APIENTRY *PFN_D3DKMTQueryAdapterInfo)(const D3DKMT_QUERYADAPTERINFO*);
@@ -242,6 +243,10 @@
 // Environment variables
 #if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__)
 
+static inline bool IsHighIntegrity() {
+    return geteuid() != getuid() || getegid() != getgid();
+}
+
 static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
     // No allocation of memory necessary for Linux, but we should at least touch
     // the inst pointer to get rid of compiler warnings.
@@ -258,7 +263,7 @@
     // that can do damage.
     // This algorithm is derived from glibc code that sets an internal
     // variable (__libc_enable_secure) if the process is running under setuid or setgid.
-    return geteuid() != getuid() || getegid() != getgid() ? NULL : loader_getenv(name, inst);
+    return IsHighIntegrity() ? NULL : loader_getenv(name, inst);
 #elif defined(__Fuchsia__)
     return loader_getenv(name, inst);
 #else
@@ -287,6 +292,28 @@
 
 #elif defined(WIN32)
 
+static inline bool IsHighIntegrity() {
+    HANDLE process_token;
+    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
+        // Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
+        uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
+        DWORD buffer_size;
+        if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
+            &buffer_size) != 0) {
+            const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
+            const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
+            const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
+
+            CloseHandle(process_token);
+            return integrity_level > SECURITY_MANDATORY_MEDIUM_RID;
+        }
+
+        CloseHandle(process_token);
+    }
+
+    return false;
+}
+
 static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
     char *retVal;
     DWORD valSize;
@@ -313,7 +340,10 @@
 }
 
 static inline char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
-    // No secure version for Windows as far as I know
+    if (IsHighIntegrity()) {
+        return NULL;
+    }
+
     return loader_getenv(name, inst);
 }
 
@@ -781,6 +811,49 @@
 // When done using the returned string list, the caller should free the pointer.
 VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *location, bool use_secondary_hive, char **reg_data,
                                 PDWORD reg_data_size) {
+    // This list contains all of the allowed ICDs. This allows us to verify that a device is actually present from the vendor
+    // specified. This does disallow other vendors, but any new driver should use the device-specific registries anyway.
+    static const struct {
+        const char *filename;
+        int vendor_id;
+    } known_drivers[] = {
+#if defined(_WIN64)
+        {
+            .filename = "igvk64.json",
+            .vendor_id = 0x8086,
+        },
+        {
+            .filename = "nv-vk64.json",
+            .vendor_id = 0x10de,
+        },
+        {
+            .filename = "amd-vulkan64.json",
+            .vendor_id = 0x1002,
+        },
+        {
+            .filename = "amdvlk64.json",
+            .vendor_id = 0x1002,
+        },
+#else
+        {
+            .filename = "igvk32.json",
+            .vendor_id = 0x8086,
+        },
+        {
+            .filename = "nv-vk32.json",
+            .vendor_id = 0x10de,
+        },
+        {
+            .filename = "amd-vulkan32.json",
+            .vendor_id = 0x1002,
+        },
+        {
+            .filename = "amdvlk32.json",
+            .vendor_id = 0x1002,
+        },
+#endif
+    };
+
     LONG rtn_value;
     HKEY hive = DEFAULT_VK_REGISTRY_HIVE, key;
     DWORD access_flags;
@@ -793,12 +866,25 @@
     DWORD value_size = sizeof(value);
     VkResult result = VK_SUCCESS;
     bool found = false;
+    IDXGIFactory1 *dxgi_factory = NULL;
+    bool is_driver = !strcmp(location, VK_DRIVERS_INFO_REGISTRY_LOC);
 
     if (NULL == reg_data) {
         result = VK_ERROR_INITIALIZATION_FAILED;
         goto out;
     }
 
+    if (is_driver) {
+        HRESULT hres = dyn_CreateDXGIFactory1(&IID_IDXGIFactory1, &dxgi_factory);
+        if (hres != S_OK) {
+            loader_log(
+                inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                "loaderGetRegistryFiles: Failed to create dxgi factory for ICD registry verification. No ICDs will be added from "
+                "legacy registry locations");
+            goto out;
+        }
+    }
+
     while (*loc) {
         next = loader_get_next_path(loc);
         access_flags = KEY_QUERY_VALUE;
@@ -833,9 +919,59 @@
                         *reg_data = new_ptr;
                         *reg_data_size *= 2;
                     }
+
+                    // We've now found a json file. If this is an ICD, we still need to check if there is actually a device
+                    // that matches this ICD
                     loader_log(
                         inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Located json file \"%s\" from registry \"%s\\%s\"", name,
                         hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR, location);
+                    if (is_driver) {
+                        int i;
+                        for (i = 0; i < sizeof(known_drivers) / sizeof(known_drivers[0]); ++i) {
+                            if (!strcmp(name + strlen(name) - strlen(known_drivers[i].filename), known_drivers[i].filename)) {
+                                break;
+                            }
+                        }
+                        if (i == sizeof(known_drivers) / sizeof(known_drivers[0])) {
+                            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                                       "Dropping driver %s as it was not recognized as a known driver", name);
+                            continue;
+                        }
+
+                        bool found_gpu = false;
+                        for (int j = 0;; ++j) {
+                            IDXGIAdapter1 *adapter;
+                            HRESULT hres = dxgi_factory->lpVtbl->EnumAdapters1(dxgi_factory, j, &adapter);
+                            if (hres == DXGI_ERROR_NOT_FOUND) {
+                                break;
+                            } else if (hres != S_OK) {
+                                loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                                           "Failed to enumerate DXGI adapters at index %d. As a result, drivers may be skipped", j);
+                                continue;
+                            }
+
+                            DXGI_ADAPTER_DESC1 description;
+                            hres = adapter->lpVtbl->GetDesc1(adapter, &description);
+                            if (hres != S_OK) {
+                                loader_log(
+                                    inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                                    "Failed to get DXGI adapter information at index %d. As a result, drivers may be skipped", j);
+                                continue;
+                            }
+
+                            if (description.VendorId == known_drivers[i].vendor_id) {
+                                found_gpu = true;
+                                break;
+                            }
+                        }
+
+                        if (!found_gpu) {
+                            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                                       "Dropping driver %s as no corresponduing DXGI adapter was found", name);
+                            continue;
+                        }
+                    }
+
                     if (strlen(*reg_data) == 0) {
                         // The list is emtpy. Add the first entry.
                         (void)snprintf(*reg_data, name_size + 1, "%s", name);
@@ -888,6 +1024,9 @@
     }
 
 out:
+    if (is_driver && dxgi_factory != NULL) {
+        dxgi_factory->lpVtbl->Release(dxgi_factory);
+    }
 
     return result;
 }
@@ -3706,8 +3845,10 @@
             search_path_size += DetermineDataFilePathSize(EXTRASYSCONFDIR, rel_size);
 #endif
             if (is_directory_list) {
-                search_path_size += DetermineDataFilePathSize(xdgdatahome, rel_size);
-                search_path_size += DetermineDataFilePathSize(home_root, rel_size);
+                if (!IsHighIntegrity()) {
+                    search_path_size += DetermineDataFilePathSize(xdgdatahome, rel_size);
+                    search_path_size += DetermineDataFilePathSize(home_root, rel_size);
+                }
             }
 #endif
         }
@@ -3951,7 +4092,6 @@
                                         bool warn_if_not_present, char *registry_location, struct loader_data_files *out_files) {
     VkResult vk_result = VK_SUCCESS;
     bool is_icd = (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD);
-    bool use_secondary_hive = data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER;
     char *search_path = NULL;
 
     // These calls look at the PNP/Device section of the registry.
@@ -3976,6 +4116,7 @@
     }
 
     // This call looks into the Khronos non-device specific section of the registry.
+    bool use_secondary_hive = (data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER) && (!IsHighIntegrity());
     VkResult reg_result = loaderGetRegistryFiles(inst, registry_location, use_secondary_hive, &search_path, &reg_size);
 
     if ((VK_SUCCESS != reg_result && VK_SUCCESS != regHKR_result) || NULL == search_path) {
@@ -6144,16 +6285,18 @@
 
         // Get the driver version from vkEnumerateInstanceVersion
         uint32_t icd_version = VK_API_VERSION_1_0;
-        PFN_vkEnumerateInstanceVersion icd_enumerate_instance_version = (PFN_vkEnumerateInstanceVersion)
-            icd_term->scanned_icd->GetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
         VkResult icd_result = VK_SUCCESS;
-        if (icd_enumerate_instance_version != NULL) {
-            icd_result = icd_enumerate_instance_version(&icd_version);
-            if (icd_result != VK_SUCCESS) {
-                icd_version = VK_API_VERSION_1_0;
-                loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "terminator_CreateInstance: ICD \"%s\" "
-                    "vkEnumerateInstanceVersion returned error. The ICD will be treated as a 1.0 ICD",
-                    icd_term->scanned_icd->lib_name);
+        if (icd_term->scanned_icd->api_version >= VK_API_VERSION_1_1) {
+            PFN_vkEnumerateInstanceVersion icd_enumerate_instance_version = (PFN_vkEnumerateInstanceVersion)
+                icd_term->scanned_icd->GetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+            if (icd_enumerate_instance_version != NULL) {
+                icd_result = icd_enumerate_instance_version(&icd_version);
+                if (icd_result != VK_SUCCESS) {
+                    icd_version = VK_API_VERSION_1_0;
+                    loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "terminator_CreateInstance: ICD \"%s\" "
+                        "vkEnumerateInstanceVersion returned error. The ICD will be treated as a 1.0 ICD",
+                        icd_term->scanned_icd->lib_name);
+                }
             }
         }
 
@@ -7105,7 +7248,7 @@
 terminator_EnumerateInstanceVersion(const VkEnumerateInstanceVersionChain *chain, uint32_t* pApiVersion) {
     // NOTE: The Vulkan WG doesn't want us checking pApiVersion for NULL, but instead
     // prefers us crashing.
-    *pApiVersion = VK_MAKE_VERSION(loader_major_version, loader_minor_version, 0);
+    *pApiVersion = VK_MAKE_VERSION(loader_major_version, loader_minor_version, VK_HEADER_VERSION);
     return VK_SUCCESS;
 }
 
diff --git a/loader/unknown_ext_chain_gas.asm b/loader/unknown_ext_chain_gas.S
similarity index 98%
rename from loader/unknown_ext_chain_gas.asm
rename to loader/unknown_ext_chain_gas.S
index aca92ea..f847e14 100644
--- a/loader/unknown_ext_chain_gas.asm
+++ b/loader/unknown_ext_chain_gas.S
@@ -23,6 +23,12 @@
 # VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then
 # jump to the next function in the call chain
 
+#ifdef HAVE_CET_H
+#include <cet.h>
+#else
+#define _CET_ENDBR
+#endif
+
 .intel_syntax noprefix
 .include "gen_defines.asm"
 
@@ -31,6 +37,7 @@
 .macro PhysDevExtTramp num
 .global vkPhysDevExtTramp\num
 vkPhysDevExtTramp\num:
+    _CET_ENDBR
     mov     rax, [rdi]
     mov     rdi, [rdi + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP]
     jmp     [rax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num))]
@@ -39,6 +46,7 @@
 .macro PhysDevExtTermin num
 .global vkPhysDevExtTermin\num
 vkPhysDevExtTermin\num:
+    _CET_ENDBR
     mov     rax, [rdi + ICD_TERM_OFFSET_PHYS_DEV_TERM]                          # Store the loader_icd_term* in rax
     cmp     qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL
     je      terminError\num                                                     # Go to the error section if it is NULL
@@ -60,6 +68,7 @@
 .macro DevExtTramp num
 .global vkdev_ext\num
 vkdev_ext\num:
+    _CET_ENDBR
     mov     rax, [rdi]                                                          # Dereference the handle to get the dispatch table
     jmp     [rax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))]            # Jump to the appropriate call chain
 .endm
@@ -69,6 +78,7 @@
 .macro PhysDevExtTramp num
 .global vkPhysDevExtTramp\num
 vkPhysDevExtTramp\num:
+    _CET_ENDBR
     mov     eax, [esp + 4]                              # Load the wrapped VkPhysicalDevice into eax
     mov     ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] # Load the unwrapped VkPhysicalDevice into ecx
     mov     [esp + 4], ecx                              # Overwrite the wrapped VkPhysicalDevice with the unwrapped one (on the stack)
@@ -79,6 +89,7 @@
 .macro PhysDevExtTermin num
 .global vkPhysDevExtTermin\num
 vkPhysDevExtTermin\num:
+    _CET_ENDBR
     mov     ecx, [esp + 4]                                                      # Move the wrapped VkPhysicalDevice into ecx
     mov     eax, [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM]                          # Store the loader_icd_term* in eax
     cmp     dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL
@@ -102,6 +113,7 @@
 .macro DevExtTramp num
 .global vkdev_ext\num
 vkdev_ext\num:
+    _CET_ENDBR
     mov     eax, [esp + 4]                                                      # Dereference the handle to get the dispatch table
     jmp     [eax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))]            # Jump to the appropriate call chain
 .endm
diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h
index 7ab99f5..c76fd7e 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -25,7 +25,7 @@
 
 #if defined(_WIN32)
 // WinSock2.h must be included *BEFORE* windows.h
-#include <WinSock2.h>
+#include <winsock2.h>
 #endif  // _WIN32
 
 #if defined(__Fuchsia__)
diff --git a/scripts/known_good.json b/scripts/known_good.json
index 64d3840..28e94ea 100644
--- a/scripts/known_good.json
+++ b/scripts/known_good.json
@@ -6,7 +6,7 @@
       "sub_dir" : "Vulkan-Headers",
       "build_dir" : "Vulkan-Headers/build",
       "install_dir" : "Vulkan-Headers/build/install",
-      "commit" : "v1.1.115"
+      "commit" : "v1.1.121"
     }
   ],
   "install_names" : {