Author: Jonas Devlieghere Date: 2024-10-31T10:27:41-07:00 New Revision: 42fae38e6ad1433ac0ff1a648dfdcd3fdb981093
URL: https://github.com/llvm/llvm-project/commit/42fae38e6ad1433ac0ff1a648dfdcd3fdb981093 DIFF: https://github.com/llvm/llvm-project/commit/42fae38e6ad1433ac0ff1a648dfdcd3fdb981093.diff LOG: [lldb] Add a fuzzer for the DWARF Expression Evaluator (#114286) This adds a fuzzer for the DWARF expression evaluator. It does pretty much the same thing as what we do in the corresponding unit test but with data generated by libfuzzer. Added: lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp Modified: lldb/tools/lldb-fuzzer/CMakeLists.txt Removed: ################################################################################ diff --git a/lldb/tools/lldb-fuzzer/CMakeLists.txt b/lldb/tools/lldb-fuzzer/CMakeLists.txt index 4c081a9de53e2d..e384ca18583981 100644 --- a/lldb/tools/lldb-fuzzer/CMakeLists.txt +++ b/lldb/tools/lldb-fuzzer/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(lldb-commandinterpreter-fuzzer) +add_subdirectory(lldb-dwarf-expression-fuzzer) add_subdirectory(lldb-expression-fuzzer) add_subdirectory(lldb-target-fuzzer) add_subdirectory(utils) diff --git a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt new file mode 100644 index 00000000000000..464696fc051d66 --- /dev/null +++ b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt @@ -0,0 +1,33 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_llvm_fuzzer(lldb-dwarf-expression-fuzzer + EXCLUDE_FROM_ALL + lldb-dwarf-expression-fuzzer.cpp + ) + +if(TARGET lldb-dwarf-expression-fuzzer) + target_include_directories(lldb-dwarf-expression-fuzzer PRIVATE ..) + target_include_directories(lldb-dwarf-expression-fuzzer PRIVATE ${LLDB_SOURCE_ROOT}) + target_link_libraries(lldb-dwarf-expression-fuzzer + PRIVATE + lldbCore + lldbPluginExpressionParserClang + lldbPluginPlatformLinux + lldbPluginTypeSystemClang + lldbFuzzerUtils + ) + + add_custom_command(TARGET lldb-dwarf-expression-fuzzer PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/fuzzer-artifacts/dwarf-expression-artifacts + ) + + add_custom_target(fuzz-lldb-dwarf-expression + COMMENT "Running the LLDB DWARF expression evaluator fuzzer..." + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/fuzzer-artifacts/dwarf-expression-artifacts + COMMAND $<TARGET_FILE:lldb-dwarf-expression-fuzzer> -artifact_prefix=dwarf-expression- + USES_TERMINAL + ) + set_target_properties(fuzz-lldb-dwarf-expression PROPERTIES FOLDER "LLDB/Fuzzer") +endif() diff --git a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp new file mode 100644 index 00000000000000..86c3709b3a8297 --- /dev/null +++ b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp @@ -0,0 +1,83 @@ +//===-- lldb-target-fuzzer.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "utils/TempFile.h" + +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Value.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::plugin::dwarf; +using namespace lldb_fuzzer; + +extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { + FileSystem::Initialize(); + HostInfo::Initialize(); + platform_linux::PlatformLinux::Initialize(); + return 0; +} + +static void Evaluate(llvm::ArrayRef<uint8_t> expr, + lldb::ModuleSP module_sp = {}, DWARFUnit *unit = nullptr, + ExecutionContext *exe_ctx = nullptr) { + DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle, + /*addr_size*/ 4); + + llvm::Expected<Value> result = + DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp, + extractor, unit, lldb::eRegisterKindLLDB, + /*initial_value_ptr*/ nullptr, + /*object_address_ptr*/ nullptr); + + if (!result) + llvm::consumeError(result.takeError()); +} + +class MockTarget : public Target { +public: + MockTarget(Debugger &debugger, const ArchSpec &target_arch, + const lldb::PlatformSP &platform_sp, llvm::ArrayRef<uint8_t> data) + : Target(debugger, target_arch, platform_sp, true), m_data(data) {} + + size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, + Status &error, bool force_live_memory = false, + lldb::addr_t *load_addr_ptr = nullptr) override { + std::memcpy(dst, m_data.data(), m_data.size()); + return m_data.size(); + } + +private: + llvm::ArrayRef<uint8_t> m_data; +}; + +extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { + // We're going to use the first half of the input data as the DWARF expression + // and the second half as memory. + const size_t partition = size / 2; + llvm::ArrayRef expression_data(data, partition); + llvm::ArrayRef memory_data(data + partition, size - partition); + + // Create a mock target for reading memory. + ArchSpec arch("i386-pc-linux"); + Platform::SetHostPlatform( + platform_linux::PlatformLinux::CreateInstance(true, &arch)); + lldb::DebuggerSP debugger_sp = Debugger::CreateInstance(); + lldb::PlatformSP platform_sp; + auto target_sp = std::make_shared<MockTarget>(*debugger_sp, arch, platform_sp, + memory_data); + ExecutionContext exe_ctx(static_cast<lldb::TargetSP>(target_sp), false); + + Evaluate(expression_data); + return 0; +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits