162 changes: 162 additions & 0 deletions bolt/test/X86/match-functions-with-calls-as-anchors.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
## Tests blocks matching by called function names in inferStaleProfile.

# REQUIRES: system-linux
# RUN: split-file %s %t
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o
# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
# RUN: llvm-bolt %t.exe -o %t.out --data %t/yaml --profile-ignore-hash -v=1 \
# RUN: --dyno-stats --print-cfg --infer-stale-profile=1 --debug 2>&1 | FileCheck %s

# CHECK: BOLT-INFO: applying profile inference for "qux"
# CHECK: Matched yaml block (bid = 1) with hash 4 to BB (index = 0) with hash 314e1bc10000
# CHECK: loose match

# CHECK: BOLT-INFO: applying profile inference for "fred"
# CHECK: Matched yaml block (bid = 1) with hash 5 to BB (index = 0) with hash 7541bc10000
# CHECK: loose match

#--- main.s
.globl foo # -- Begin function foo
.p2align 4, 0x90
.type foo,@function
foo: # @foo
# %bb.0:
pushq %rbp
movq %rsp, %rbp
popq %rbp
retq
.Lfunc_end0:
.size foo, .Lfunc_end0-foo
# -- End function
.globl bar # -- Begin function bar
.p2align 4, 0x90
.type bar,@function
bar: # @bar
# %bb.0:
pushq %rbp
movq %rsp, %rbp
popq %rbp
retq
.Lfunc_end1:
.size bar, .Lfunc_end1-bar
# -- End function
.globl qux # -- Begin function qux
.p2align 4, 0x90
.type qux,@function
qux: # @qux
# %bb.0:
pushq %rbp
movq %rsp, %rbp
callq foo
callq bar
popq %rbp
retq
.Lfunc_end2:
.size qux, .Lfunc_end2-qux
# -- End function
.globl fred # -- Begin function fred
.p2align 4, 0x90
.type fred,@function
fred: # @fred
# %bb.0:
pushq %rbp
movq %rsp, %rbp
callq foo
callq qux
callq bar
callq bar
callq foo
popq %rbp
retq
.Lfunc_end3:
.size fred, .Lfunc_end3-fred
# -- End function
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
# %bb.0:
pushq %rbp
movq %rsp, %rbp
xorl %eax, %eax
popq %rbp
retq
.Lfunc_end4:
.size main, .Lfunc_end4-main
# -- End function
.addrsig
.addrsig_sym foo
.addrsig_sym bar
.addrsig_sym qux

#--- yaml
---
header:
profile-version: 1
binary-name: 'match-functions-with-calls-as-anchors.s.tmp.exe'
binary-build-id: '<unknown>'
profile-flags: [ lbr ]
profile-origin: branch profile reader
profile-events: ''
dfs-order: false
hash-func: xxh3
functions:
- name: main
fid: 0
hash: 0x0000000000000001
exec: 1
nblocks: 6
blocks:
- bid: 1
hash: 0x0000000000000001
insns: 1
succ: [ { bid: 3, cnt: 1} ]
- name: foo
fid: 1
hash: 0x0000000000000002
exec: 1
nblocks: 6
blocks:
- bid: 1
hash: 0x0000000000000002
insns: 1
succ: [ { bid: 3, cnt: 1} ]

- name: bar
fid: 2
hash: 0x0000000000000003
exec: 1
nblocks: 6
blocks:
- bid: 1
hash: 0x0000000000000003
insns: 1
succ: [ { bid: 3, cnt: 1} ]
- name: qux
fid: 3
hash: 0x0000000000000004
exec: 4
nblocks: 6
blocks:
- bid: 1
hash: 0x0000000000000004
insns: 1
succ: [ { bid: 3, cnt: 1} ]
calls: [ { off : 0, fid : 1, cnt : 0},
{ off : 0, fid : 2, cnt : 0} ]
- name: fred
fid: 4
hash: 0x0000000000000005
exec: 1
nblocks: 6
blocks:
- bid: 1
hash: 0x0000000000000005
insns: 1
succ: [ { bid: 3, cnt: 1} ]
calls: [ { off : 0, fid : 3, cnt : 0},
{ off : 0, fid : 1, cnt : 0},
{ off : 0, fid : 2, cnt : 0},
{ off : 0, fid : 1, cnt : 0},
{ off : 0, fid : 2, cnt : 0} ]
...
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/HLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
static std::optional<std::string> parseTargetProfile(StringRef TargetProfile);
bool requiresValidation(llvm::opt::DerivedArgList &Args) const;

