Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lldb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ endif()

include(LLDBConfig)
include(AddLLDB)
include(LLDBLayeringCheck)

set(LLDB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

Expand Down Expand Up @@ -127,6 +128,8 @@ add_subdirectory(source)
add_subdirectory(tools)
add_subdirectory(docs)

check_lldb_plugin_layering()

if (LLDB_ENABLE_PYTHON)
if(LLDB_BUILD_FRAMEWORK)
set(lldb_python_target_dir "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Resources/Python/lldb")
Expand Down
68 changes: 68 additions & 0 deletions lldb/cmake/modules/LLDBLayeringCheck.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
define_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND)
define_property(TARGET PROPERTY LLDB_PLUGIN_KIND INHERITED)

define_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES)
define_property(TARGET PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES INHERITED)

define_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES)
define_property(TARGET PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES INHERITED)

option(LLDB_GENERATE_PLUGIN_DEP_GRAPH OFF)

function(check_lldb_plugin_layering)
get_property(plugins GLOBAL PROPERTY LLDB_PLUGINS)
foreach(plugin ${plugins})
get_property(plugin_kind TARGET ${plugin} PROPERTY LLDB_PLUGIN_KIND)
get_property(acceptable_deps TARGET ${plugin}
PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES)
get_property(tolerated_deps TARGET ${plugin}
PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES)

# A plugin is always permitted to depend on its own kind for the purposes
# subclassing. Ideally the intra-kind dependencies should not form a loop,
# but we're not checking that here.
list(APPEND acceptable_deps ${plugin_kind})

list(APPEND all_plugin_kinds ${plugin_kind})

get_property(link_libs TARGET ${plugin} PROPERTY LINK_LIBRARIES)
foreach(link_lib ${link_libs})
if(link_lib IN_LIST plugins)
get_property(lib_kind TARGET ${link_lib} PROPERTY LLDB_PLUGIN_KIND)
if (lib_kind)
if (lib_kind IN_LIST acceptable_deps)
set(dep_kind green)
elseif (lib_kind IN_LIST tolerated_deps)
set(dep_kind yellow)
else()
set(dep_kind red)
message(SEND_ERROR "Plugin ${plugin} cannot depend on ${lib_kind} "
"plugin ${link_lib}")
endif()
list(APPEND dep_${dep_kind}_${plugin_kind}_${lib_kind} ${plugin})
endif()
endif()
endforeach()
endforeach()

if (LLDB_GENERATE_PLUGIN_DEP_GRAPH)
set(dep_graph "digraph Plugins {\n")
list(REMOVE_DUPLICATES all_plugin_kinds)
foreach (from ${all_plugin_kinds})
foreach (to ${all_plugin_kinds})
foreach (dep_kind green yellow red)
if (dep_${dep_kind}_${from}_${to})
list(REMOVE_DUPLICATES dep_${dep_kind}_${from}_${to})
string(REGEX REPLACE "lldbPlugin|${from}" "" short_deps
"${dep_${dep_kind}_${from}_${to}}")
string(JOIN "\n" plugins ${short_deps})
string(APPEND dep_graph
" ${from}->${to}[color=\"${dep_kind}\" label=\"${plugins}\"];\n")
endif()
endforeach()
endforeach()
endforeach()
string(APPEND dep_graph "}\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lldb-plugin-deps.dot" "${dep_graph}")
endif()
endfunction()
50 changes: 50 additions & 0 deletions lldb/docs/resources/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,56 @@ subset of LLDB tests (the API tests) use a different system. Refer to the
`lldb/test <https://github.com/llvm/llvm-project/tree/main/lldb/test>`_ folder
for examples.


LLDB plugins and their dependencies
-----------------------------------

LLDB has a concept of *plugins*, which are used to provide abstraction
boundaries over functionality that is specific to a certain architecture,
operating system, programming language, etc. A plugin implements an abstract
base class (rarely, a set of related base classes), which is a part of LLDB
core. This setup allows the LLDB core to remain generic while making it possible
to support for new architectures, languages, and so on. For this to work, all
code needs to obey certain rules.

The principal rule is that LLDB core (defined as: everything under lldb/source
*minus* lldb/source/Plugins) must not depend on any specific plugin. The only
way it can interact with them is through the abstract interface. Explicit
dependencies such as casting the base class to the plugin type are not permitted
and neither are more subtle dependencies like checking the name plugin or or
other situations where some code in LLDB core is tightly coupled to the
implementation details of a specific plugin.

The rule for interaction between different plugins is more nuanced. We recognize
that some cross-plugin dependencies are unavoidable or even desirable. For
example, a plugin may want to extend a plugin of the same kind to
add/override/refine some functionality (e.g., Android is a "kind of" Linux, but
it handles some things differently). Alternatively, a plugin of one kind may
want to build on the functionality offered by a specific plugin of another kind
(ELFCore Process plugin uses ELF ObjectFile plugin to create a process out of an
ELF core file).

In cases such as these, direct dependencies are acceptable. However, to keep the
dependency graph manageable, we still have some rules to govern these
relationships:

* All dependencies between plugins of the same kind must flow in the same
direction (if plugin `A1` depends on plugin `B1`, then `B2` must not depend on
`A2`)
* Dependency graph of plugin kinds must not contain loops (dependencies like
`A1->B1`, `B2->C2` and `C3->A3` are forbidden because they induce a cycle in
the plugin kind graph even though the plugins themselves are acyclical)