// Set default DWARF version to 4 for DXIL uses version 4.
unsigned GetDefaultDwarfVersion() const override { return 4; }

private:
mutable std::unique_ptr<tools::hlsl::Validator> Validator;
};
Expand Down
3 changes: 2 additions & 1 deletion clang/test/Driver/dxc_debug.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
// CHECK: "-cc1"
// CHECK-CV-SAME: -gcodeview
// CHECK-SAME: "-debug-info-kind=constructor"
// CHECK-DWARF-SAME: -dwarf-version
// Make sure dwarf-version is 4.
// CHECK-DWARF-SAME: -dwarf-version=4
14 changes: 7 additions & 7 deletions compiler-rt/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,13 @@ else()
set(COMPILER_RT_HAS_ASAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux|Android|Fuchsia")
set(COMPILER_RT_HAS_HWASAN TRUE)
else()
set(COMPILER_RT_HAS_HWASAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND RTSAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Darwin|Linux")
set(COMPILER_RT_HAS_RTSAN TRUE)
Expand Down Expand Up @@ -787,13 +794,6 @@ else()
set(COMPILER_RT_HAS_MSAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux|Android|Fuchsia")
set(COMPILER_RT_HAS_HWASAN TRUE)
else()
set(COMPILER_RT_HAS_HWASAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND MEMPROF_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux")
set(COMPILER_RT_HAS_MEMPROF TRUE)
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ endif()
if(COMPILER_RT_BUILD_SANITIZERS)
if(COMPILER_RT_HAS_SANITIZER_COMMON)
add_subdirectory(stats)
compiler_rt_build_runtime(lsan)
compiler_rt_build_runtime(ubsan)
# Contains RTLSanCommon used even without COMPILER_RT_HAS_LSAN.
add_subdirectory(lsan)
# Contains RTUbsan used even without COMPILER_RT_HAS_UBSAN.
add_subdirectory(lsan)
endif()

foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD})
Expand Down
69 changes: 36 additions & 33 deletions compiler-rt/lib/lsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,51 +36,54 @@ set(LSAN_HEADERS

set(LSAN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})

# Used by asan/hwasan even without COMPILER_RT_HAS_LSAN.
add_compiler_rt_object_libraries(RTLSanCommon
OS ${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${LSAN_COMMON_SUPPORTED_ARCH}
SOURCES ${LSAN_COMMON_SOURCES}
ADDITIONAL_HEADERS ${LSAN_HEADERS}
CFLAGS ${LSAN_CFLAGS})

add_compiler_rt_component(lsan)
if(APPLE)
set(LSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
if(COMPILER_RT_HAS_LSAN)
add_compiler_rt_component(lsan)
if(APPLE)
set(LSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})

add_weak_symbols("lsan" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("lsan" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)

add_compiler_rt_runtime(clang_rt.lsan
SHARED
OS ${LSAN_SUPPORTED_OS}
ARCHS ${LSAN_SUPPORTED_ARCH}
SOURCES ${LSAN_SOURCES}
ADDITIONAL_HEADERS ${LSAN_HEADERS}
OBJECT_LIBS RTLSanCommon
RTInterception
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
CFLAGS ${LSAN_CFLAGS}
LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
LINK_LIBS ${LSAN_LINK_LIBS}
PARENT_TARGET lsan)
else()
foreach(arch ${LSAN_SUPPORTED_ARCH})
add_compiler_rt_runtime(clang_rt.lsan
STATIC
ARCHS ${arch}
SHARED
OS ${LSAN_SUPPORTED_OS}
ARCHS ${LSAN_SUPPORTED_ARCH}
SOURCES ${LSAN_SOURCES}
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
ADDITIONAL_HEADERS ${LSAN_HEADERS}
OBJECT_LIBS RTLSanCommon
RTInterception
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
CFLAGS ${LSAN_CFLAGS}
LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
LINK_LIBS ${LSAN_LINK_LIBS}
PARENT_TARGET lsan)
endforeach()
else()
foreach(arch ${LSAN_SUPPORTED_ARCH})
add_compiler_rt_runtime(clang_rt.lsan
STATIC
ARCHS ${arch}
SOURCES ${LSAN_SOURCES}
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
ADDITIONAL_HEADERS ${LSAN_HEADERS}
CFLAGS ${LSAN_CFLAGS}
PARENT_TARGET lsan)
endforeach()
endif()
endif()
212 changes: 108 additions & 104 deletions compiler-rt/lib/ubsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,45 +92,47 @@ if(APPLE)
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
CFLAGS ${UBSAN_CXXFLAGS})

# Initializer of standalone UBSan runtime.
add_compiler_rt_object_libraries(RTUbsan_standalone
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ${UBSAN_STANDALONE_SOURCES}
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
CFLAGS ${UBSAN_STANDALONE_CFLAGS})

add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
if(COMPILER_RT_HAS_UBSAN)
# Initializer of standalone UBSan runtime.
add_compiler_rt_object_libraries(RTUbsan_standalone
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ${UBSAN_STANDALONE_SOURCES}
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
CFLAGS ${UBSAN_STANDALONE_CFLAGS})

add_compiler_rt_runtime(clang_rt.ubsan
SHARED
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan
RTUbsan_standalone
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
RTInterception
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
PARENT_TARGET ubsan)
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)

if (NOT APPLE)
add_compiler_rt_runtime(clang_rt.ubsan
STATIC
SHARED
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan
RTUbsan_standalone
RTSanitizerCommonNoHooks
RTSanitizerCommonLibcNoHooks
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizerNoHooks
RTSanitizerCommonSymbolizer
RTInterception
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
PARENT_TARGET ubsan)

if (NOT APPLE)
add_compiler_rt_runtime(clang_rt.ubsan
STATIC
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan
RTUbsan_standalone
RTSanitizerCommonNoHooks
RTSanitizerCommonLibcNoHooks
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizerNoHooks
RTInterception
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
PARENT_TARGET ubsan)
endif()
endif()

else()
Expand Down Expand Up @@ -188,89 +190,91 @@ else()
DEFS ${UBSAN_COMMON_DEFINITIONS})
endif()

add_compiler_rt_object_libraries(RTUbsan_standalone
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ${UBSAN_STANDALONE_SOURCES}
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
CFLAGS ${UBSAN_STANDALONE_CFLAGS})

# Standalone UBSan runtimes.
add_compiler_rt_runtime(clang_rt.ubsan_standalone
STATIC
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES
ubsan_init_standalone_preinit.cpp
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
RTSanitizerCommonSymbolizerInternal
RTUbsan
RTUbsan_standalone
RTInterception
CFLAGS ${UBSAN_CFLAGS}
PARENT_TARGET ubsan)

add_compiler_rt_runtime(clang_rt.ubsan_standalone_cxx
STATIC
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_cxx
CFLAGS ${UBSAN_CXXFLAGS}
PARENT_TARGET ubsan)

if (COMPILER_RT_HAS_VERSION_SCRIPT)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
add_compiler_rt_object_libraries(RTUbsan_dynamic_version_script_dummy
if(COMPILER_RT_HAS_UBSAN)
add_compiler_rt_object_libraries(RTUbsan_standalone
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ${UBSAN_STANDALONE_SOURCES}
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
CFLAGS ${UBSAN_STANDALONE_CFLAGS})

# Standalone UBSan runtimes.
add_compiler_rt_runtime(clang_rt.ubsan_standalone
STATIC
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
CFLAGS ${UBSAN_CFLAGS})

foreach(arch ${UBSAN_SUPPORTED_ARCH})
add_sanitizer_rt_version_list(clang_rt.ubsan_standalone-dynamic-${arch}
LIBS clang_rt.ubsan_standalone-${arch}
clang_rt.ubsan_standalone_cxx-${arch}
EXTRA ubsan.syms.extra)
set(VERSION_SCRIPT_FLAG
-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.ubsan_standalone-dynamic-${arch}.vers)
# The Solaris 11.4 linker supports a subset of GNU ld version scripts,
# but requires a special option to enable it.
if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
endif()
set_property(SOURCE
${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
APPEND PROPERTY
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.ubsan_standalone-dynamic-${arch}.vers)

add_compiler_rt_runtime(clang_rt.ubsan_standalone
SHARED
ARCHS ${arch}
OBJECT_LIBS RTSanitizerCommon
SOURCES
ubsan_init_standalone_preinit.cpp
ADDITIONAL_HEADERS ${UBSAN_HEADERS}
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
RTSanitizerCommonSymbolizerInternal
RTUbsan
RTUbsan_cxx
RTUbsan_standalone
RTInterception
RTUbsan_dynamic_version_script_dummy
CFLAGS ${UBSAN_CFLAGS}
LINK_FLAGS ${UBSAN_LINK_FLAGS} ${VERSION_SCRIPT_FLAG}
LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
PARENT_TARGET ubsan)
endforeach()

set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386)
add_sanitizer_rt_symbols(clang_rt.ubsan_standalone
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan
EXTRA ubsan.syms.extra)
add_sanitizer_rt_symbols(clang_rt.ubsan_standalone_cxx
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan
EXTRA ubsan.syms.extra)
CFLAGS ${UBSAN_CFLAGS}
PARENT_TARGET ubsan)

add_compiler_rt_runtime(clang_rt.ubsan_standalone_cxx
STATIC
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_cxx
CFLAGS ${UBSAN_CXXFLAGS}
PARENT_TARGET ubsan)

if (COMPILER_RT_HAS_VERSION_SCRIPT)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
add_compiler_rt_object_libraries(RTUbsan_dynamic_version_script_dummy
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
CFLAGS ${UBSAN_CFLAGS})

foreach(arch ${UBSAN_SUPPORTED_ARCH})
add_sanitizer_rt_version_list(clang_rt.ubsan_standalone-dynamic-${arch}
LIBS clang_rt.ubsan_standalone-${arch}
clang_rt.ubsan_standalone_cxx-${arch}
EXTRA ubsan.syms.extra)
set(VERSION_SCRIPT_FLAG
-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.ubsan_standalone-dynamic-${arch}.vers)
# The Solaris 11.4 linker supports a subset of GNU ld version scripts,
# but requires a special option to enable it.
if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
endif()
set_property(SOURCE
${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
APPEND PROPERTY
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.ubsan_standalone-dynamic-${arch}.vers)

add_compiler_rt_runtime(clang_rt.ubsan_standalone
SHARED
ARCHS ${arch}
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
RTSanitizerCommonSymbolizerInternal
RTUbsan
RTUbsan_cxx
RTUbsan_standalone
RTInterception
RTUbsan_dynamic_version_script_dummy
CFLAGS ${UBSAN_CFLAGS}
LINK_FLAGS ${UBSAN_LINK_FLAGS} ${VERSION_SCRIPT_FLAG}
LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
PARENT_TARGET ubsan)
endforeach()

set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386)
add_sanitizer_rt_symbols(clang_rt.ubsan_standalone
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan
EXTRA ubsan.syms.extra)
add_sanitizer_rt_symbols(clang_rt.ubsan_standalone_cxx
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan
EXTRA ubsan.syms.extra)
endif()
endif()
endif()
1 change: 1 addition & 0 deletions libc/src/__support/macros/sanitizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#endif

#if LIBC_HAS_FEATURE(address_sanitizer)
#define LIBC_HAVE_ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#define ASAN_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
Expand Down
26 changes: 26 additions & 0 deletions lldb/include/lldb/API/SBLanguageRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,32 @@ class SBLanguageRuntime {
static lldb::LanguageType GetLanguageTypeFromString(const char *string);

static const char *GetNameForLanguageType(lldb::LanguageType language);

/// Returns whether the given language is any version of C++.
static bool LanguageIsCPlusPlus(lldb::LanguageType language);

/// Returns whether the given language is Obj-C or Obj-C++.
static bool LanguageIsObjC(lldb::LanguageType language);

/// Returns whether the given language is any version of C, C++ or Obj-C.
static bool LanguageIsCFamily(lldb::LanguageType language);

/// Returns whether the given language supports exception breakpoints on
/// throw statements.
static bool SupportsExceptionBreakpointsOnThrow(lldb::LanguageType language);

/// Returns whether the given language supports exception breakpoints on
/// catch statements.
static bool SupportsExceptionBreakpointsOnCatch(lldb::LanguageType language);

/// Returns the keyword used for throw statements in the given language, e.g.
/// Python uses \b raise. Returns \b nullptr if the language is not supported.
static const char *GetThrowKeywordForLanguage(lldb::LanguageType language);

/// Returns the keyword used for catch statements in the given language, e.g.
/// Python uses \b except. Returns \b nullptr if the language is not
/// supported.
static const char *GetCatchKeywordForLanguage(lldb::LanguageType language);
};

} // namespace lldb
Expand Down
8 changes: 8 additions & 0 deletions lldb/include/lldb/Target/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,14 @@ class Language : public PluginInterface {
/// a corresponding LanguageRuntime plugin.
virtual bool SupportsExceptionBreakpointsOnCatch() const { return false; }

/// Returns the keyword used for throw statements in this language, e.g.
/// Python uses \b raise. Defaults to \b throw.
virtual llvm::StringRef GetThrowKeyword() const { return "throw"; }

/// Returns the keyword used for catch statements in this language, e.g.
/// Python uses \b except. Defaults to \b catch.
virtual llvm::StringRef GetCatchKeyword() const { return "catch"; }

protected:
// Classes that inherit from Language can see and modify these

Expand Down
40 changes: 40 additions & 0 deletions lldb/source/API/SBLanguageRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,43 @@ SBLanguageRuntime::GetNameForLanguageType(lldb::LanguageType language) {

return Language::GetNameForLanguageType(language);
}

bool SBLanguageRuntime::LanguageIsCPlusPlus(lldb::LanguageType language) {
return Language::LanguageIsCPlusPlus(language);
}

bool SBLanguageRuntime::LanguageIsObjC(lldb::LanguageType language) {
return Language::LanguageIsObjC(language);
}

bool SBLanguageRuntime::LanguageIsCFamily(lldb::LanguageType language) {
return Language::LanguageIsCFamily(language);
}

bool SBLanguageRuntime::SupportsExceptionBreakpointsOnThrow(
lldb::LanguageType language) {
if (Language *lang_plugin = Language::FindPlugin(language))
return lang_plugin->SupportsExceptionBreakpointsOnThrow();
return false;
}

bool SBLanguageRuntime::SupportsExceptionBreakpointsOnCatch(
lldb::LanguageType language) {
if (Language *lang_plugin = Language::FindPlugin(language))
return lang_plugin->SupportsExceptionBreakpointsOnCatch();
return false;
}

const char *
SBLanguageRuntime::GetThrowKeywordForLanguage(lldb::LanguageType language) {
if (Language *lang_plugin = Language::FindPlugin(language))
return ConstString(lang_plugin->GetThrowKeyword()).AsCString();
return nullptr;
}

const char *
SBLanguageRuntime::GetCatchKeywordForLanguage(lldb::LanguageType language) {
if (Language *lang_plugin = Language::FindPlugin(language))
return ConstString(lang_plugin->GetCatchKeyword()).AsCString();
return nullptr;
}
58 changes: 57 additions & 1 deletion lldb/tools/lldb-dap/DAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,17 @@ DAP::DAP()

DAP::~DAP() = default;

/// Return string with first character capitalized.
static std::string capitalize(llvm::StringRef str) {
if (str.empty())
return "";
return ((llvm::Twine)llvm::toUpper(str[0]) + str.drop_front()).str();
}

void DAP::PopulateExceptionBreakpoints() {
llvm::call_once(init_exception_breakpoints_flag, [this]() {
exception_breakpoints = std::vector<ExceptionBreakpoint> {};

if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) {
exception_breakpoints->emplace_back("cpp_catch", "C++ Catch",
lldb::eLanguageTypeC_plus_plus);
Expand All @@ -80,6 +87,49 @@ void DAP::PopulateExceptionBreakpoints() {
exception_breakpoints->emplace_back("swift_throw", "Swift Throw",
lldb::eLanguageTypeSwift);
}
// Besides handling the hardcoded list of languages from above, we try to
// find any other languages that support exception breakpoints using the
// SB API.
for (int raw_lang = lldb::eLanguageTypeUnknown;
raw_lang < lldb::eNumLanguageTypes; ++raw_lang) {
lldb::LanguageType lang = static_cast<lldb::LanguageType>(raw_lang);

// We first discard any languages already handled above.
if (lldb::SBLanguageRuntime::LanguageIsCFamily(lang) ||
lang == lldb::eLanguageTypeSwift)
continue;

if (!lldb::SBDebugger::SupportsLanguage(lang))
continue;

const char *name = lldb::SBLanguageRuntime::GetNameForLanguageType(lang);
if (!name)
continue;
std::string raw_lang_name = name;
std::string capitalized_lang_name = capitalize(name);

if (lldb::SBLanguageRuntime::SupportsExceptionBreakpointsOnThrow(lang)) {
const char *raw_throw_keyword =
lldb::SBLanguageRuntime::GetThrowKeywordForLanguage(lang);
std::string throw_keyword =
raw_throw_keyword ? raw_throw_keyword : "throw";

exception_breakpoints->emplace_back(
raw_lang_name + "_" + throw_keyword,
capitalized_lang_name + " " + capitalize(throw_keyword), lang);
}

if (lldb::SBLanguageRuntime::SupportsExceptionBreakpointsOnCatch(lang)) {
const char *raw_catch_keyword =
lldb::SBLanguageRuntime::GetCatchKeywordForLanguage(lang);
std::string catch_keyword =
raw_catch_keyword ? raw_catch_keyword : "catch";

exception_breakpoints->emplace_back(
raw_lang_name + "_" + catch_keyword,
capitalized_lang_name + " " + capitalize(catch_keyword), lang);
}
}
assert(!exception_breakpoints->empty() && "should not be empty");
});
}
Expand Down Expand Up @@ -514,6 +564,12 @@ llvm::Error DAP::RunInitCommands() {
return llvm::Error::success();
}

llvm::Error DAP::RunPreInitCommands() {
if (!RunLLDBCommands("Running preInitCommands:", pre_init_commands))
return createRunLLDBCommandsErrorMessage("preInitCommands");
return llvm::Error::success();
}

llvm::Error DAP::RunPreRunCommands() {
if (!RunLLDBCommands("Running preRunCommands:", pre_run_commands))
return createRunLLDBCommandsErrorMessage("preRunCommands");
Expand Down
2 changes: 2 additions & 0 deletions lldb/tools/lldb-dap/DAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ struct DAP {
FunctionBreakpointMap function_breakpoints;
std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
llvm::once_flag init_exception_breakpoints_flag;
std::vector<std::string> pre_init_commands;
std::vector<std::string> init_commands;
std::vector<std::string> pre_run_commands;
std::vector<std::string> post_run_commands;
Expand Down Expand Up @@ -246,6 +247,7 @@ struct DAP {

llvm::Error RunAttachCommands(llvm::ArrayRef<std::string> attach_commands);
llvm::Error RunLaunchCommands(llvm::ArrayRef<std::string> launch_commands);
llvm::Error RunPreInitCommands();
llvm::Error RunInitCommands();
llvm::Error RunPreRunCommands();
void RunPostRunCommands();
Expand Down
8 changes: 8 additions & 0 deletions lldb/tools/lldb-dap/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ def debugger_pid: S<"debugger-pid">,
def repl_mode: S<"repl-mode">,
MetaVarName<"<mode>">,
HelpText<"The mode for handling repl evaluation requests, supported modes: variable, command, auto.">;

def pre_init_command: S<"pre-init-command">,
MetaVarName<"<command>">,
HelpText<"A command to execute before the DAP initialization request and "
"right after a Debugger has been created.">;
def: Separate<["-"], "c">,
Alias<pre_init_command>,
HelpText<"Alias for --pre-init-command">;
19 changes: 16 additions & 3 deletions lldb/tools/lldb-dap/lldb-dap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,10 @@ void request_modules(const llvm::json::Object &request) {
// }]
// }
void request_initialize(const llvm::json::Object &request) {
llvm::json::Object response;
FillResponse(request, response);
llvm::json::Object body;

auto log_cb = [](const char *buf, void *baton) -> void {
g_dap.SendOutput(OutputType::Console, llvm::StringRef{buf});
};
Expand All @@ -1611,6 +1615,13 @@ void request_initialize(const llvm::json::Object &request) {
bool source_init_file = GetBoolean(arguments, "sourceInitFile", true);

g_dap.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
if (llvm::Error err = g_dap.RunPreInitCommands()) {
response["success"] = false;
EmplaceSafeString(response, "message", llvm::toString(std::move(err)));
g_dap.SendJSON(llvm::json::Value(std::move(response)));
return;
}

g_dap.PopulateExceptionBreakpoints();
auto cmd = g_dap.debugger.GetCommandInterpreter().AddMultiwordCommand(
"lldb-dap", "Commands for managing lldb-dap.");
Expand All @@ -1630,9 +1641,6 @@ void request_initialize(const llvm::json::Object &request) {
// process and more.
g_dap.event_thread = std::thread(EventThreadFunction);

llvm::json::Object response;
FillResponse(request, response);
llvm::json::Object body;
// The debug adapter supports the configurationDoneRequest.
body.try_emplace("supportsConfigurationDoneRequest", true);
// The debug adapter supports function breakpoints.
Expand Down Expand Up @@ -4318,6 +4326,11 @@ int main(int argc, char *argv[]) {
g_dap.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
}

for (const std::string &arg :
input_args.getAllArgValues(OPT_pre_init_command)) {
g_dap.pre_init_commands.push_back(arg);
}

bool CleanExit = true;
if (auto Err = g_dap.Loop()) {
if (g_dap.log)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,7 @@ void DwarfStreamer::emitLineTableRows(
LineSectionSize += /* extended op */ 1 + getULEB128Size(Size + 1) +
/* discriminator */ 1 + Size;
}
Discriminator = 0;

if (Isa != Row.Isa) {
Isa = Row.Isa;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ class DebugLineSectionEmitter {
Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);
encodeULEB128(Discriminator, Section.OS);
}
Discriminator = 0;

if (Isa != Row.Isa) {
Isa = Row.Isa;
Expand Down
2,862 changes: 1,570 additions & 1,292 deletions llvm/lib/Target/X86/X86IntrinsicsInfo.h

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions llvm/test/tools/dsymutil/ARM/discriminator.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@
;
; with -g -fdebug-info-for-profiling -O2.

RUN: dsymutil --flat --linker=classic -oso-prepend-path %p -o - \
RUN: --oso-prepend-path %p/../Inputs --verify-dwarf=none \
RUN: %p/../Inputs/discriminator.arm64.dylib | llvm-dwarfdump -debug-line - \
RUN: | FileCheck %s
RUN: dsymutil --flat --linker=classic -o - --oso-prepend-path %p/../Inputs \
RUN: --verify-dwarf=none %p/../Inputs/discriminator.arm64.dylib \
RUN: | llvm-dwarfdump -debug-line - | FileCheck %s

RUN: dsymutil --flat --linker=parallel -oso-prepend-path %p -o - \
RUN: --oso-prepend-path %p/../Inputs --verify-dwarf=none \
RUN: %p/../Inputs/discriminator.arm64.dylib | llvm-dwarfdump -debug-line - \
RUN: | FileCheck %s
RUN: dsymutil --flat --linker=parallel -o - --oso-prepend-path %p/../Inputs \
RUN: --verify-dwarf=none %p/../Inputs/discriminator.arm64.dylib \
RUN: | llvm-dwarfdump -debug-line - | FileCheck %s

CHECK: Address Line Column File ISA Discriminator OpIndex Flags
CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- -------------
CHECK-NEXT: 0x0000000000003f98 2 10 0 0 0 0 is_stmt prologue_end
CHECK-NEXT: 0x0000000000003fa4 2 3 0 0 6 0
CHECK-NEXT: 0x0000000000003fa8 2 3 0 0 0 0 end_sequence
CHECK-NEXT: 0x0000000000003fa8 2 3 0 0 6 0 end_sequence
51 changes: 51 additions & 0 deletions llvm/test/tools/dsymutil/ARM/discriminator_repeated.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
; The input at Inputs/discriminator_repeated.arm64.* were
; produced by compiling
;
; void loop(int X, int Y, unsigned int **A, unsigned int **B, unsigned int **C) {
; for (int i = 0; i < X; i++)
; for (int j = 0; j < Y; j++)
; C[i][j] += A[i][j] + B[i][j];
; }
;
; with -g -fdebug-info-for-profiling -O2.

RUN: dsymutil --flat --linker=classic -o - --oso-prepend-path %p/../Inputs \
RUN: --verify-dwarf=none %p/../Inputs/discriminator_repeated.arm64.dylib \
RUN: | llvm-dwarfdump -debug-line - | FileCheck %s

RUN: dsymutil --flat --linker=parallel -o - --oso-prepend-path %p/../Inputs \
RUN: --verify-dwarf=none %p/../Inputs/discriminator_repeated.arm64.dylib \
RUN: | llvm-dwarfdump -debug-line - | FileCheck %s

CHECK: Address Line Column File ISA Discriminator OpIndex Flags
CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------- -------------
CHECK-NEXT: 0x0000000000003e8c 2 3 0 0 2 0 is_stmt prologue_end
CHECK-NEXT: 0x0000000000003e94 0 3 0 0 0 0
CHECK-NEXT: 0x0000000000003e98 2 21 0 0 2 0
CHECK-NEXT: 0x0000000000003ea0 2 3 0 0 2 0
CHECK-NEXT: 0x0000000000003eac 2 27 0 0 4 0
CHECK-NEXT: 0x0000000000003eb0 2 3 0 0 2 0
CHECK-NEXT: 0x0000000000003eb8 3 5 0 0 2 0 is_stmt
CHECK-NEXT: 0x0000000000003ec0 0 5 0 0 0 0
CHECK-NEXT: 0x0000000000003ecc 3 5 0 0 2 0
CHECK-NEXT: 0x0000000000003ed4 0 5 0 0 0 0
CHECK-NEXT: 0x0000000000003ed8 3 5 0 0 0 0
CHECK-NEXT: 0x0000000000003eec 4 18 0 0 0 0 is_stmt
CHECK-NEXT: 0x0000000000003ef0 4 28 0 0 0 0
CHECK-NEXT: 0x0000000000003ef4 4 15 0 0 0 0
CHECK-NEXT: 0x0000000000003ef8 4 26 0 0 0 0
CHECK-NEXT: 0x0000000000003efc 4 15 0 0 0 0
CHECK-NEXT: 0x0000000000003f04 3 23 0 0 2 0 is_stmt
CHECK-NEXT: 0x0000000000003f08 3 5 0 0 2 0
CHECK-NEXT: 0x0000000000003f10 0 5 0 0 0 0
CHECK-NEXT: 0x0000000000003f14 3 5 0 0 2 0
CHECK-NEXT: 0x0000000000003f3c 3 5 0 0 0 0
CHECK-NEXT: 0x0000000000003f4c 4 18 0 0 65 0 is_stmt
CHECK-NEXT: 0x0000000000003f54 4 28 0 0 65 0
CHECK-NEXT: 0x0000000000003f5c 4 26 0 0 65 0
CHECK-NEXT: 0x0000000000003f6c 4 15 0 0 65 0
CHECK-NEXT: 0x0000000000003f8c 3 29 0 0 4100 0 is_stmt
CHECK-NEXT: 0x0000000000003f94 0 29 0 0 0 0
CHECK-NEXT: 0x0000000000003f98 3 5 0 0 4098 0
CHECK-NEXT: 0x0000000000003fa4 5 1 0 0 0 0 is_stmt
CHECK-NEXT: 0x0000000000003fa8 5 1 0 0 0 0 is_stmt end_sequence
Binary file not shown.
Binary file not shown.
8 changes: 8 additions & 0 deletions utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ cc_library(
],
)

cc_library(
name = "ProfileHeaders",
hdrs = glob(["include/bolt/Profile/*.h"]),
includes = ["include"],
visibility = ["//visibility:private"],
)

cc_library(
name = "Profile",
srcs = glob([
Expand Down Expand Up @@ -258,6 +265,7 @@ cc_library(
]),
includes = ["include"],
deps = [
":ProfileHeaders",
":Utils",
"//llvm:Analysis",
"//llvm:BinaryFormat",
Expand Down