The first of these rules is checked via CMake scripts (using the
`LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES` property). Dependencies in this category
are expected and permitted (subject to other constraints such as that dependency
making sense for the particular pair of plugins). Unfortunately, due to historic
reasons, not all plugin dependencies follow this rule, which is why we have
another category called `LLDB_TOLERATED_PLUGIN_DEPENDENCIES`. New dependencies
are forbidden (even though they are accepted by CMake) and existing ones should
be removed whereever possible.

.. _Error handling:

Error handling and use of assertions in LLDB
Expand Down
6 changes: 6 additions & 0 deletions lldb/source/Plugins/ABI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND ABI)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES
ProcessUtility
TypeSystem
)

foreach(target AArch64 ARM ARC Hexagon LoongArch Mips MSP430 PowerPC RISCV SystemZ X86)
if (${target} IN_LIST LLVM_TARGETS_TO_BUILD)
add_subdirectory(${target})
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/Architecture/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Architecture)

add_subdirectory(Arm)
add_subdirectory(Mips)
add_subdirectory(PPC64)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/Disassembler/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Disassembler)

add_subdirectory(LLVMC)
7 changes: 7 additions & 0 deletions lldb/source/Plugins/DynamicLoader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND DynamicLoader)
set_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES ObjectFile)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES
Process # part of a loop (Process<->DynamicLoader).
TypeSystem
)

add_subdirectory(Darwin-Kernel)
add_subdirectory(FreeBSD-Kernel)
add_subdirectory(MacOSX-DYLD)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ExpressionParser/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND ExpressionParser)

add_subdirectory(Clang)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/Instruction/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Instruction)

add_subdirectory(ARM)
add_subdirectory(ARM64)
add_subdirectory(LoongArch)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/InstrumentationRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND InstrumentationRuntime)

add_subdirectory(ASan)
add_subdirectory(ASanLibsanitizers)
add_subdirectory(MainThreadChecker)
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/JITLoader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND JITLoader)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES ObjectFile)

add_subdirectory(GDB)
6 changes: 6 additions & 0 deletions lldb/source/Plugins/Language/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Language)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES
LanguageRuntime
TypeSystem
)

add_subdirectory(ClangCommon)
add_subdirectory(CPlusPlus)
add_subdirectory(ObjC)
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/LanguageRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND LanguageRuntime)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES TypeSystem)

add_subdirectory(CPlusPlus)
add_subdirectory(ObjC)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/MemoryHistory/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND MemoryHistory)

add_subdirectory(asan)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ObjectContainer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND ObjectContainer)

add_subdirectory(BSD-Archive)
add_subdirectory(Universal-Mach-O)
add_subdirectory(Mach-O-Fileset)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ObjectFile/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND ObjectFile)

add_subdirectory(Breakpad)
add_subdirectory(COFF)
add_subdirectory(ELF)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/OperatingSystem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND OperatingSystem)

if (LLDB_ENABLE_PYTHON)
add_subdirectory(Python)
endif()
7 changes: 7 additions & 0 deletions lldb/source/Plugins/Platform/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Platform)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES
DynamicLoader
ObjectContainer
Process
)

add_subdirectory(AIX)
add_subdirectory(Android)
add_subdirectory(FreeBSD)
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/Plugins/Process/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Process)
set_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES ObjectFile)
# This dependency is part of a loop (Process<->DynamicLoader).
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES DynamicLoader)

if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
add_subdirectory(Linux)
add_subdirectory(POSIX)
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Process/Utility/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# TODO: Clean up this directory and its dependencies
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND ProcessUtility)

add_lldb_library(lldbPluginProcessUtility
AuxVector.cpp
FreeBSDSignals.cpp
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/REPL/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND REPL)
set_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES TypeSystem)

add_subdirectory(Clang)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/RegisterTypeBuilder/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND RegisterTypeBuilder)

add_lldb_library(lldbPluginRegisterTypeBuilderClang PLUGIN
RegisterTypeBuilderClang.cpp

Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ScriptInterpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND ScriptInterpreter)

add_subdirectory(None)
if (LLDB_ENABLE_PYTHON)
add_subdirectory(Python)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/StructuredData/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND StructuredData)

add_subdirectory(DarwinLog)

7 changes: 7 additions & 0 deletions lldb/source/Plugins/SymbolFile/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND SymbolFile)
set_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES ObjectFile)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES
Language
TypeSystem # part of a loop (TypeSystem<->SymbolFile).
)

add_subdirectory(Breakpad)
add_subdirectory(CTF)
add_subdirectory(DWARF)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/SymbolLocator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND SymbolLocator)

# Order matters here: the first symbol locator prevents further searching.
# For DWARF binaries that are both stripped and split, the Default plugin
# will return the stripped binary when asked for the ObjectFile, which then
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/SymbolVendor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND SymbolVendor)
set_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES ObjectFile)

add_subdirectory(ELF)

if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/SystemRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND SystemRuntime)
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES TypeSystem)

add_subdirectory(MacOSX)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/Trace/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND Trace)

option(LLDB_BUILD_INTEL_PT "Enable Building of Intel(R) Processor Trace Tool" OFF)

add_subdirectory(common)
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/TraceExporter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND TraceExporter)

add_subdirectory(common)
add_subdirectory(ctf)
4 changes: 4 additions & 0 deletions lldb/source/Plugins/TypeSystem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND TypeSystem)
# This dependency is part of a loop (TypeSystem<->SymbolFile).
set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES SymbolFile)

add_subdirectory(Clang)
2 changes: 2 additions & 0 deletions lldb/source/Plugins/UnwindAssembly/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND UnwindAssembly)

add_subdirectory(InstEmulation)
add_subdirectory(x86)
Loading