From: robert Date: Sat, 11 Nov 2023 18:24:39 +0000 (+0000) Subject: merge lldb-16.0.6 X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=101d251d5caf88a9341f3045ab62e122abae1b90;p=openbsd merge lldb-16.0.6 --- diff --git a/gnu/llvm/lldb/cmake/modules/FindLibEdit.cmake b/gnu/llvm/lldb/cmake/modules/FindLibEdit.cmake deleted file mode 100644 index b4f0cb32981..00000000000 --- a/gnu/llvm/lldb/cmake/modules/FindLibEdit.cmake +++ /dev/null @@ -1,64 +0,0 @@ -#.rst: -# FindLibEdit -# ----------- -# -# Find libedit library and headers -# -# The module defines the following variables: -# -# :: -# -# LibEdit_FOUND - true if libedit was found -# LibEdit_INCLUDE_DIRS - include search path -# LibEdit_LIBRARIES - libraries to link -# LibEdit_VERSION_STRING - version number - -if(LibEdit_INCLUDE_DIRS AND LibEdit_LIBRARIES) - set(LibEdit_FOUND TRUE) -else() - find_package(PkgConfig QUIET) - pkg_check_modules(PC_LIBEDIT QUIET libedit) - - find_path(LibEdit_INCLUDE_DIRS - NAMES - histedit.h - HINTS - ${PC_LIBEDIT_INCLUDEDIR} - ${PC_LIBEDIT_INCLUDE_DIRS} - ${CMAKE_INSTALL_FULL_INCLUDEDIR}) - find_library(LibEdit_LIBRARIES - NAMES - edit libedit - HINTS - ${PC_LIBEDIT_LIBDIR} - ${PC_LIBEDIT_LIBRARY_DIRS} - ${CMAKE_INSTALL_FULL_LIBDIR}) - - if(LibEdit_INCLUDE_DIRS AND EXISTS "${LibEdit_INCLUDE_DIRS}/histedit.h") - file(STRINGS "${LibEdit_INCLUDE_DIRS}/histedit.h" - libedit_major_version_str - REGEX "^#define[ \t]+LIBEDIT_MAJOR[ \t]+[0-9]+") - string(REGEX REPLACE "^#define[ \t]+LIBEDIT_MAJOR[ \t]+([0-9]+)" "\\1" - LIBEDIT_MAJOR_VERSION "${libedit_major_version_str}") - - file(STRINGS "${LibEdit_INCLUDE_DIRS}/histedit.h" - libedit_minor_version_str - REGEX "^#define[ \t]+LIBEDIT_MINOR[ \t]+[0-9]+") - string(REGEX REPLACE "^#define[ \t]+LIBEDIT_MINOR[ \t]+([0-9]+)" "\\1" - LIBEDIT_MINOR_VERSION "${libedit_minor_version_str}") - - set(LibEdit_VERSION_STRING "${libedit_major_version}.${libedit_minor_version}") - endif() - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(LibEdit - FOUND_VAR - LibEdit_FOUND - REQUIRED_VARS - LibEdit_INCLUDE_DIRS - LibEdit_LIBRARIES - VERSION_VAR - LibEdit_VERSION_STRING) - mark_as_advanced(LibEdit_INCLUDE_DIRS LibEdit_LIBRARIES) -endif() - diff --git a/gnu/llvm/lldb/docs/design/reproducers.rst b/gnu/llvm/lldb/docs/design/reproducers.rst deleted file mode 100644 index 99e34d812de..00000000000 --- a/gnu/llvm/lldb/docs/design/reproducers.rst +++ /dev/null @@ -1,205 +0,0 @@ -Reproducers -=========== - -As unbelievable as it may sound, the debugger has bugs. These bugs might -manifest themselves as errors, missing results or even a crash. Quite often -these bugs don't reproduce in simple, isolated scenarios. The debugger deals -with a lot of moving parts and subtle differences can easily add up. - -Reproducers in LLDB improve the experience for both the users encountering bugs -and the developers working on resolving them. The general idea consists of -*capturing* all the information necessary to later *replay* a debug session -while debugging the debugger. - -.. contents:: - :local: - -Usage ------ - -Reproducers are a generic concept in LLDB and are not inherently coupled with -the command line driver. The functionality can be used for anything that uses -the SB API and the driver is just one example. However, because it's probably -the most common way users interact with lldb, that's the workflow described in -this section. - -Capture -``````` - -Until reproducer capture is enabled by default, you need to launch LLDB in -capture mode. For the command line driver, this means passing ``--capture``. -You cannot enable reproducer capture from within LLDB, as this would be too -late to capture initialization of the debugger. - -.. code-block:: bash - - > lldb --capture - -In capture mode, LLDB will keep track of all the information it needs to replay -the current debug session. Most data is captured lazily to limit the impact on -performance. To create the reproducer, use the ``reproducer generate`` -sub-command. It's always possible to check the status of the reproducers with -the ``reproducer status`` sub-command. Note that generating the reproducer -terminates the debug session. - -.. code-block:: none - - (lldb) reproducer status - Reproducer is in capture mode. - (lldb) reproducer generate - Reproducer written to '/path/to/reproducer' - Please have a look at the directory to assess if you're willing to share the contained information. - - -The resulting reproducer is a directory. It was a conscious decision to not -compress and archive it automatically. The reproducer can contain potentially -sensitive information like object and symbol files, their paths on disk, debug -information, memory excerpts of the inferior process, etc. - -Replay -`````` - -It is strongly recommended to replay the reproducer locally to ensure it -actually reproduces the expected behavior. If the reproducer doesn't behave -correctly locally, it means there's a bug in the reproducer implementation that -should be addressed. - -To replay a reproducer, simply pass its path to LLDB through the ``--replay`` -flag. It is unnecessary to pass any other command line flags. The flags that -were passed to LLDB during capture are already part of the reproducer. - -.. code-block:: bash - - > lldb --replay /path/to/reproducer - - -During replay LLDB will behave similar to batch mode. The session should be -identical to the recorded debug session. The only expected differences are that -the binary being debugged doesn't actually run during replay. That means that -you won't see any of its side effects, like things being printed to the -terminal. Another expected difference is the behavior of the ``reproducer -generate`` command, which becomes a NOOP during replay. - -Augmenting a Bug Report with a Reproducer -````````````````````````````````````````` - -A reproducer can significantly improve a bug report, but it in itself is not -sufficient. Always describe the expected and unexpected behavior. Just like the -debugger can have bugs, the reproducer can have bugs too. - - -Design ------- - - -Replay -`````` - -Reproducers support two replay modes. The main and most common mode is active -replay. It's called active, because it's LLDB that is driving replay by calling -the captured SB API functions one after each other. The second mode is passive -replay. In this mode, LLDB sits idle until an SB API function is called, for -example from Python, and then replays just this individual call. - -Active Replay -^^^^^^^^^^^^^ - -No matter how a reproducer was captured, they can always be replayed with the -command line driver. When a reproducer is passed with the ``--replay`` flag, the -driver short-circuits and passes off control to the reproducer infrastructure, -effectively bypassing its normal operation. This works because the driver is -implemented using the SB API and is therefore nothing more than a sequence of -SB API calls. - -Replay is driven by the ``Registry::Replay``. As long as there's data in the -buffer holding the API data, the next SB API function call is deserialized. -Once the function is known, the registry can retrieve its signature, and use -that to deserialize its arguments. The function can then be invoked, most -commonly through the synthesized default replayer, or potentially using a -custom defined replay function. This process continues, until more data is -available or a replay error is encountered. - -During replay only a function's side effects matter. The result returned by the -replayed function is ignored because it cannot be observed beyond the driver. -This is sound, because anything that is passed into a subsequent API call will -have been serialized as an input argument. This also works for SB API objects -because the reproducers know about every object that has crossed the API -boundary, which is true by definition for object return values. - - -Passive Replay -^^^^^^^^^^^^^^ - -Passive replay exists to support running the API test suite against a -reproducer. The API test suite is written in Python and tests the debugger by -calling into its API from Python. To make this work, the API must transparently -replay itself when called. This is what makes passive replay different from -driver replay, where it is lldb itself that's driving replay. For passive -replay, the driving factor is external. - -In order to replay API calls, the reproducers need a way to intercept them. -Every API call is already instrumented with an ``LLDB_RECORD_*`` macro that -captures its input arguments. Furthermore, it also contains the necessary logic -to detect which calls cross the API boundary and should be intercepted. We were -able to reuse all of this to implement passive replay. - -During passive replay is enabled, nothing happens until an SB API is called. -Inside that API function, the macro detects whether this call should be -replayed (i.e. crossed the API boundary). If the answer is yes, the next -function is deserialized from the SB API data and compared to the current -function. If the signature matches, we deserialize its input arguments and -reinvoke the current function with the deserialized arguments. We don't need to -do anything special to prevent us from recursively calling the replayed version -again, as the API boundary crossing logic knows that we're still behind the API -boundary when we re-invoked the current function. - -Another big difference with driver replay is the return value. While this -didn't matter for driver replay, it's key for passive replay, because that's -what gets checked by the test suite. Luckily, the ``LLDB_RECORD_*`` macros -contained sufficient type information to derive the result type. - -Testing -------- - -Reproducers are tested in the following ways: - - - Unit tests to cover the reproducer infrastructure. There are tests for the - provider, loader and for the reproducer instrumentation. - - Feature specific end-to-end test cases in the ``test/Shell/Reproducer`` - directory. These tests serve as integration and regression tests for the - reproducers infrastructure, as well as doing some sanity checking for basic - debugger functionality. - - The API and shell tests can be run against a replayed reproducer. The - ``check-lldb-reproducers`` target will run the API and shell test suite - twice: first running the test normally while capturing a reproducer and then - a second time using the replayed session as the test input. For the shell - tests this use a little shim (``lldb-repro``) that uses the arguments and - current working directory to transparently generate or replay a reproducer. - For the API tests an extra argument with the reproducer path is passed to - ``dotest.py`` which initializes the debugger in the appropriate mode. - Certain tests do not fit this paradigm (for example test that check the - output of the binary being debugged) and are skipped by marking them as - unsupported by adding ``UNSUPPORTED: lldb-repro`` to the top of the shell - test or adding the ``skipIfReproducer`` decorator for the API tests. - -Knows Issues ------------- - -The reproducers are still a work in progress. Here's a non-exhaustive list of -outstanding work, limitations and known issues. - - - The VFS cannot deal with more than one current working directory. Changing - the current working directory during the debug session will break relative - paths. - - Not all SB APIs are properly instrumented. We need customer serialization - for APIs that take buffers and lengths. - - We leak memory during replay because the reproducer doesn't capture the end - of an object's life time. We need to add instrumentation to the destructor - of SB API objects. - - The reproducer includes every file opened by LLDB. This is overkill. For - example we do not need to capture source files for code listings. There's - currently no way to say that some file shouldn't be included in the - reproducer. - - We do not yet automatically generate a reproducer on a crash. The reason is - that generating the reproducer is too expensive to do in a signal handler. - We should re-invoke lldb after a crash and do the heavy lifting. diff --git a/gnu/llvm/lldb/docs/man/lldb.rst b/gnu/llvm/lldb/docs/man/lldb.rst index b75288db380..10b143cd0de 100644 --- a/gnu/llvm/lldb/docs/man/lldb.rst +++ b/gnu/llvm/lldb/docs/man/lldb.rst @@ -111,7 +111,7 @@ COMMANDS .. option:: --source-quietly - Tells the debugger to execute this one-line lldb command before any file has been loaded. + Tells the debugger not to echo commands while sourcing files or one-line commands provided on the command line. .. option:: --source @@ -234,6 +234,10 @@ SCRIPTING Alias for --script-language +.. option:: --print-script-interpreter-info + + Prints out a json dictionary with information about the scripting language interpreter. + .. option:: --python-path Prints out the path to the lldb.py file for this version of lldb. diff --git a/gnu/llvm/lldb/docs/testsuite/best-practices.txt b/gnu/llvm/lldb/docs/testsuite/best-practices.txt deleted file mode 100644 index b5a9156fd52..00000000000 --- a/gnu/llvm/lldb/docs/testsuite/best-practices.txt +++ /dev/null @@ -1,93 +0,0 @@ -This document attempts to point out some best practices that prove to be helpful -when building new test cases in the tot/test directory. Everyone is welcomed to -add/modify contents into this file. - -o Do not use hard-coded line numbers in your test case. Instead, try to tag the - line with some distinguishing pattern, and use the function line_number() - defined in lldbtest.py which takes filename and string_to_match as arguments - and returns the line number. - -As an example, take a look at test/breakpoint_conditions/main.c which has these -two lines: - - return c(val); // Find the line number of c's parent call here. - -and - - return val + 3; // Find the line number of function "c" here. - -The Python test case TestBreakpointConditions.py uses the comment strings to -find the line numbers during setUp(self) and use them later on to verify that -the correct breakpoint is being stopped on and that its parent frame also has -the correct line number as intended through the breakpoint condition. - -o Take advantage of the unittest framework's decorator features to properly - mark your test class or method for platform-specific tests. - -As an example, take a look at test/forward/TestForwardDeclaration.py which has -these lines: - - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - def test_with_dsym_and_run_command(self): - """Display *bar_ptr when stopped on a function with forward declaration of struct bar.""" - self.buildDsym() - self.forward_declaration() - -This tells the test harness that unless we are running "darwin", the test should -be skipped. This is because we are asking to build the binaries with dsym debug -info, which is only available on the darwin platforms. - -o Cleanup after yourself. A classic example of this can be found in test/types/ - TestFloatTypes.py: - - def test_float_types_with_dsym(self): - """Test that float-type variables are displayed correctly.""" - d = {'CXX_SOURCES': 'float.cpp'} - self.buildDsym(dictionary=d) - self.setTearDownCleanup(dictionary=d) - self.float_type() - - ... - - def test_double_type_with_dsym(self): - """Test that double-type variables are displayed correctly.""" - d = {'CXX_SOURCES': 'double.cpp'} - self.buildDsym(dictionary=d) - self.setTearDownCleanup(dictionary=d) - self.double_type() - -This tests different data structures composed of float types to verify that what -the debugger prints out matches what the compiler does for different variables -of these types. We're using a dictionary to pass the build parameters to the -build system. After a particular test instance is done, it is a good idea to -clean up the files built. This eliminates the chance that some leftover files -can interfere with the build phase for the next test instance and render it -invalid. - -TestBase.setTearDownCleanup(self, dictionary) defined in lldbtest.py is created -to cope with this use case by taking the same build parameters in order to do -the cleanup when we are finished with a test instance, during -TestBase.tearDown(self). - -o Class-wise cleanup after yourself. - -TestBase.tearDownClass(cls) provides a mechanism to invoke the platform-specific -cleanup after finishing with a test class. A test class can have more than one -test methods, so the tearDownClass(cls) method gets run after all the test -methods have been executed by the test harness. - -The default cleanup action performed by the plugins/darwin.py module invokes the -"make clean" os command. - -If this default cleanup is not enough, individual class can provide an extra -cleanup hook with a class method named classCleanup , for example, -in test/breakpoint_command/TestBreakpointCommand.py: - - @classmethod - def classCleanup(cls): - system(["/bin/sh", "-c", "rm -f output.txt"]) - -The 'output.txt' file gets generated during the test run, so it makes sense to -explicitly spell out the action in the same TestBreakpointCommand.py file to do -the cleanup instead of artificially adding it as part of the default cleanup -action which serves to cleanup those intermediate and a.out files. diff --git a/gnu/llvm/lldb/docs/use/links.md b/gnu/llvm/lldb/docs/use/links.md deleted file mode 100644 index 8c125a26cb4..00000000000 --- a/gnu/llvm/lldb/docs/use/links.md +++ /dev/null @@ -1,56 +0,0 @@ -Links -===== - -This page contains links to external resources on how to use LLDB. Being listed -on this page is not an endorsement. - -## Blog Posts - -### [Dancing in the Debugger — A Waltz with LLDB (2014) ](https://www.objc.io/issues/19-debugging/lldb-debugging/) - -A high level overview of LLDB with a focus on debugging Objective-C code. - -## Videos - -### [LLDB: Beyond "po" (2019)](https://developer.apple.com/videos/play/wwdc2019/429/) - -LLDB is a powerful tool for exploring and debugging your app at runtime. -Discover the various ways to display values in your app, how to format custom -data types, and how to extend LLDB using your own Python 3 scripts. - -### [Advanced Debugging with Xcode and LLDB (2018)](https://developer.apple.com/videos/play/wwdc2018/412/) - -Discover advanced techniques, and tips and tricks for enhancing your Xcode -debugging workflows. Learn how to take advantage of LLDB and custom breakpoints -for more powerful debugging. Get the most out of Xcode's view debugging tools -to solve UI issues in your app more efficiently. - -### [Debugging with LLDB (2012)](https://developer.apple.com/videos/play/wwdc2012/415/) - -LLDB is the next-generation debugger for macOS and iOS. Get an introduction to -using LLDB via the console interface and within Xcode's graphical debugger. The -team that created LLDB will demonstrate the latest features and improvements, -helping you track down bugs more efficiently than ever before. - -### [Migrating from GDB to LLDB (2011)](https://developer.apple.com/videos/play/wwdc2011/321/) - -LLDB is the next-generation debugger for macOS and iOS. Discover why you'll -want to start using LLDB in your own development, get expert tips from the team -that created LLDB, and see how it will help you track down bugs more -efficiently than ever before. - -## Books - -### [Advanced Apple Debugging & Reverse Engineering (2018)](https://www.raywenderlich.com/books/advanced-apple-debugging-reverse-engineering/) - -A book about using LLDB on Apple platforms. - -## Extensions - -### [facebook/chisel](https://github.com/facebook/chisel) - -Chisel is a collection of LLDB commands to assist in the debugging of iOS apps. - -### [DerekSelander/LLDB](https://github.com/DerekSelander/LLDB) - -A collection of LLDB aliases/regexes and Python scripts. diff --git a/gnu/llvm/lldb/examples/python/scripted_process/my_scripted_process.py b/gnu/llvm/lldb/examples/python/scripted_process/my_scripted_process.py deleted file mode 100644 index 429531e80e1..00000000000 --- a/gnu/llvm/lldb/examples/python/scripted_process/my_scripted_process.py +++ /dev/null @@ -1,45 +0,0 @@ -import os - -import lldb -from lldb.plugins.scripted_process import ScriptedProcess - -class MyScriptedProcess(ScriptedProcess): - def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): - super().__init__(target, args) - - def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo: - return self.memory_regions[0] - - def get_thread_with_id(self, tid: int): - return {} - - def get_registers_for_thread(self, tid: int): - return {} - - def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData: - data = lldb.SBData().CreateDataFromCString( - self.target.GetByteOrder(), - self.target.GetCodeByteSize(), - "Hello, world!") - return data - - def get_loaded_images(self): - return self.loaded_images - - def get_process_id(self) -> int: - return 42 - - def should_stop(self) -> bool: - return True - - def is_alive(self) -> bool: - return True - -def __lldb_init_module(debugger, dict): - if not 'SKIP_SCRIPTED_PROCESS_LAUNCH' in os.environ: - debugger.HandleCommand( - "process launch -C %s.%s" % (__name__, - MyScriptedProcess.__name__)) - else: - print("Name of the class that will manage the scripted process: '%s.%s'" - % (__name__, MyScriptedProcess.__name__)) \ No newline at end of file diff --git a/gnu/llvm/lldb/include/lldb/Host/StringConvert.h b/gnu/llvm/lldb/include/lldb/Host/StringConvert.h deleted file mode 100644 index 33608a85ff4..00000000000 --- a/gnu/llvm/lldb/include/lldb/Host/StringConvert.h +++ /dev/null @@ -1,38 +0,0 @@ -//===-- StringConvert.h -----------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_HOST_STRINGCONVERT_H -#define LLDB_HOST_STRINGCONVERT_H - -#include - -namespace lldb_private { - -namespace StringConvert { - -/// \namespace StringConvert StringConvert.h "lldb/Host/StringConvert.h" -/// Utility classes for converting strings into Integers - -int32_t ToSInt32(const char *s, int32_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -uint32_t ToUInt32(const char *s, uint32_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -int64_t ToSInt64(const char *s, int64_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -uint64_t ToUInt64(const char *s, uint64_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -double ToDouble(const char *s, double fail_value = 0.0, - bool *success_ptr = nullptr); -} // namespace StringConvert -} // namespace lldb_private - -#endif diff --git a/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h b/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h index 366157851be..22865d1ce6d 100644 --- a/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h +++ b/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h @@ -12,6 +12,7 @@ #include "lldb/Host/posix/HostInfoPosix.h" #include "lldb/Utility/FileSpec.h" #include "llvm/Support/VersionTuple.h" +#include namespace lldb_private { @@ -20,8 +21,7 @@ class HostInfoOpenBSD : public HostInfoPosix { public: static llvm::VersionTuple GetOSVersion(); - static bool GetOSBuildString(std::string &s); - static bool GetOSKernelDescription(std::string &s); + static std::optional GetOSBuildString(); static FileSpec GetProgramFileSpec(); protected: diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/Fcntl.h b/gnu/llvm/lldb/include/lldb/Host/posix/Fcntl.h deleted file mode 100644 index 31cc293dd37..00000000000 --- a/gnu/llvm/lldb/include/lldb/Host/posix/Fcntl.h +++ /dev/null @@ -1,24 +0,0 @@ -//===-- Fcntl.h -------------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// This file defines fcntl functions & structures - -#ifndef liblldb_Host_posix_Fcntl_h_ -#define liblldb_Host_posix_Fcntl_h_ - -#ifdef __ANDROID__ -#include -#endif - -#include - -#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 -#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6) -#endif - -#endif // liblldb_Host_posix_Fcntl_h_ diff --git a/gnu/llvm/lldb/include/lldb/Target/TraceInstructionDumper.h b/gnu/llvm/lldb/include/lldb/Target/TraceInstructionDumper.h deleted file mode 100644 index c4878bfd3fd..00000000000 --- a/gnu/llvm/lldb/include/lldb/Target/TraceInstructionDumper.h +++ /dev/null @@ -1,77 +0,0 @@ -//===-- TraceInstructionDumper.h --------------------------------*- C++ -*-===// -// -// 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 "lldb/Target/TraceCursor.h" - -#ifndef LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H -#define LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H - -namespace lldb_private { - -/// Class used to dump the instructions of a \a TraceCursor using its current -/// state and granularity. -class TraceInstructionDumper { -public: - /// Create a instruction dumper for the cursor. - /// - /// \param[in] cursor - /// The cursor whose instructions will be dumped. - /// - /// \param[in] initial_index - /// Presentation index to use for referring to the current instruction - /// of the cursor. If the direction is forwards, the index will increase, - /// and if the direction is backwards, the index will decrease. - /// - /// \param[in] raw - /// Dump only instruction addresses without disassembly nor symbol - /// information. - /// - /// \param[in] show_tsc - /// For each instruction, print the corresponding timestamp counter if - /// available. - TraceInstructionDumper(lldb::TraceCursorUP &&cursor_up, int initial_index = 0, - bool raw = false, bool show_tsc = false); - - /// Dump \a count instructions of the thread trace starting at the current - /// cursor position. - /// - /// This effectively moves the cursor to the next unvisited position, so that - /// a subsequent call to this method continues where it left off. - /// - /// \param[in] s - /// The stream object where the instructions are printed. - /// - /// \param[in] count - /// The number of instructions to print. - void DumpInstructions(Stream &s, size_t count); - - /// Indicate the dumper that no more data is available in the trace. - void SetNoMoreData(); - - /// \return - /// \b true if there's still more data to traverse in the trace. - bool HasMoreData(); - -private: - /// Move the cursor one step. - /// - /// \return - /// \b true if the cursor moved. - bool TryMoveOneStep(); - - lldb::TraceCursorUP m_cursor_up; - int m_index; - bool m_raw; - bool m_show_tsc; - /// If \b true, all the instructions have been traversed. - bool m_no_more_data = false; -}; - -} // namespace lldb_private - -#endif // LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h b/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h index 9500f434044..7a9150cdef7 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h +++ b/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h @@ -16,7 +16,6 @@ #include "lldb/lldb-private-enumerations.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" -#include "llvm/Support/YAMLTraits.h" #include #include #include @@ -92,12 +91,29 @@ public: eARM_abi_hard_float = 0x00000400 }; + enum RISCVeflags { + eRISCV_rvc = 0x00000001, /// RVC, +c + eRISCV_float_abi_soft = 0x00000000, /// soft float + eRISCV_float_abi_single = 0x00000002, /// single precision floating point, +f + eRISCV_float_abi_double = 0x00000004, /// double precision floating point, +d + eRISCV_float_abi_quad = 0x00000006, /// quad precision floating point, +q + eRISCV_float_abi_mask = 0x00000006, + eRISCV_rve = 0x00000008, /// RVE, +e + eRISCV_tso = 0x00000010, /// RVTSO (total store ordering) + }; + enum RISCVSubType { eRISCVSubType_unknown, eRISCVSubType_riscv32, eRISCVSubType_riscv64, }; + enum LoongArchSubType { + eLoongArchSubType_unknown, + eLoongArchSubType_loongarch32, + eLoongArchSubType_loongarch64, + }; + enum Core { eCore_arm_generic, eCore_arm_armv4, @@ -195,6 +211,9 @@ public: eCore_riscv32, eCore_riscv64, + eCore_loongarch32, + eCore_loongarch64, + eCore_uknownMach32, eCore_uknownMach64, @@ -478,19 +497,25 @@ public: /// architecture and false otherwise. bool CharIsSignedByDefault() const; - /// Compare an ArchSpec to another ArchSpec, requiring an exact cpu type - /// match between them. e.g. armv7s is not an exact match with armv7 - this - /// would return false + enum MatchType : bool { CompatibleMatch, ExactMatch }; + + /// Compare this ArchSpec to another ArchSpec. \a match specifies the kind of + /// matching that is to be done. CompatibleMatch requires only a compatible + /// cpu type (e.g., armv7s is compatible with armv7). ExactMatch requires an + /// exact match (armv7s is not an exact match with armv7). /// /// \return true if the two ArchSpecs match. - bool IsExactMatch(const ArchSpec &rhs) const; + bool IsMatch(const ArchSpec &rhs, MatchType match) const; - /// Compare an ArchSpec to another ArchSpec, requiring a compatible cpu type - /// match between them. e.g. armv7s is compatible with armv7 - this method - /// would return true - /// - /// \return true if the two ArchSpecs are compatible - bool IsCompatibleMatch(const ArchSpec &rhs) const; + /// Shorthand for IsMatch(rhs, ExactMatch). + bool IsExactMatch(const ArchSpec &rhs) const { + return IsMatch(rhs, ExactMatch); + } + + /// Shorthand for IsMatch(rhs, CompatibleMatch). + bool IsCompatibleMatch(const ArchSpec &rhs) const { + return IsMatch(rhs, CompatibleMatch); + } bool IsFullySpecifiedTriple() const; @@ -519,7 +544,6 @@ public: void SetFlags(const std::string &elf_abi); protected: - bool IsEqualTo(const ArchSpec &rhs, bool exact_match) const; void UpdateCore(); llvm::Triple m_triple; @@ -553,16 +577,4 @@ bool ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str, ArchSpec &arch); } // namespace lldb_private -namespace llvm { -namespace yaml { -template <> struct ScalarTraits { - static void output(const lldb_private::ArchSpec &, void *, raw_ostream &); - static StringRef input(StringRef, void *, lldb_private::ArchSpec &); - static QuotingType mustQuote(StringRef S) { return QuotingType::Double; } -}; -} // namespace yaml -} // namespace llvm - -LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ArchSpec) - #endif // LLDB_UTILITY_ARCHSPEC_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Logging.h b/gnu/llvm/lldb/include/lldb/Utility/Logging.h deleted file mode 100644 index 1a8a1022c5c..00000000000 --- a/gnu/llvm/lldb/include/lldb/Utility/Logging.h +++ /dev/null @@ -1,65 +0,0 @@ -//===-- Logging.h -----------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UTILITY_LOGGING_H -#define LLDB_UTILITY_LOGGING_H - -#include - -// Log Bits specific to logging in lldb -#define LIBLLDB_LOG_PROCESS (1u << 1) -#define LIBLLDB_LOG_THREAD (1u << 2) -#define LIBLLDB_LOG_DYNAMIC_LOADER (1u << 3) -#define LIBLLDB_LOG_EVENTS (1u << 4) -#define LIBLLDB_LOG_BREAKPOINTS (1u << 5) -#define LIBLLDB_LOG_WATCHPOINTS (1u << 6) -#define LIBLLDB_LOG_STEP (1u << 7) -#define LIBLLDB_LOG_EXPRESSIONS (1u << 8) -#define LIBLLDB_LOG_TEMPORARY (1u << 9) -#define LIBLLDB_LOG_STATE (1u << 10) -#define LIBLLDB_LOG_OBJECT (1u << 11) -#define LIBLLDB_LOG_COMMUNICATION (1u << 12) -#define LIBLLDB_LOG_CONNECTION (1u << 13) -#define LIBLLDB_LOG_HOST (1u << 14) -#define LIBLLDB_LOG_UNWIND (1u << 15) -#define LIBLLDB_LOG_API (1u << 16) -#define LIBLLDB_LOG_SCRIPT (1u << 17) -#define LIBLLDB_LOG_COMMANDS (1U << 18) -#define LIBLLDB_LOG_TYPES (1u << 19) -#define LIBLLDB_LOG_SYMBOLS (1u << 20) -#define LIBLLDB_LOG_MODULES (1u << 21) -#define LIBLLDB_LOG_TARGET (1u << 22) -#define LIBLLDB_LOG_MMAP (1u << 23) -#define LIBLLDB_LOG_OS (1u << 24) -#define LIBLLDB_LOG_PLATFORM (1u << 25) -#define LIBLLDB_LOG_SYSTEM_RUNTIME (1u << 26) -#define LIBLLDB_LOG_JIT_LOADER (1u << 27) -#define LIBLLDB_LOG_LANGUAGE (1u << 28) -#define LIBLLDB_LOG_DATAFORMATTERS (1u << 29) -#define LIBLLDB_LOG_DEMANGLE (1u << 30) -#define LIBLLDB_LOG_AST (1u << 31) -#define LIBLLDB_LOG_ALL (UINT32_MAX) -#define LIBLLDB_LOG_DEFAULT \ - (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD | LIBLLDB_LOG_DYNAMIC_LOADER | \ - LIBLLDB_LOG_BREAKPOINTS | LIBLLDB_LOG_WATCHPOINTS | LIBLLDB_LOG_STEP | \ - LIBLLDB_LOG_STATE | LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_TARGET | \ - LIBLLDB_LOG_COMMANDS) - -namespace lldb_private { - -class Log; - -Log *GetLogIfAllCategoriesSet(uint32_t mask); - -Log *GetLogIfAnyCategoriesSet(uint32_t mask); - -void InitializeLldbChannel(); - -} // namespace lldb_private - -#endif // LLDB_UTILITY_LOGGING_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h b/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h deleted file mode 100644 index 4659254e57d..00000000000 --- a/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h +++ /dev/null @@ -1,252 +0,0 @@ -//===-- Reproducer.h --------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UTILITY_REPRODUCER_H -#define LLDB_UTILITY_REPRODUCER_H - -#include "lldb/Utility/FileSpec.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/VirtualFileSystem.h" -#include "llvm/Support/YAMLTraits.h" - -#include -#include -#include -#include - -namespace lldb_private { -class UUID; -namespace repro { - -class Reproducer; - -enum class ReproducerMode { - Capture, - Replay, - PassiveReplay, - Off, -}; - -/// The provider defines an interface for generating files needed for -/// reproducing. -/// -/// Different components will implement different providers. -class ProviderBase { -public: - virtual ~ProviderBase() = default; - - const FileSpec &GetRoot() const { return m_root; } - - /// The Keep method is called when it is decided that we need to keep the - /// data in order to provide a reproducer. - virtual void Keep(){}; - - /// The Discard method is called when it is decided that we do not need to - /// keep any information and will not generate a reproducer. - virtual void Discard(){}; - - // Returns the class ID for this type. - static const void *ClassID() { return &ID; } - - // Returns the class ID for the dynamic type of this Provider instance. - virtual const void *DynamicClassID() const = 0; - - virtual llvm::StringRef GetName() const = 0; - virtual llvm::StringRef GetFile() const = 0; - -protected: - ProviderBase(const FileSpec &root) : m_root(root) {} - -private: - /// Every provider knows where to dump its potential files. - FileSpec m_root; - - virtual void anchor(); - static char ID; -}; - -template class Provider : public ProviderBase { -public: - static const void *ClassID() { return &ThisProviderT::ID; } - - const void *DynamicClassID() const override { return &ThisProviderT::ID; } - - llvm::StringRef GetName() const override { return ThisProviderT::Info::name; } - llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; } - -protected: - using ProviderBase::ProviderBase; // Inherit constructor. -}; - -/// The generator is responsible for the logic needed to generate a -/// reproducer. For doing so it relies on providers, who serialize data that -/// is necessary for reproducing a failure. -class Generator final { - -public: - Generator(FileSpec root); - ~Generator(); - - /// Method to indicate we want to keep the reproducer. If reproducer - /// generation is disabled, this does nothing. - void Keep(); - - /// Method to indicate we do not want to keep the reproducer. This is - /// unaffected by whether or not generation reproduction is enabled, as we - /// might need to clean up files already written to disk. - void Discard(); - - /// Enable or disable auto generate. - void SetAutoGenerate(bool b); - - /// Return whether auto generate is enabled. - bool IsAutoGenerate() const; - - /// Create and register a new provider. - template T *Create() { - std::unique_ptr provider = std::make_unique(m_root); - return static_cast(Register(std::move(provider))); - } - - /// Get an existing provider. - template T *Get() { - auto it = m_providers.find(T::ClassID()); - if (it == m_providers.end()) - return nullptr; - return static_cast(it->second.get()); - } - - /// Get a provider if it exists, otherwise create it. - template T &GetOrCreate() { - auto *provider = Get(); - if (provider) - return *provider; - return *Create(); - } - - const FileSpec &GetRoot() const; - -private: - friend Reproducer; - - ProviderBase *Register(std::unique_ptr provider); - - /// Builds and index with provider info. - void AddProvidersToIndex(); - - /// Map of provider IDs to provider instances. - llvm::DenseMap> m_providers; - std::mutex m_providers_mutex; - - /// The reproducer root directory. - FileSpec m_root; - - /// Flag to ensure that we never call both keep and discard. - bool m_done = false; - - /// Flag to auto generate a reproducer when it would otherwise be discarded. - bool m_auto_generate = false; -}; - -class Loader final { -public: - Loader(FileSpec root, bool passive = false); - - template FileSpec GetFile() { - if (!HasFile(T::file)) - return {}; - - return GetRoot().CopyByAppendingPathComponent(T::file); - } - - template llvm::Expected LoadBuffer() { - FileSpec file = GetFile(); - llvm::ErrorOr> buffer = - llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath()); - if (!buffer) - return llvm::errorCodeToError(buffer.getError()); - return (*buffer)->getBuffer().str(); - } - - llvm::Error LoadIndex(); - - const FileSpec &GetRoot() const { return m_root; } - - bool IsPassiveReplay() const { return m_passive_replay; } - -private: - bool HasFile(llvm::StringRef file); - - FileSpec m_root; - std::vector m_files; - bool m_loaded; - bool m_passive_replay; -}; - -/// The reproducer enables clients to obtain access to the Generator and -/// Loader. -class Reproducer { -public: - static Reproducer &Instance(); - static llvm::Error Initialize(ReproducerMode mode, - llvm::Optional root); - static void Initialize(); - static bool Initialized(); - static void Terminate(); - - Reproducer() = default; - - Generator *GetGenerator(); - Loader *GetLoader(); - - const Generator *GetGenerator() const; - const Loader *GetLoader() const; - - FileSpec GetReproducerPath() const; - - bool IsCapturing() { return static_cast(m_generator); }; - bool IsReplaying() { return static_cast(m_loader); }; - -protected: - llvm::Error SetCapture(llvm::Optional root); - llvm::Error SetReplay(llvm::Optional root, bool passive = false); - -private: - static llvm::Optional &InstanceImpl(); - - llvm::Optional m_generator; - llvm::Optional m_loader; - - mutable std::mutex m_mutex; -}; - -class Verifier { -public: - Verifier(Loader *loader) : m_loader(loader) {} - void Verify(llvm::function_ref error_callback, - llvm::function_ref warning_callback, - llvm::function_ref note_callback) const; - -private: - Loader *m_loader; -}; - -struct ReplayOptions { - bool verify = true; - bool check_version = true; -}; - -llvm::Error Finalize(Loader *loader); -llvm::Error Finalize(const FileSpec &root); - -} // namespace repro -} // namespace lldb_private - -#endif // LLDB_UTILITY_REPRODUCER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h deleted file mode 100644 index 2b2d273a17a..00000000000 --- a/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ /dev/null @@ -1,1111 +0,0 @@ -//===-- ReproducerInstrumentation.h -----------------------------*- C++ -*-===// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H -#define LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H - -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/ErrorHandling.h" - -#include -#include -#include - -template ::value, int>::type = 0> -inline void stringify_append(llvm::raw_string_ostream &ss, const T &t) { - ss << t; -} - -template ::value, - int>::type = 0> -inline void stringify_append(llvm::raw_string_ostream &ss, const T &t) { - ss << &t; -} - -template -inline void stringify_append(llvm::raw_string_ostream &ss, T *t) { - ss << reinterpret_cast(t); -} - -template -inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) { - ss << reinterpret_cast(t); -} - -template <> -inline void stringify_append(llvm::raw_string_ostream &ss, - const char *t) { - ss << '\"' << t << '\"'; -} - -template <> -inline void stringify_append(llvm::raw_string_ostream &ss, - const std::nullptr_t &t) { - ss << "\"nullptr\""; -} - -template -inline void stringify_helper(llvm::raw_string_ostream &ss, const Head &head) { - stringify_append(ss, head); -} - -template -inline void stringify_helper(llvm::raw_string_ostream &ss, const Head &head, - const Tail &... tail) { - stringify_append(ss, head); - ss << ", "; - stringify_helper(ss, tail...); -} - -template inline std::string stringify_args(const Ts &... ts) { - std::string buffer; - llvm::raw_string_ostream ss(buffer); - stringify_helper(ss, ts...); - return ss.str(); -} - -// Define LLDB_REPRO_INSTR_TRACE to trace to stderr instead of LLDB's log -// infrastructure. This is useful when you need to see traces before the logger -// is initialized or enabled. -// #define LLDB_REPRO_INSTR_TRACE - -#ifdef LLDB_REPRO_INSTR_TRACE -inline llvm::raw_ostream &this_thread_id() { - size_t tid = std::hash{}(std::this_thread::get_id()); - return llvm::errs().write_hex(tid) << " :: "; -} -#endif - -#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature) \ - R.Register(&construct::record, "", \ - #Class, #Class, #Signature) - -#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature) \ - R.Register( \ - &invoke::method<(&Class::Method)>::record, \ - #Result, #Class, #Method, #Signature) - -#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature) \ - R.Register(&invoke::method<(&Class::Method)>::record, \ - #Result, #Class, #Method, #Signature) - -#define LLDB_REGISTER_STATIC_METHOD(Result, Class, Method, Signature) \ - R.Register(&invoke::method<(&Class::Method)>::record, \ - #Result, #Class, #Method, #Signature) - -#define LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(Result, Class, Method) \ - R.Register( \ - &invoke::method<(&Class::Method)>::record, \ - &invoke_char_ptr::method<(&Class::Method)>::record, \ - #Result, #Class, #Method, "(char*, size_t"); - -#define LLDB_REGISTER_CHAR_PTR_METHOD(Result, Class, Method) \ - R.Register(&invoke::method<( \ - &Class::Method)>::record, \ - &invoke_char_ptr::method<( \ - &Class::Method)>::record, \ - #Result, #Class, #Method, "(char*, size_t"); - -#define LLDB_REGISTER_CHAR_PTR_METHOD_CONST(Result, Class, Method) \ - R.Register(&invoke::method<(&Class::Method)>::record, \ - &invoke_char_ptr::method<(&Class::Method)>::record, \ - #Result, #Class, #Method, "(char*, size_t"); - -#define LLDB_CONSTRUCT_(T, Class, ...) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION); \ - lldb_private::repro::construct::handle(LLDB_GET_INSTRUMENTATION_DATA(), \ - _recorder, Class, __VA_ARGS__); - -#define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...) \ - LLDB_CONSTRUCT_(Class Signature, this, __VA_ARGS__) - -#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class) \ - LLDB_CONSTRUCT_(Class(), this, lldb_private::repro::EmptyArg()) - -#define LLDB_RECORD_(T1, T2, ...) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - if (lldb_private::repro::Serializer *_serializer = \ - _data.GetSerializer()) { \ - _recorder.Record(*_serializer, _data.GetRegistry(), \ - &lldb_private::repro::invoke::method::record, \ - __VA_ARGS__); \ - } else if (lldb_private::repro::Deserializer *_deserializer = \ - _data.GetDeserializer()) { \ - if (_recorder.ShouldCapture()) { \ - return lldb_private::repro::invoke::method::replay( \ - _recorder, *_deserializer, _data.GetRegistry()); \ - } \ - } \ - } - -#define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \ - LLDB_RECORD_(Result(Class::*) Signature, (&Class::Method), this, __VA_ARGS__) - -#define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \ - LLDB_RECORD_(Result(Class::*) Signature const, (&Class::Method), this, \ - __VA_ARGS__) - -#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \ - LLDB_RECORD_(Result (Class::*)(), (&Class::Method), this) - -#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \ - LLDB_RECORD_(Result (Class::*)() const, (&Class::Method), this) - -#define LLDB_RECORD_STATIC_METHOD(Result, Class, Method, Signature, ...) \ - LLDB_RECORD_(Result(*) Signature, (&Class::Method), __VA_ARGS__) - -#define LLDB_RECORD_STATIC_METHOD_NO_ARGS(Result, Class, Method) \ - LLDB_RECORD_(Result (*)(), (&Class::Method), lldb_private::repro::EmptyArg()) - -#define LLDB_RECORD_CHAR_PTR_(T1, T2, StrOut, ...) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - if (lldb_private::repro::Serializer *_serializer = \ - _data.GetSerializer()) { \ - _recorder.Record(*_serializer, _data.GetRegistry(), \ - &lldb_private::repro::invoke::method<(T2)>::record, \ - __VA_ARGS__); \ - } else if (lldb_private::repro::Deserializer *_deserializer = \ - _data.GetDeserializer()) { \ - if (_recorder.ShouldCapture()) { \ - return lldb_private::repro::invoke_char_ptr::method::replay( \ - _recorder, *_deserializer, _data.GetRegistry(), StrOut); \ - } \ - } \ - } - -#define LLDB_RECORD_CHAR_PTR_METHOD(Result, Class, Method, Signature, StrOut, \ - ...) \ - LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature, (&Class::Method), StrOut, \ - this, __VA_ARGS__) - -#define LLDB_RECORD_CHAR_PTR_METHOD_CONST(Result, Class, Method, Signature, \ - StrOut, ...) \ - LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature const, (&Class::Method), \ - StrOut, this, __VA_ARGS__) - -#define LLDB_RECORD_CHAR_PTR_STATIC_METHOD(Result, Class, Method, Signature, \ - StrOut, ...) \ - LLDB_RECORD_CHAR_PTR_(Result(*) Signature, (&Class::Method), StrOut, \ - __VA_ARGS__) - -#define LLDB_RECORD_RESULT(Result) _recorder.RecordResult(Result, true); - -/// The LLDB_RECORD_DUMMY macro is special because it doesn't actually record -/// anything. It's used to track API boundaries when we cannot record for -/// technical reasons. -#define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder _recorder; - -#define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder _recorder; - -namespace lldb_private { -namespace repro { - -template -struct is_trivially_serializable - : std::integral_constant::value || - std::is_enum::value> {}; - -/// Mapping between serialized indices and their corresponding objects. -/// -/// This class is used during replay to map indices back to in-memory objects. -/// -/// When objects are constructed, they are added to this mapping using -/// AddObjectForIndex. -/// -/// When an object is passed to a function, its index is deserialized and -/// AddObjectForIndex returns the corresponding object. If there is no object -/// for the given index, a nullptr is returend. The latter is valid when custom -/// replay code is in place and the actual object is ignored. -class IndexToObject { -public: - /// Returns an object as a pointer for the given index or nullptr if not - /// present in the map. - template T *GetObjectForIndex(unsigned idx) { - assert(idx != 0 && "Cannot get object for sentinel"); - void *object = GetObjectForIndexImpl(idx); - return static_cast(object); - } - - /// Adds a pointer to an object to the mapping for the given index. - template T *AddObjectForIndex(unsigned idx, T *object) { - AddObjectForIndexImpl( - idx, static_cast( - const_cast::type *>(object))); - return object; - } - - /// Adds a reference to an object to the mapping for the given index. - template T &AddObjectForIndex(unsigned idx, T &object) { - AddObjectForIndexImpl( - idx, static_cast( - const_cast::type *>(&object))); - return object; - } - - /// Get all objects sorted by their index. - std::vector GetAllObjects() const; - -private: - /// Helper method that does the actual lookup. The void* result is later cast - /// by the caller. - void *GetObjectForIndexImpl(unsigned idx); - - /// Helper method that does the actual insertion. - void AddObjectForIndexImpl(unsigned idx, void *object); - - /// Keeps a mapping between indices and their corresponding object. - llvm::DenseMap m_mapping; -}; - -/// We need to differentiate between pointers to fundamental and -/// non-fundamental types. See the corresponding Deserializer::Read method -/// for the reason why. -struct PointerTag {}; -struct ReferenceTag {}; -struct ValueTag {}; -struct FundamentalPointerTag {}; -struct FundamentalReferenceTag {}; - -/// Return the deserialization tag for the given type T. -template struct serializer_tag { - typedef typename std::conditional::value, - ValueTag, ReferenceTag>::type type; -}; -template struct serializer_tag { - typedef - typename std::conditional::value, - FundamentalPointerTag, PointerTag>::type type; -}; -template struct serializer_tag { - typedef typename std::conditional::value, - FundamentalReferenceTag, ReferenceTag>::type - type; -}; - -/// Deserializes data from a buffer. It is used to deserialize function indices -/// to replay, their arguments and return values. -/// -/// Fundamental types and strings are read by value. Objects are read by their -/// index, which get translated by the IndexToObject mapping maintained in -/// this class. -/// -/// Additional bookkeeping with regards to the IndexToObject is required to -/// deserialize objects. When a constructor is run or an object is returned by -/// value, we need to capture the object and add it to the index together with -/// its index. This is the job of HandleReplayResult(Void). -class Deserializer { -public: - Deserializer(llvm::StringRef buffer) : m_buffer(buffer) {} - - /// Returns true when the buffer has unread data. - bool HasData(unsigned size) { return size <= m_buffer.size(); } - - /// Deserialize and interpret value as T. - template T Deserialize() { - T t = Read(typename serializer_tag::type()); -#ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; -#endif - return t; - } - - template const T &HandleReplayResult(const T &t) { - CheckSequence(Deserialize()); - unsigned result = Deserialize(); - if (is_trivially_serializable::value) - return t; - // We need to make a copy as the original object might go out of scope. - return *m_index_to_object.AddObjectForIndex(result, new T(t)); - } - - /// Store the returned value in the index-to-object mapping. - template T &HandleReplayResult(T &t) { - CheckSequence(Deserialize()); - unsigned result = Deserialize(); - if (is_trivially_serializable::value) - return t; - // We need to make a copy as the original object might go out of scope. - return *m_index_to_object.AddObjectForIndex(result, new T(t)); - } - - /// Store the returned value in the index-to-object mapping. - template T *HandleReplayResult(T *t) { - CheckSequence(Deserialize()); - unsigned result = Deserialize(); - if (is_trivially_serializable::value) - return t; - return m_index_to_object.AddObjectForIndex(result, t); - } - - /// All returned types are recorded, even when the function returns a void. - /// The latter requires special handling. - void HandleReplayResultVoid() { - CheckSequence(Deserialize()); - unsigned result = Deserialize(); - assert(result == 0); - (void)result; - } - - std::vector GetAllObjects() const { - return m_index_to_object.GetAllObjects(); - } - - void SetExpectedSequence(unsigned sequence) { - m_expected_sequence = sequence; - } - -private: - template T Read(ValueTag) { - assert(HasData(sizeof(T))); - T t; - std::memcpy(reinterpret_cast(&t), m_buffer.data(), sizeof(T)); - m_buffer = m_buffer.drop_front(sizeof(T)); - return t; - } - - template T Read(PointerTag) { - typedef typename std::remove_pointer::type UnderlyingT; - return m_index_to_object.template GetObjectForIndex( - Deserialize()); - } - - template T Read(ReferenceTag) { - typedef typename std::remove_reference::type UnderlyingT; - // If this is a reference to a fundamental type we just read its value. - return *m_index_to_object.template GetObjectForIndex( - Deserialize()); - } - - /// This method is used to parse references to fundamental types. Because - /// they're not recorded in the object table we have serialized their value. - /// We read its value, allocate a copy on the heap, and return a pointer to - /// the copy. - template T Read(FundamentalPointerTag) { - typedef typename std::remove_pointer::type UnderlyingT; - return new UnderlyingT(Deserialize()); - } - - /// This method is used to parse references to fundamental types. Because - /// they're not recorded in the object table we have serialized their value. - /// We read its value, allocate a copy on the heap, and return a reference to - /// the copy. - template T Read(FundamentalReferenceTag) { - // If this is a reference to a fundamental type we just read its value. - typedef typename std::remove_reference::type UnderlyingT; - return *(new UnderlyingT(Deserialize())); - } - - /// Verify that the given sequence number matches what we expect. - void CheckSequence(unsigned sequence); - - /// Mapping of indices to objects. - IndexToObject m_index_to_object; - - /// Buffer containing the serialized data. - llvm::StringRef m_buffer; - - /// The result's expected sequence number. - llvm::Optional m_expected_sequence; -}; - -/// Partial specialization for C-style strings. We read the string value -/// instead of treating it as pointer. -template <> const char *Deserializer::Deserialize(); -template <> const char **Deserializer::Deserialize(); -template <> const uint8_t *Deserializer::Deserialize(); -template <> const void *Deserializer::Deserialize(); -template <> char *Deserializer::Deserialize(); -template <> void *Deserializer::Deserialize(); - -/// Helpers to auto-synthesize function replay code. It deserializes the replay -/// function's arguments one by one and finally calls the corresponding -/// function. -template struct DeserializationHelper; - -template -struct DeserializationHelper { - template struct deserialized { - static Result doit(Deserializer &deserializer, - Result (*f)(Deserialized..., Head, Tail...), - Deserialized... d) { - return DeserializationHelper:: - template deserialized::doit( - deserializer, f, d..., deserializer.Deserialize()); - } - }; -}; - -template <> struct DeserializationHelper<> { - template struct deserialized { - static Result doit(Deserializer &deserializer, Result (*f)(Deserialized...), - Deserialized... d) { - return f(d...); - } - }; -}; - -/// The replayer interface. -struct Replayer { - virtual ~Replayer() = default; - virtual void operator()(Deserializer &deserializer) const = 0; -}; - -/// The default replayer deserializes the arguments and calls the function. -template struct DefaultReplayer; -template -struct DefaultReplayer : public Replayer { - DefaultReplayer(Result (*f)(Args...)) : Replayer(), f(f) {} - - void operator()(Deserializer &deserializer) const override { - Replay(deserializer); - } - - Result Replay(Deserializer &deserializer) const { - return deserializer.HandleReplayResult( - DeserializationHelper::template deserialized::doit( - deserializer, f)); - } - - Result (*f)(Args...); -}; - -/// Partial specialization for function returning a void type. It ignores the -/// (absent) return value. -template -struct DefaultReplayer : public Replayer { - DefaultReplayer(void (*f)(Args...)) : Replayer(), f(f) {} - - void operator()(Deserializer &deserializer) const override { - Replay(deserializer); - } - - void Replay(Deserializer &deserializer) const { - DeserializationHelper::template deserialized::doit( - deserializer, f); - deserializer.HandleReplayResultVoid(); - } - - void (*f)(Args...); -}; - -/// The registry contains a unique mapping between functions and their ID. The -/// IDs can be serialized and deserialized to replay a function. Functions need -/// to be registered with the registry for this to work. -class Registry { -private: - struct SignatureStr { - SignatureStr(llvm::StringRef result = {}, llvm::StringRef scope = {}, - llvm::StringRef name = {}, llvm::StringRef args = {}) - : result(result), scope(scope), name(name), args(args) {} - - std::string ToString() const; - - llvm::StringRef result; - llvm::StringRef scope; - llvm::StringRef name; - llvm::StringRef args; - }; - -public: - Registry() = default; - virtual ~Registry() = default; - - /// Register a default replayer for a function. - template - void Register(Signature *f, llvm::StringRef result = {}, - llvm::StringRef scope = {}, llvm::StringRef name = {}, - llvm::StringRef args = {}) { - DoRegister(uintptr_t(f), std::make_unique>(f), - SignatureStr(result, scope, name, args)); - } - - /// Register a replayer that invokes a custom function with the same - /// signature as the replayed function. - template - void Register(Signature *f, Signature *g, llvm::StringRef result = {}, - llvm::StringRef scope = {}, llvm::StringRef name = {}, - llvm::StringRef args = {}) { - DoRegister(uintptr_t(f), std::make_unique>(g), - SignatureStr(result, scope, name, args)); - } - - /// Replay functions from a file. - bool Replay(const FileSpec &file); - - /// Replay functions from a buffer. - bool Replay(llvm::StringRef buffer); - - /// Replay functions from a deserializer. - bool Replay(Deserializer &deserializer); - - /// Returns the ID for a given function address. - unsigned GetID(uintptr_t addr); - - /// Get the replayer matching the given ID. - Replayer *GetReplayer(unsigned id); - - std::string GetSignature(unsigned id); - - void CheckID(unsigned expected, unsigned actual); - -protected: - /// Register the given replayer for a function (and the ID mapping). - void DoRegister(uintptr_t RunID, std::unique_ptr replayer, - SignatureStr signature); - -private: - /// Mapping of function addresses to replayers and their ID. - std::map, unsigned>> - m_replayers; - - /// Mapping of IDs to replayer instances. - std::map> m_ids; -}; - -/// Maps an object to an index for serialization. Indices are unique and -/// incremented for every new object. -/// -/// Indices start at 1 in order to differentiate with an invalid index (0) in -/// the serialized buffer. -class ObjectToIndex { -public: - template unsigned GetIndexForObject(T *t) { - return GetIndexForObjectImpl(static_cast(t)); - } - -private: - unsigned GetIndexForObjectImpl(const void *object); - - llvm::DenseMap m_mapping; -}; - -/// Serializes functions, their arguments and their return type to a stream. -class Serializer { -public: - Serializer(llvm::raw_ostream &stream = llvm::outs()) : m_stream(stream) {} - - /// Recursively serialize all the given arguments. - template - void SerializeAll(const Head &head, const Tail &... tail) { - Serialize(head); - SerializeAll(tail...); - } - - void SerializeAll() { m_stream.flush(); } - -private: - /// Serialize pointers. We need to differentiate between pointers to - /// fundamental types (in which case we serialize its value) and pointer to - /// objects (in which case we serialize their index). - template void Serialize(T *t) { -#ifdef LLDB_REPRO_INSTR_TRACE - this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; -#endif - if (std::is_fundamental::value) { - Serialize(*t); - } else { - unsigned idx = m_tracker.GetIndexForObject(t); - Serialize(idx); - } - } - - /// Serialize references. We need to differentiate between references to - /// fundamental types (in which case we serialize its value) and references - /// to objects (in which case we serialize their index). - template void Serialize(T &t) { -#ifdef LLDB_REPRO_INSTR_TRACE - this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; -#endif - if (is_trivially_serializable::value) { - m_stream.write(reinterpret_cast(&t), sizeof(T)); - } else { - unsigned idx = m_tracker.GetIndexForObject(&t); - Serialize(idx); - } - } - - void Serialize(const void *v) { - // FIXME: Support void* - } - - void Serialize(void *v) { - // FIXME: Support void* - } - - void Serialize(const char *t) { -#ifdef LLDB_REPRO_INSTR_TRACE - this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " - << stringify_args(t) << "\n"; -#endif - const size_t size = t ? strlen(t) : std::numeric_limits::max(); - Serialize(size); - if (t) { - m_stream << t; - m_stream.write(0x0); - } - } - - void Serialize(const char **t) { - size_t size = 0; - if (!t) { - Serialize(size); - return; - } - - // Compute the size of the array. - const char *const *temp = t; - while (*temp++) - size++; - Serialize(size); - - // Serialize the content of the array. - while (*t) - Serialize(*t++); - } - - /// Serialization stream. - llvm::raw_ostream &m_stream; - - /// Mapping of objects to indices. - ObjectToIndex m_tracker; -}; // namespace repro - -class InstrumentationData { -public: - Serializer *GetSerializer() { return m_serializer; } - Deserializer *GetDeserializer() { return m_deserializer; } - Registry &GetRegistry() { return *m_registry; } - - operator bool() { - return (m_serializer != nullptr || m_deserializer != nullptr) && - m_registry != nullptr; - } - - static void Initialize(Serializer &serializer, Registry ®istry); - static void Initialize(Deserializer &serializer, Registry ®istry); - static InstrumentationData &Instance(); - -protected: - friend llvm::optional_detail::OptionalStorage; - friend llvm::Optional; - - InstrumentationData() = default; - InstrumentationData(Serializer &serializer, Registry ®istry) - : m_serializer(&serializer), m_deserializer(nullptr), - m_registry(®istry) {} - InstrumentationData(Deserializer &deserializer, Registry ®istry) - : m_serializer(nullptr), m_deserializer(&deserializer), - m_registry(®istry) {} - -private: - static llvm::Optional &InstanceImpl(); - - Serializer *m_serializer = nullptr; - Deserializer *m_deserializer = nullptr; - Registry *m_registry = nullptr; -}; - -struct EmptyArg {}; - -/// RAII object that records function invocations and their return value. -/// -/// API calls are only captured when the API boundary is crossed. Once we're in -/// the API layer, and another API function is called, it doesn't need to be -/// recorded. -/// -/// When a call is recored, its result is always recorded as well, even if the -/// function returns a void. For functions that return by value, RecordResult -/// should be used. Otherwise a sentinel value (0) will be serialized. -/// -/// Because of the functional overlap between logging and recording API calls, -/// this class is also used for logging. -class Recorder { -public: - Recorder(); - Recorder(llvm::StringRef pretty_func, std::string &&pretty_args = {}); - ~Recorder(); - - /// Records a single function call. - template - void Record(Serializer &serializer, Registry ®istry, Result (*f)(FArgs...), - const RArgs &... args) { - m_serializer = &serializer; - if (!ShouldCapture()) - return; - - std::lock_guard lock(g_mutex); - unsigned sequence = GetSequenceNumber(); - unsigned id = registry.GetID(uintptr_t(f)); - -#ifdef LLDB_REPRO_INSTR_TRACE - Log(id); -#endif - - serializer.SerializeAll(sequence); - serializer.SerializeAll(id); - serializer.SerializeAll(args...); - - if (std::is_class::type>::type>::value) { - m_result_recorded = false; - } else { - serializer.SerializeAll(sequence); - serializer.SerializeAll(0); - m_result_recorded = true; - } - } - - /// Records a single function call. - template - void Record(Serializer &serializer, Registry ®istry, void (*f)(Args...), - const Args &... args) { - m_serializer = &serializer; - if (!ShouldCapture()) - return; - - std::lock_guard lock(g_mutex); - unsigned sequence = GetSequenceNumber(); - unsigned id = registry.GetID(uintptr_t(f)); - -#ifdef LLDB_REPRO_INSTR_TRACE - Log(id); -#endif - - serializer.SerializeAll(sequence); - serializer.SerializeAll(id); - serializer.SerializeAll(args...); - - // Record result. - serializer.SerializeAll(sequence); - serializer.SerializeAll(0); - m_result_recorded = true; - } - - /// Specializations for the no-argument methods. These are passed an empty - /// dummy argument so the same variadic macro can be used. These methods - /// strip the arguments before forwarding them. - template - void Record(Serializer &serializer, Registry ®istry, Result (*f)(), - const EmptyArg &arg) { - Record(serializer, registry, f); - } - - /// Record the result of a function call. - template - Result RecordResult(Result &&r, bool update_boundary) { - // When recording the result from the LLDB_RECORD_RESULT macro, we need to - // update the boundary so we capture the copy constructor. However, when - // called to record the this pointer of the (copy) constructor, the - // boundary should not be toggled, because it is called from the - // LLDB_RECORD_CONSTRUCTOR macro, which might be followed by other API - // calls. - if (update_boundary) - UpdateBoundary(); - if (m_serializer && ShouldCapture()) { - std::lock_guard lock(g_mutex); - assert(!m_result_recorded); - m_serializer->SerializeAll(GetSequenceNumber()); - m_serializer->SerializeAll(r); - m_result_recorded = true; - } - return std::forward(r); - } - - template - Result Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr, - bool update_boundary) { - deserializer.SetExpectedSequence(deserializer.Deserialize()); - unsigned actual_id = registry.GetID(addr); - unsigned id = deserializer.Deserialize(); - registry.CheckID(id, actual_id); - return ReplayResult( - static_cast *>(registry.GetReplayer(id)) - ->Replay(deserializer), - update_boundary); - } - - void Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr) { - deserializer.SetExpectedSequence(deserializer.Deserialize()); - unsigned actual_id = registry.GetID(addr); - unsigned id = deserializer.Deserialize(); - registry.CheckID(id, actual_id); - registry.GetReplayer(id)->operator()(deserializer); - } - - template - Result ReplayResult(Result &&r, bool update_boundary) { - if (update_boundary) - UpdateBoundary(); - return std::forward(r); - } - - bool ShouldCapture() { return m_local_boundary; } - - /// Mark the current thread as a private thread and pretend that everything - /// on this thread is behind happening behind the API boundary. - static void PrivateThread() { g_global_boundary = true; } - -private: - static unsigned GetNextSequenceNumber() { return g_sequence++; } - unsigned GetSequenceNumber() const; - - template friend struct replay; - void UpdateBoundary() { - if (m_local_boundary) - g_global_boundary = false; - } - -#ifdef LLDB_REPRO_INSTR_TRACE - void Log(unsigned id) { - this_thread_id() << "Recording " << id << ": " << m_pretty_func << " (" - << m_pretty_args << ")\n"; - } -#endif - - Serializer *m_serializer = nullptr; - - /// Pretty function for logging. - llvm::StringRef m_pretty_func; - std::string m_pretty_args; - - /// Whether this function call was the one crossing the API boundary. - bool m_local_boundary = false; - - /// Whether the return value was recorded explicitly. - bool m_result_recorded = true; - - /// The sequence number for this pair of function and result. - unsigned m_sequence; - - /// Whether we're currently across the API boundary. - static thread_local bool g_global_boundary; - - /// Global mutex to protect concurrent access. - static std::mutex g_mutex; - - /// Unique, monotonically increasing sequence number. - static std::atomic g_sequence; -}; - -/// To be used as the "Runtime ID" of a constructor. It also invokes the -/// constructor when called. -template struct construct; -template struct construct { - static Class *handle(lldb_private::repro::InstrumentationData data, - lldb_private::repro::Recorder &recorder, Class *c, - const EmptyArg &) { - return handle(data, recorder, c); - } - - static Class *handle(lldb_private::repro::InstrumentationData data, - lldb_private::repro::Recorder &recorder, Class *c, - Args... args) { - if (!data) - return nullptr; - - if (Serializer *serializer = data.GetSerializer()) { - recorder.Record(*serializer, data.GetRegistry(), &record, args...); - recorder.RecordResult(c, false); - } else if (Deserializer *deserializer = data.GetDeserializer()) { - if (recorder.ShouldCapture()) { - replay(recorder, *deserializer, data.GetRegistry()); - } - } - - return nullptr; - } - - static Class *record(Args... args) { return new Class(args...); } - - static Class *replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - return recorder.Replay( - deserializer, registry, uintptr_t(&record), false); - } -}; - -/// To be used as the "Runtime ID" of a member function. It also invokes the -/// member function when called. -template struct invoke; -template -struct invoke { - template struct method { - static Result record(Class *c, Args... args) { return (c->*m)(args...); } - - static Result replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - return recorder.Replay( - deserializer, registry, uintptr_t(&record), true); - } - }; -}; - -template -struct invoke { - template struct method { - static void record(Class *c, Args... args) { (c->*m)(args...); } - static void replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - recorder.Replay(deserializer, registry, uintptr_t(&record)); - } - }; -}; - -template -struct invoke { - template struct method { - static Result record(Class *c, Args... args) { return (c->*m)(args...); } - static Result replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - return recorder.Replay( - deserializer, registry, uintptr_t(&record), true); - } - }; -}; - -template -struct invoke { - template struct method { - static void record(Class *c, Args... args) { return (c->*m)(args...); } - static void replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - recorder.Replay(deserializer, registry, uintptr_t(&record)); - } - }; -}; - -template struct replay; - -template -struct replay { - template struct method {}; -}; - -template -struct invoke { - template struct method { - static Result record(Args... args) { return (*m)(args...); } - static Result replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - return recorder.Replay(deserializer, registry, - uintptr_t(&record), true); - } - }; -}; - -template struct invoke { - template struct method { - static void record(Args... args) { return (*m)(args...); } - static void replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry) { - recorder.Replay(deserializer, registry, uintptr_t(&record)); - } - }; -}; - -/// Special handling for functions returning strings as (char*, size_t). -/// { - -/// For inline replay, we ignore the arguments and use the ones from the -/// serializer instead. This doesn't work for methods that use a char* and a -/// size to return a string. For one these functions have a custom replayer to -/// prevent override the input buffer. Furthermore, the template-generated -/// deserialization is not easy to hook into. -/// -/// The specializations below hand-implement the serialization logic for the -/// inline replay. Instead of using the function from the registry, it uses the -/// one passed into the macro. -template struct invoke_char_ptr; -template -struct invoke_char_ptr { - template struct method { - static Result record(Class *c, char *s, size_t l) { - char *buffer = reinterpret_cast(calloc(l, sizeof(char))); - return (c->*m)(buffer, l); - } - - static Result replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry, char *str) { - deserializer.SetExpectedSequence(deserializer.Deserialize()); - deserializer.Deserialize(); - Class *c = deserializer.Deserialize(); - deserializer.Deserialize(); - size_t l = deserializer.Deserialize(); - return recorder.ReplayResult( - std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true); - } - }; -}; - -template struct invoke_char_ptr; -template -struct invoke_char_ptr { - template struct method { - static Result record(Class *c, char *s, size_t l) { - char *buffer = reinterpret_cast(calloc(l, sizeof(char))); - return (c->*m)(buffer, l); - } - - static Result replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry, char *str) { - deserializer.SetExpectedSequence(deserializer.Deserialize()); - deserializer.Deserialize(); - Class *c = deserializer.Deserialize(); - deserializer.Deserialize(); - size_t l = deserializer.Deserialize(); - return recorder.ReplayResult( - std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true); - } - }; -}; - -template -struct invoke_char_ptr { - template struct method { - static Result record(char *s, size_t l) { - char *buffer = reinterpret_cast(calloc(l, sizeof(char))); - return (*m)(buffer, l); - } - - static Result replay(Recorder &recorder, Deserializer &deserializer, - Registry ®istry, char *str) { - deserializer.SetExpectedSequence(deserializer.Deserialize()); - deserializer.Deserialize(); - deserializer.Deserialize(); - size_t l = deserializer.Deserialize(); - return recorder.ReplayResult( - std::move(deserializer.HandleReplayResult((*m)(str, l))), true); - } - }; -}; -/// } - -} // namespace repro -} // namespace lldb_private - -#endif // LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/ReproducerProvider.h b/gnu/llvm/lldb/include/lldb/Utility/ReproducerProvider.h deleted file mode 100644 index db7378069a8..00000000000 --- a/gnu/llvm/lldb/include/lldb/Utility/ReproducerProvider.h +++ /dev/null @@ -1,435 +0,0 @@ -//===-- Reproducer.h --------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UTILITY_REPRODUCER_PROVIDER_H -#define LLDB_UTILITY_REPRODUCER_PROVIDER_H - -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/ProcessInfo.h" -#include "lldb/Utility/Reproducer.h" -#include "lldb/Utility/UUID.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/FileCollector.h" -#include "llvm/Support/YAMLTraits.h" - -#include -#include -#include - -namespace lldb_private { -namespace repro { - -/// The recorder is a small object handed out by a provider to record data. It -/// is commonly used in combination with a MultiProvider which is meant to -/// record information for multiple instances of the same source of data. -class AbstractRecorder { -protected: - AbstractRecorder(const FileSpec &filename, std::error_code &ec) - : m_filename(filename.GetFilename().GetStringRef()), - m_os(filename.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF), - m_record(true) {} - -public: - const FileSpec &GetFilename() { return m_filename; } - - void Stop() { - assert(m_record); - m_record = false; - } - -private: - FileSpec m_filename; - -protected: - llvm::raw_fd_ostream m_os; - bool m_record; -}; - -/// Recorder that records its data as text to a file. -class DataRecorder : public AbstractRecorder { -public: - DataRecorder(const FileSpec &filename, std::error_code &ec) - : AbstractRecorder(filename, ec) {} - - static llvm::Expected> - Create(const FileSpec &filename); - - template void Record(const T &t, bool newline = false) { - if (!m_record) - return; - m_os << t; - if (newline) - m_os << '\n'; - m_os.flush(); - } -}; - -/// Recorder that records its data as YAML to a file. -class YamlRecorder : public AbstractRecorder { -public: - YamlRecorder(const FileSpec &filename, std::error_code &ec) - : AbstractRecorder(filename, ec) {} - - static llvm::Expected> - Create(const FileSpec &filename); - - template void Record(const T &t) { - if (!m_record) - return; - llvm::yaml::Output yout(m_os); - // The YAML traits are defined as non-const because they are used for - // serialization and deserialization. The cast is safe because - // serialization doesn't modify the object. - yout << const_cast(t); - m_os.flush(); - } -}; - -class FlushingFileCollector : public llvm::FileCollectorBase { -public: - FlushingFileCollector(llvm::StringRef files_path, llvm::StringRef dirs_path, - std::error_code &ec); - -protected: - void addFileImpl(llvm::StringRef file) override; - - llvm::vfs::directory_iterator - addDirectoryImpl(const llvm::Twine &dir, - llvm::IntrusiveRefCntPtr vfs, - std::error_code &dir_ec) override; - - llvm::Optional m_files_os; - llvm::Optional m_dirs_os; -}; - -class FileProvider : public Provider { -public: - struct Info { - static const char *name; - static const char *file; - }; - - FileProvider(const FileSpec &directory) : Provider(directory) { - std::error_code ec; - m_collector = std::make_shared( - directory.CopyByAppendingPathComponent("files.txt").GetPath(), - directory.CopyByAppendingPathComponent("dirs.txt").GetPath(), ec); - if (ec) - m_collector.reset(); - } - - std::shared_ptr GetFileCollector() { - return m_collector; - } - - void RecordInterestingDirectory(const llvm::Twine &dir); - void RecordInterestingDirectoryRecursive(const llvm::Twine &dir); - - static char ID; - -private: - std::shared_ptr m_collector; -}; - -/// Provider for the LLDB version number. -/// -/// When the reproducer is kept, it writes the lldb version to a file named -/// version.txt in the reproducer root. -class VersionProvider : public Provider { -public: - VersionProvider(const FileSpec &directory) : Provider(directory) {} - struct Info { - static const char *name; - static const char *file; - }; - void SetVersion(std::string version) { - assert(m_version.empty()); - m_version = std::move(version); - } - void Keep() override; - std::string m_version; - static char ID; -}; - -/// Abstract provider to storing directory paths. -template class DirectoryProvider : public repro::Provider { -public: - DirectoryProvider(const FileSpec &root) : Provider(root) {} - void SetDirectory(std::string directory) { - m_directory = std::move(directory); - } - llvm::StringRef GetDirectory() { return m_directory; } - - void Keep() override { - FileSpec file = this->GetRoot().CopyByAppendingPathComponent(T::Info::file); - std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); - if (ec) - return; - os << m_directory << "\n"; - } - -protected: - std::string m_directory; -}; - -/// Provider for the current working directory. -/// -/// When the reproducer is kept, it writes lldb's current working directory to -/// a file named cwd.txt in the reproducer root. -class WorkingDirectoryProvider - : public DirectoryProvider { -public: - WorkingDirectoryProvider(const FileSpec &directory) - : DirectoryProvider(directory) { - llvm::SmallString<128> cwd; - if (std::error_code EC = llvm::sys::fs::current_path(cwd)) - return; - SetDirectory(std::string(cwd)); - } - struct Info { - static const char *name; - static const char *file; - }; - static char ID; -}; - -/// Provider for the home directory. -/// -/// When the reproducer is kept, it writes the user's home directory to a file -/// a file named home.txt in the reproducer root. -class HomeDirectoryProvider : public DirectoryProvider { -public: - HomeDirectoryProvider(const FileSpec &directory) - : DirectoryProvider(directory) { - llvm::SmallString<128> home_dir; - llvm::sys::path::home_directory(home_dir); - SetDirectory(std::string(home_dir)); - } - struct Info { - static const char *name; - static const char *file; - }; - static char ID; -}; - -/// Provider for mapping UUIDs to symbol and executable files. -class SymbolFileProvider : public Provider { -public: - SymbolFileProvider(const FileSpec &directory) - : Provider(directory), m_symbol_files() {} - - void AddSymbolFile(const UUID *uuid, const FileSpec &module_path, - const FileSpec &symbol_path); - void Keep() override; - - struct Entry { - Entry() = default; - Entry(std::string uuid) : uuid(std::move(uuid)) {} - Entry(std::string uuid, std::string module_path, std::string symbol_path) - : uuid(std::move(uuid)), module_path(std::move(module_path)), - symbol_path(std::move(symbol_path)) {} - - bool operator==(const Entry &rhs) const { return uuid == rhs.uuid; } - bool operator<(const Entry &rhs) const { return uuid < rhs.uuid; } - - std::string uuid; - std::string module_path; - std::string symbol_path; - }; - - struct Info { - static const char *name; - static const char *file; - }; - static char ID; - -private: - std::vector m_symbol_files; -}; - -/// The MultiProvider is a provider that hands out recorder which can be used -/// to capture data for different instances of the same object. The recorders -/// can be passed around or stored as an instance member. -/// -/// The Info::file for the MultiProvider contains an index of files for every -/// recorder. Use the MultiLoader to read the index and get the individual -/// files. -template -class MultiProvider : public repro::Provider { -public: - MultiProvider(const FileSpec &directory) : Provider(directory) {} - - T *GetNewRecorder() { - std::size_t i = m_recorders.size() + 1; - std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") + - llvm::Twine(i) + llvm::Twine(".yaml")) - .str(); - auto recorder_or_error = - T::Create(this->GetRoot().CopyByAppendingPathComponent(filename)); - if (!recorder_or_error) { - llvm::consumeError(recorder_or_error.takeError()); - return nullptr; - } - - m_recorders.push_back(std::move(*recorder_or_error)); - return m_recorders.back().get(); - } - - void Keep() override { - std::vector files; - for (auto &recorder : m_recorders) { - recorder->Stop(); - files.push_back(recorder->GetFilename().GetPath()); - } - - FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file); - std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); - if (ec) - return; - llvm::yaml::Output yout(os); - yout << files; - } - - void Discard() override { m_recorders.clear(); } - -private: - std::vector> m_recorders; -}; - -class CommandProvider : public MultiProvider { -public: - struct Info { - static const char *name; - static const char *file; - }; - - CommandProvider(const FileSpec &directory) - : MultiProvider(directory) {} - - static char ID; -}; - -class ProcessInfoRecorder : public AbstractRecorder { -public: - ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec) - : AbstractRecorder(filename, ec) {} - - static llvm::Expected> - Create(const FileSpec &filename); - - void Record(const ProcessInstanceInfoList &process_infos); -}; - -class ProcessInfoProvider : public repro::Provider { -public: - struct Info { - static const char *name; - static const char *file; - }; - - ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {} - - ProcessInfoRecorder *GetNewProcessInfoRecorder(); - - void Keep() override; - void Discard() override; - - static char ID; - -private: - std::unique_ptr m_stream_up; - std::vector> m_process_info_recorders; -}; - -/// Loader for data captured with the MultiProvider. It will read the index and -/// return the path to the files in the index. -template class MultiLoader { -public: - MultiLoader(std::vector files) : m_files(std::move(files)) {} - - static std::unique_ptr Create(Loader *loader) { - if (!loader) - return {}; - - FileSpec file = loader->GetFile(); - if (!file) - return {}; - - auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); - if (auto err = error_or_file.getError()) - return {}; - - std::vector files; - llvm::yaml::Input yin((*error_or_file)->getBuffer()); - yin >> files; - - if (auto err = yin.error()) - return {}; - - for (auto &file : files) { - FileSpec absolute_path = - loader->GetRoot().CopyByAppendingPathComponent(file); - file = absolute_path.GetPath(); - } - - return std::make_unique>(std::move(files)); - } - - llvm::Optional GetNextFile() { - if (m_index >= m_files.size()) - return {}; - return m_files[m_index++]; - } - -private: - std::vector m_files; - unsigned m_index = 0; -}; - -class SymbolFileLoader { -public: - SymbolFileLoader(Loader *loader); - std::pair GetPaths(const UUID *uuid) const; - -private: - // Sorted list of UUID to path mappings. - std::vector m_symbol_files; -}; - -/// Helper to read directories written by the DirectoryProvider. -template -llvm::Expected GetDirectoryFrom(repro::Loader *loader) { - llvm::Expected dir = loader->LoadBuffer(); - if (!dir) - return dir.takeError(); - return std::string(llvm::StringRef(*dir).rtrim()); -} - -} // namespace repro -} // namespace lldb_private - -LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::repro::SymbolFileProvider::Entry) - -namespace llvm { -namespace yaml { -template <> -struct MappingTraits { - static void mapping(IO &io, - lldb_private::repro::SymbolFileProvider::Entry &entry) { - io.mapRequired("uuid", entry.uuid); - io.mapRequired("module-path", entry.module_path); - io.mapRequired("symbol-path", entry.symbol_path); - } -}; -} // namespace yaml -} // namespace llvm - -#endif // LLDB_UTILITY_REPRODUCER_PROVIDER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h b/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h deleted file mode 100644 index d234cbea85c..00000000000 --- a/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h +++ /dev/null @@ -1,35 +0,0 @@ -//===-- StreamCallback.h -----------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UTILITY_STREAMCALLBACK_H -#define LLDB_UTILITY_STREAMCALLBACK_H - -#include "lldb/lldb-types.h" -#include "llvm/Support/raw_ostream.h" - -#include -#include - -namespace lldb_private { - -class StreamCallback : public llvm::raw_ostream { -public: - StreamCallback(lldb::LogOutputCallback callback, void *baton); - ~StreamCallback() override = default; - -private: - lldb::LogOutputCallback m_callback; - void *m_baton; - - void write_impl(const char *Ptr, size_t Size) override; - uint64_t current_pos() const override; -}; - -} // namespace lldb_private - -#endif // LLDB_UTILITY_STREAMCALLBACK_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private-defines.h b/gnu/llvm/lldb/include/lldb/lldb-private-defines.h deleted file mode 100644 index d66e6ef1518..00000000000 --- a/gnu/llvm/lldb/include/lldb/lldb-private-defines.h +++ /dev/null @@ -1,36 +0,0 @@ -//===-- lldb-private-defines.h ----------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_LLDB_PRIVATE_DEFINES_H -#define LLDB_LLDB_PRIVATE_DEFINES_H - -#if defined(__cplusplus) - -// Include Compiler.h here so we don't define LLVM_FALLTHROUGH and then -// Compiler.h later tries to redefine it. -#include "llvm/Support/Compiler.h" - -#ifndef LLVM_FALLTHROUGH - -#ifndef __has_cpp_attribute -#define __has_cpp_attribute(x) 0 -#endif - -/// \macro LLVM_FALLTHROUGH -/// Marks an empty statement preceding a deliberate switch fallthrough. -#if __has_cpp_attribute(clang::fallthrough) -#define LLVM_FALLTHROUGH [[clang::fallthrough]] -#else -#define LLVM_FALLTHROUGH -#endif - -#endif // ifndef LLVM_FALLTHROUGH - -#endif // #if defined(__cplusplus) - -#endif // LLDB_LLDB_PRIVATE_DEFINES_H diff --git a/gnu/llvm/lldb/packages/Python/lldbconfig/__init__.py b/gnu/llvm/lldb/packages/Python/lldbconfig/__init__.py deleted file mode 100644 index 6c43d709df7..00000000000 --- a/gnu/llvm/lldb/packages/Python/lldbconfig/__init__.py +++ /dev/null @@ -1 +0,0 @@ -INITIALIZE = True diff --git a/gnu/llvm/lldb/source/API/SBReproducerPrivate.h b/gnu/llvm/lldb/source/API/SBReproducerPrivate.h deleted file mode 100644 index 02ac31c2ad8..00000000000 --- a/gnu/llvm/lldb/source/API/SBReproducerPrivate.h +++ /dev/null @@ -1,78 +0,0 @@ -//===-- SBReproducerPrivate.h -----------------------------------*- C++ -*-===// -// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_API_SBREPRODUCERPRIVATE_H -#define LLDB_SOURCE_API_SBREPRODUCERPRIVATE_H - -#include "lldb/API/SBReproducer.h" - -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Reproducer.h" -#include "lldb/Utility/ReproducerInstrumentation.h" -#include "lldb/Utility/ReproducerProvider.h" - -#include "llvm/ADT/DenseMap.h" - -#define LLDB_GET_INSTRUMENTATION_DATA() \ - lldb_private::repro::InstrumentationData::Instance() - -namespace lldb_private { -namespace repro { - -class SBRegistry : public Registry { -public: - SBRegistry(); -}; - -class SBProvider : public Provider { -public: - struct Info { - static const char *name; - static const char *file; - }; - - SBProvider(const FileSpec &directory) - : Provider(directory), - m_stream(directory.CopyByAppendingPathComponent("sbapi.bin").GetPath(), - m_ec, llvm::sys::fs::OpenFlags::OF_None), - m_serializer(m_stream) {} - - Serializer &GetSerializer() { return m_serializer; } - Registry &GetRegistry() { return m_registry; } - - static char ID; - -private: - std::error_code m_ec; - llvm::raw_fd_ostream m_stream; - Serializer m_serializer; - SBRegistry m_registry; -}; - -class ReplayData { -public: - ReplayData(std::unique_ptr memory_buffer) - : m_memory_buffer(std::move(memory_buffer)), m_registry(), - m_deserializer(m_memory_buffer->getBuffer()) {} - Deserializer &GetDeserializer() { return m_deserializer; } - Registry &GetRegistry() { return m_registry; } - -private: - std::unique_ptr m_memory_buffer; - SBRegistry m_registry; - Deserializer m_deserializer; -}; - -template void RegisterMethods(Registry &R); - -} // namespace repro -} // namespace lldb_private - -#endif diff --git a/gnu/llvm/lldb/source/API/liblldb.xcode.exports b/gnu/llvm/lldb/source/API/liblldb.xcode.exports deleted file mode 100644 index 9c194fa6ff6..00000000000 --- a/gnu/llvm/lldb/source/API/liblldb.xcode.exports +++ /dev/null @@ -1,3 +0,0 @@ -__ZN4lldb* -__ZNK4lldb* -_init_lld* diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp deleted file mode 100644 index 01f9dc64e6f..00000000000 --- a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp +++ /dev/null @@ -1,722 +0,0 @@ -//===-- CommandObjectReproducer.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 "CommandObjectReproducer.h" - -#include "lldb/Host/HostInfo.h" -#include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/OptionArgParser.h" -#include "lldb/Utility/GDBRemote.h" -#include "lldb/Utility/ProcessInfo.h" -#include "lldb/Utility/Reproducer.h" - -#include - -using namespace lldb; -using namespace llvm; -using namespace lldb_private; -using namespace lldb_private::repro; - -enum ReproducerProvider { - eReproducerProviderCommands, - eReproducerProviderFiles, - eReproducerProviderSymbolFiles, - eReproducerProviderGDB, - eReproducerProviderProcessInfo, - eReproducerProviderVersion, - eReproducerProviderWorkingDirectory, - eReproducerProviderHomeDirectory, - eReproducerProviderNone -}; - -static constexpr OptionEnumValueElement g_reproducer_provider_type[] = { - { - eReproducerProviderCommands, - "commands", - "Command Interpreter Commands", - }, - { - eReproducerProviderFiles, - "files", - "Files", - }, - { - eReproducerProviderSymbolFiles, - "symbol-files", - "Symbol Files", - }, - { - eReproducerProviderGDB, - "gdb", - "GDB Remote Packets", - }, - { - eReproducerProviderProcessInfo, - "processes", - "Process Info", - }, - { - eReproducerProviderVersion, - "version", - "Version", - }, - { - eReproducerProviderWorkingDirectory, - "cwd", - "Working Directory", - }, - { - eReproducerProviderHomeDirectory, - "home", - "Home Directory", - }, - { - eReproducerProviderNone, - "none", - "None", - }, -}; - -static constexpr OptionEnumValues ReproducerProviderType() { - return OptionEnumValues(g_reproducer_provider_type); -} - -#define LLDB_OPTIONS_reproducer_dump -#include "CommandOptions.inc" - -enum ReproducerCrashSignal { - eReproducerCrashSigill, - eReproducerCrashSigsegv, -}; - -static constexpr OptionEnumValueElement g_reproducer_signaltype[] = { - { - eReproducerCrashSigill, - "SIGILL", - "Illegal instruction", - }, - { - eReproducerCrashSigsegv, - "SIGSEGV", - "Segmentation fault", - }, -}; - -static constexpr OptionEnumValues ReproducerSignalType() { - return OptionEnumValues(g_reproducer_signaltype); -} - -#define LLDB_OPTIONS_reproducer_xcrash -#include "CommandOptions.inc" - -#define LLDB_OPTIONS_reproducer_verify -#include "CommandOptions.inc" - -template -llvm::Expected static ReadFromYAML(StringRef filename) { - auto error_or_file = MemoryBuffer::getFile(filename); - if (auto err = error_or_file.getError()) { - return errorCodeToError(err); - } - - T t; - yaml::Input yin((*error_or_file)->getBuffer()); - yin >> t; - - if (auto err = yin.error()) { - return errorCodeToError(err); - } - - return t; -} - -static void SetError(CommandReturnObject &result, Error err) { - result.AppendError(toString(std::move(err))); -} - -/// Create a loader from the given path if specified. Otherwise use the current -/// loader used for replay. -static Loader * -GetLoaderFromPathOrCurrent(llvm::Optional &loader_storage, - CommandReturnObject &result, - FileSpec reproducer_path) { - if (reproducer_path) { - loader_storage.emplace(reproducer_path); - Loader *loader = &(*loader_storage); - if (Error err = loader->LoadIndex()) { - // This is a hard error and will set the result to eReturnStatusFailed. - SetError(result, std::move(err)); - return nullptr; - } - return loader; - } - - if (Loader *loader = Reproducer::Instance().GetLoader()) - return loader; - - // This is a soft error because this is expected to fail during capture. - result.AppendError( - "Not specifying a reproducer is only support during replay."); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return nullptr; -} - -class CommandObjectReproducerGenerate : public CommandObjectParsed { -public: - CommandObjectReproducerGenerate(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "reproducer generate", - "Generate reproducer on disk. When the debugger is in capture " - "mode, this command will output the reproducer to a directory on " - "disk and quit. In replay mode this command in a no-op.", - nullptr) {} - - ~CommandObjectReproducerGenerate() override = default; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - auto &r = Reproducer::Instance(); - if (auto generator = r.GetGenerator()) { - generator->Keep(); - if (llvm::Error e = repro::Finalize(r.GetReproducerPath())) { - SetError(result, std::move(e)); - return result.Succeeded(); - } - } else if (r.IsReplaying()) { - // Make this operation a NO-OP in replay mode. - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } else { - result.AppendErrorWithFormat("Unable to get the reproducer generator"); - return false; - } - - result.GetOutputStream() - << "Reproducer written to '" << r.GetReproducerPath() << "'\n"; - result.GetOutputStream() - << "Please have a look at the directory to assess if you're willing to " - "share the contained information.\n"; - - m_interpreter.BroadcastEvent( - CommandInterpreter::eBroadcastBitQuitCommandReceived); - result.SetStatus(eReturnStatusQuit); - return result.Succeeded(); - } -}; - -class CommandObjectReproducerXCrash : public CommandObjectParsed { -public: - CommandObjectReproducerXCrash(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer xcrash", - "Intentionally force the debugger to crash in " - "order to trigger and test reproducer generation.", - nullptr) {} - - ~CommandObjectReproducerXCrash() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() : Options() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 's': - signal = (ReproducerCrashSignal)OptionArgParser::ToOptionEnum( - option_arg, GetDefinitions()[option_idx].enum_values, 0, error); - if (!error.Success()) - error.SetErrorStringWithFormat("unrecognized value for signal '%s'", - option_arg.str().c_str()); - break; - default: - llvm_unreachable("Unimplemented option"); - } - - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - signal = eReproducerCrashSigsegv; - } - - ArrayRef GetDefinitions() override { - return makeArrayRef(g_reproducer_xcrash_options); - } - - ReproducerCrashSignal signal = eReproducerCrashSigsegv; - }; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - auto &r = Reproducer::Instance(); - - if (!r.IsCapturing() && !r.IsReplaying()) { - result.AppendError( - "forcing a crash is only supported when capturing a reproducer."); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return false; - } - - switch (m_options.signal) { - case eReproducerCrashSigill: - std::raise(SIGILL); - break; - case eReproducerCrashSigsegv: - std::raise(SIGSEGV); - break; - } - - result.SetStatus(eReturnStatusQuit); - return result.Succeeded(); - } - -private: - CommandOptions m_options; -}; - -class CommandObjectReproducerStatus : public CommandObjectParsed { -public: - CommandObjectReproducerStatus(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "reproducer status", - "Show the current reproducer status. In capture mode the " - "debugger " - "is collecting all the information it needs to create a " - "reproducer. In replay mode the reproducer is replaying a " - "reproducer. When the reproducers are off, no data is collected " - "and no reproducer can be generated.", - nullptr) {} - - ~CommandObjectReproducerStatus() override = default; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - auto &r = Reproducer::Instance(); - if (r.IsCapturing()) { - result.GetOutputStream() << "Reproducer is in capture mode.\n"; - } else if (r.IsReplaying()) { - result.GetOutputStream() << "Reproducer is in replay mode.\n"; - } else { - result.GetOutputStream() << "Reproducer is off.\n"; - } - - if (r.IsCapturing() || r.IsReplaying()) { - result.GetOutputStream() - << "Path: " << r.GetReproducerPath().GetPath() << '\n'; - } - - // Auto generate is hidden unless enabled because this is mostly for - // development and testing. - if (Generator *g = r.GetGenerator()) { - if (g->IsAutoGenerate()) - result.GetOutputStream() << "Auto generate: on\n"; - } - - result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); - } -}; - -class CommandObjectReproducerDump : public CommandObjectParsed { -public: - CommandObjectReproducerDump(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer dump", - "Dump the information contained in a reproducer. " - "If no reproducer is specified during replay, it " - "dumps the content of the current reproducer.", - nullptr) {} - - ~CommandObjectReproducerDump() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() : Options(), file() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'f': - file.SetFile(option_arg, FileSpec::Style::native); - FileSystem::Instance().Resolve(file); - break; - case 'p': - provider = (ReproducerProvider)OptionArgParser::ToOptionEnum( - option_arg, GetDefinitions()[option_idx].enum_values, 0, error); - if (!error.Success()) - error.SetErrorStringWithFormat("unrecognized value for provider '%s'", - option_arg.str().c_str()); - break; - default: - llvm_unreachable("Unimplemented option"); - } - - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - file.Clear(); - provider = eReproducerProviderNone; - } - - ArrayRef GetDefinitions() override { - return makeArrayRef(g_reproducer_dump_options); - } - - FileSpec file; - ReproducerProvider provider = eReproducerProviderNone; - }; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - llvm::Optional loader_storage; - Loader *loader = - GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file); - if (!loader) - return false; - - switch (m_options.provider) { - case eReproducerProviderFiles: { - FileSpec vfs_mapping = loader->GetFile(); - - // Read the VFS mapping. - ErrorOr> buffer = - vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath()); - if (!buffer) { - SetError(result, errorCodeToError(buffer.getError())); - return false; - } - - // Initialize a VFS from the given mapping. - IntrusiveRefCntPtr vfs = vfs::getVFSFromYAML( - std::move(buffer.get()), nullptr, vfs_mapping.GetPath()); - - // Dump the VFS to a buffer. - std::string str; - raw_string_ostream os(str); - static_cast(*vfs).dump(os); - os.flush(); - - // Return the string. - result.AppendMessage(str); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderSymbolFiles: { - Expected symbol_files = - loader->LoadBuffer(); - if (!symbol_files) { - SetError(result, symbol_files.takeError()); - return false; - } - - std::vector entries; - llvm::yaml::Input yin(*symbol_files); - yin >> entries; - - for (const auto &entry : entries) { - result.AppendMessageWithFormat("- uuid: %s\n", - entry.uuid.c_str()); - result.AppendMessageWithFormat(" module path: %s\n", - entry.module_path.c_str()); - result.AppendMessageWithFormat(" symbol path: %s\n", - entry.symbol_path.c_str()); - } - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderVersion: { - Expected version = loader->LoadBuffer(); - if (!version) { - SetError(result, version.takeError()); - return false; - } - result.AppendMessage(*version); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderWorkingDirectory: { - Expected cwd = - repro::GetDirectoryFrom(loader); - if (!cwd) { - SetError(result, cwd.takeError()); - return false; - } - result.AppendMessage(*cwd); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderHomeDirectory: { - Expected home = - repro::GetDirectoryFrom(loader); - if (!home) { - SetError(result, home.takeError()); - return false; - } - result.AppendMessage(*home); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderCommands: { - std::unique_ptr> multi_loader = - repro::MultiLoader::Create(loader); - if (!multi_loader) { - SetError(result, - make_error("Unable to create command loader.", - llvm::inconvertibleErrorCode())); - return false; - } - - // Iterate over the command files and dump them. - llvm::Optional command_file; - while ((command_file = multi_loader->GetNextFile())) { - if (!command_file) - break; - - auto command_buffer = llvm::MemoryBuffer::getFile(*command_file); - if (auto err = command_buffer.getError()) { - SetError(result, errorCodeToError(err)); - return false; - } - result.AppendMessage((*command_buffer)->getBuffer()); - } - - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderGDB: { - std::unique_ptr> - multi_loader = - repro::MultiLoader::Create(loader); - - if (!multi_loader) { - SetError(result, - make_error("Unable to create GDB loader.", - llvm::inconvertibleErrorCode())); - return false; - } - - llvm::Optional gdb_file; - while ((gdb_file = multi_loader->GetNextFile())) { - if (llvm::Expected> packets = - ReadFromYAML>(*gdb_file)) { - for (GDBRemotePacket &packet : *packets) { - packet.Dump(result.GetOutputStream()); - } - } else { - SetError(result, packets.takeError()); - return false; - } - } - - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderProcessInfo: { - std::unique_ptr> - multi_loader = - repro::MultiLoader::Create(loader); - - if (!multi_loader) { - SetError(result, make_error( - llvm::inconvertibleErrorCode(), - "Unable to create process info loader.")); - return false; - } - - llvm::Optional process_file; - while ((process_file = multi_loader->GetNextFile())) { - if (llvm::Expected infos = - ReadFromYAML(*process_file)) { - for (ProcessInstanceInfo info : *infos) - info.Dump(result.GetOutputStream(), HostInfo::GetUserIDResolver()); - } else { - SetError(result, infos.takeError()); - return false; - } - } - - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - case eReproducerProviderNone: - result.AppendError("No valid provider specified."); - return false; - } - - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } - -private: - CommandOptions m_options; -}; - -class CommandObjectReproducerVerify : public CommandObjectParsed { -public: - CommandObjectReproducerVerify(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer verify", - "Verify the contents of a reproducer. " - "If no reproducer is specified during replay, it " - "verifies the content of the current reproducer.", - nullptr) {} - - ~CommandObjectReproducerVerify() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() : Options(), file() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'f': - file.SetFile(option_arg, FileSpec::Style::native); - FileSystem::Instance().Resolve(file); - break; - default: - llvm_unreachable("Unimplemented option"); - } - - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - file.Clear(); - } - - ArrayRef GetDefinitions() override { - return makeArrayRef(g_reproducer_verify_options); - } - - FileSpec file; - }; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - llvm::Optional loader_storage; - Loader *loader = - GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file); - if (!loader) - return false; - - bool errors = false; - auto error_callback = [&](llvm::StringRef error) { - errors = true; - result.AppendError(error); - }; - - bool warnings = false; - auto warning_callback = [&](llvm::StringRef warning) { - warnings = true; - result.AppendWarning(warning); - }; - - auto note_callback = [&](llvm::StringRef warning) { - result.AppendMessage(warning); - }; - - Verifier verifier(loader); - verifier.Verify(error_callback, warning_callback, note_callback); - - if (warnings || errors) { - result.AppendMessage("reproducer verification failed"); - result.SetStatus(eReturnStatusFailed); - } else { - result.AppendMessage("reproducer verification succeeded"); - result.SetStatus(eReturnStatusSuccessFinishResult); - } - - return result.Succeeded(); - } - -private: - CommandOptions m_options; -}; - -CommandObjectReproducer::CommandObjectReproducer( - CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "reproducer", - "Commands for manipulating reproducers. Reproducers make it " - "possible " - "to capture full debug sessions with all its dependencies. The " - "resulting reproducer is used to replay the debug session while " - "debugging the debugger.\n" - "Because reproducers need the whole the debug session from " - "beginning to end, you need to launch the debugger in capture or " - "replay mode, commonly though the command line driver.\n" - "Reproducers are unrelated record-replay debugging, as you cannot " - "interact with the debugger during replay.\n", - "reproducer []") { - LoadSubCommand( - "generate", - CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); - LoadSubCommand("status", CommandObjectSP( - new CommandObjectReproducerStatus(interpreter))); - LoadSubCommand("dump", - CommandObjectSP(new CommandObjectReproducerDump(interpreter))); - LoadSubCommand("verify", CommandObjectSP( - new CommandObjectReproducerVerify(interpreter))); - LoadSubCommand("xcrash", CommandObjectSP( - new CommandObjectReproducerXCrash(interpreter))); -} - -CommandObjectReproducer::~CommandObjectReproducer() = default; diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h b/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h deleted file mode 100644 index bdee8053549..00000000000 --- a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h +++ /dev/null @@ -1,27 +0,0 @@ -//===-- CommandObjectReproducer.h -------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H -#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H - -#include "lldb/Interpreter/CommandObjectMultiword.h" - -namespace lldb_private { - -// CommandObjectReproducer - -class CommandObjectReproducer : public CommandObjectMultiword { -public: - CommandObjectReproducer(CommandInterpreter &interpreter); - - ~CommandObjectReproducer() override; -}; - -} // namespace lldb_private - -#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H diff --git a/gnu/llvm/lldb/source/Core/FormatEntity.cpp b/gnu/llvm/lldb/source/Core/FormatEntity.cpp index 4c31fb9639b..eb1681a001a 100644 --- a/gnu/llvm/lldb/source/Core/FormatEntity.cpp +++ b/gnu/llvm/lldb/source/Core/FormatEntity.cpp @@ -44,8 +44,8 @@ #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" @@ -263,11 +263,10 @@ constexpr Definition g_root = Entry::DefinitionWithChildren( FormatEntity::Entry::Entry(llvm::StringRef s) : string(s.data(), s.size()), printf_format(), children(), - type(Type::String), fmt(lldb::eFormatDefault), number(0), deref(false) {} + type(Type::String) {} FormatEntity::Entry::Entry(char ch) - : string(1, ch), printf_format(), children(), type(Type::String), - fmt(lldb::eFormatDefault), number(0), deref(false) {} + : string(1, ch), printf_format(), children(), type(Type::String) {} void FormatEntity::Entry::AppendChar(char ch) { if (children.empty() || children.back().type != Entry::Type::String) @@ -509,7 +508,7 @@ static bool ScanBracketedRange(llvm::StringRef subpath, size_t &close_bracket_index, const char *&var_name_final_if_array_range, int64_t &index_lower, int64_t &index_higher) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); close_bracket_index = llvm::StringRef::npos; const size_t open_bracket_index = subpath.find('['); if (open_bracket_index == llvm::StringRef::npos) { @@ -618,12 +617,9 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind, static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index, bool deref_pointer) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); - const char *ptr_deref_format = "[%d]"; - std::string ptr_deref_buffer(10, 0); - ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); - LLDB_LOGF(log, "[ExpandIndexedExpression] name to deref: %s", - ptr_deref_buffer.c_str()); + Log *log = GetLog(LLDBLog::DataFormatters); + std::string name_to_deref = llvm::formatv("[{0}]", index); + LLDB_LOG(log, "[ExpandIndexedExpression] name to deref: {0}", name_to_deref); ValueObject::GetValueForExpressionPathOptions options; ValueObject::ExpressionPathEndResultType final_value_type; ValueObject::ExpressionPathScanEndReason reason_to_stop; @@ -631,8 +627,7 @@ static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index, (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); ValueObjectSP item = valobj->GetValueForExpressionPath( - ptr_deref_buffer.c_str(), &reason_to_stop, &final_value_type, options, - &what_next); + name_to_deref, &reason_to_stop, &final_value_type, options, &what_next); if (!item) { LLDB_LOGF(log, "[ExpandIndexedExpression] ERROR: why stopping = %d," @@ -676,7 +671,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, if (valobj == nullptr) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + Log *log = GetLog(LLDBLog::DataFormatters); Format custom_format = eFormatInvalid; ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() @@ -697,7 +692,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, case FormatEntity::Entry::Type::ScriptVariableSynthetic: is_script = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case FormatEntity::Entry::Type::VariableSynthetic: custom_format = entry.fmt; val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number; @@ -712,9 +707,6 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, return false; } - if (valobj == nullptr) - return false; - ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); @@ -829,7 +821,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); auto type_sp = std::make_shared( - bitfield_name.GetString(), false); + bitfield_name.GetString(), lldb::eFormatterMatchExact); if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp)) @@ -1043,6 +1035,71 @@ static inline bool IsToken(const char *var_name_begin, const char *var) { return (::strncmp(var_name_begin, var, strlen(var)) == 0); } +/// Parses the basename out of a demangled function name +/// that may include function arguments. Supports +/// template functions. +/// +/// Returns pointers to the opening and closing parenthesis of +/// `full_name`. Can return nullptr for either parenthesis if +/// none is exists. +static std::pair +ParseBaseName(char const *full_name) { + const char *open_paren = strchr(full_name, '('); + const char *close_paren = nullptr; + const char *generic = strchr(full_name, '<'); + // if before the arguments list begins there is a template sign + // then scan to the end of the generic args before you try to find + // the arguments list + if (generic && open_paren && generic < open_paren) { + int generic_depth = 1; + ++generic; + for (; *generic && generic_depth > 0; generic++) { + if (*generic == '<') + generic_depth++; + if (*generic == '>') + generic_depth--; + } + if (*generic) + open_paren = strchr(generic, '('); + else + open_paren = nullptr; + } + + if (open_paren) { + if (IsToken(open_paren, "(anonymous namespace)")) { + open_paren = strchr(open_paren + strlen("(anonymous namespace)"), '('); + if (open_paren) + close_paren = strchr(open_paren, ')'); + } else + close_paren = strchr(open_paren, ')'); + } + + return {open_paren, close_paren}; +} + +/// Writes out the function name in 'full_name' to 'out_stream' +/// but replaces each argument type with the variable name +/// and the corresponding pretty-printed value +static void PrettyPrintFunctionNameWithArgs(Stream &out_stream, + char const *full_name, + ExecutionContextScope *exe_scope, + VariableList const &args) { + auto [open_paren, close_paren] = ParseBaseName(full_name); + if (open_paren) + out_stream.Write(full_name, open_paren - full_name + 1); + else { + out_stream.PutCString(full_name); + out_stream.PutChar('('); + } + + FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope); + + if (close_paren) + out_stream.PutCString(close_paren); + else + out_stream.PutChar(')'); +} + bool FormatEntity::FormatStringRef(const llvm::StringRef &format_str, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, @@ -1650,100 +1707,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, variable_list_sp->AppendVariablesWithScope( eValueTypeVariableArgument, args); if (args.GetSize() > 0) { - const char *open_paren = strchr(cstr, '('); - const char *close_paren = nullptr; - const char *generic = strchr(cstr, '<'); - // if before the arguments list begins there is a template sign - // then scan to the end of the generic args before you try to find - // the arguments list - if (generic && open_paren && generic < open_paren) { - int generic_depth = 1; - ++generic; - for (; *generic && generic_depth > 0; generic++) { - if (*generic == '<') - generic_depth++; - if (*generic == '>') - generic_depth--; - } - if (*generic) - open_paren = strchr(generic, '('); - else - open_paren = nullptr; - } - if (open_paren) { - if (IsToken(open_paren, "(anonymous namespace)")) { - open_paren = - strchr(open_paren + strlen("(anonymous namespace)"), '('); - if (open_paren) - close_paren = strchr(open_paren, ')'); - } else - close_paren = strchr(open_paren, ')'); - } - - if (open_paren) - s.Write(cstr, open_paren - cstr + 1); - else { - s.PutCString(cstr); - s.PutChar('('); - } - const size_t num_args = args.GetSize(); - for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) { - std::string buffer; - - VariableSP var_sp(args.GetVariableAtIndex(arg_idx)); - ValueObjectSP var_value_sp( - ValueObjectVariable::Create(exe_scope, var_sp)); - StreamString ss; - llvm::StringRef var_representation; - const char *var_name = var_value_sp->GetName().GetCString(); - if (var_value_sp->GetCompilerType().IsValid()) { - if (var_value_sp && exe_scope->CalculateTarget()) - var_value_sp = - var_value_sp->GetQualifiedRepresentationIfAvailable( - exe_scope->CalculateTarget() - ->TargetProperties::GetPreferDynamicValue(), - exe_scope->CalculateTarget() - ->TargetProperties::GetEnableSyntheticValue()); - if (var_value_sp->GetCompilerType().IsAggregateType() && - DataVisualization::ShouldPrintAsOneLiner(*var_value_sp)) { - static StringSummaryFormat format( - TypeSummaryImpl::Flags() - .SetHideItemNames(false) - .SetShowMembersOneLiner(true), - ""); - format.FormatObject(var_value_sp.get(), buffer, - TypeSummaryOptions()); - var_representation = buffer; - } else - var_value_sp->DumpPrintableRepresentation( - ss, - ValueObject::ValueObjectRepresentationStyle:: - eValueObjectRepresentationStyleSummary, - eFormatDefault, - ValueObject::PrintableRepresentationSpecialCases::eAllow, - false); - } - - if (!ss.GetString().empty()) - var_representation = ss.GetString(); - if (arg_idx > 0) - s.PutCString(", "); - if (var_value_sp->GetError().Success()) { - if (!var_representation.empty()) - s.Printf("%s=%s", var_name, var_representation.str().c_str()); - else - s.Printf("%s=%s at %s", var_name, - var_value_sp->GetTypeName().GetCString(), - var_value_sp->GetLocationAsCString()); - } else - s.Printf("%s=", var_name); - } - - if (close_paren) - s.PutCString(close_paren); - else - s.PutChar(')'); - + PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args); } else { s.PutCString(cstr); } @@ -2452,3 +2416,55 @@ void FormatEntity::AutoComplete(CompletionRequest &request) { request.AddCompletions(new_matches); } } + +void FormatEntity::PrettyPrintFunctionArguments( + Stream &out_stream, VariableList const &args, + ExecutionContextScope *exe_scope) { + const size_t num_args = args.GetSize(); + for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) { + std::string buffer; + + VariableSP var_sp(args.GetVariableAtIndex(arg_idx)); + ValueObjectSP var_value_sp(ValueObjectVariable::Create(exe_scope, var_sp)); + StreamString ss; + llvm::StringRef var_representation; + const char *var_name = var_value_sp->GetName().GetCString(); + if (var_value_sp->GetCompilerType().IsValid()) { + if (exe_scope && exe_scope->CalculateTarget()) + var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable( + exe_scope->CalculateTarget() + ->TargetProperties::GetPreferDynamicValue(), + exe_scope->CalculateTarget() + ->TargetProperties::GetEnableSyntheticValue()); + if (var_value_sp->GetCompilerType().IsAggregateType() && + DataVisualization::ShouldPrintAsOneLiner(*var_value_sp)) { + static StringSummaryFormat format(TypeSummaryImpl::Flags() + .SetHideItemNames(false) + .SetShowMembersOneLiner(true), + ""); + format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions()); + var_representation = buffer; + } else + var_value_sp->DumpPrintableRepresentation( + ss, + ValueObject::ValueObjectRepresentationStyle:: + eValueObjectRepresentationStyleSummary, + eFormatDefault, + ValueObject::PrintableRepresentationSpecialCases::eAllow, false); + } + + if (!ss.GetString().empty()) + var_representation = ss.GetString(); + if (arg_idx > 0) + out_stream.PutCString(", "); + if (var_value_sp->GetError().Success()) { + if (!var_representation.empty()) + out_stream.Printf("%s=%s", var_name, var_representation.str().c_str()); + else + out_stream.Printf("%s=%s at %s", var_name, + var_value_sp->GetTypeName().GetCString(), + var_value_sp->GetLocationAsCString()); + } else + out_stream.Printf("%s=", var_name); + } +} diff --git a/gnu/llvm/lldb/source/Host/common/MainLoop.cpp b/gnu/llvm/lldb/source/Host/common/MainLoop.cpp deleted file mode 100644 index d36587ce234..00000000000 --- a/gnu/llvm/lldb/source/Host/common/MainLoop.cpp +++ /dev/null @@ -1,424 +0,0 @@ -//===-- MainLoop.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 "llvm/Config/llvm-config.h" -#include "lldb/Host/Config.h" - -#include "lldb/Host/MainLoop.h" -#include "lldb/Host/PosixApi.h" -#include "lldb/Utility/Status.h" -#include -#include -#include -#include -#include -#include - -// Multiplexing is implemented using kqueue on systems that support it (BSD -// variants including OSX). On linux we use ppoll, while android uses pselect -// (ppoll is present but not implemented properly). On windows we use WSApoll -// (which does not support signals). - -#if HAVE_SYS_EVENT_H -#include -#elif defined(_WIN32) -#include -#elif defined(__ANDROID__) -#include -#else -#include -#endif - -#ifdef _WIN32 -#define POLL WSAPoll -#else -#define POLL poll -#endif - -#if SIGNAL_POLLING_UNSUPPORTED -#ifdef _WIN32 -typedef int sigset_t; -typedef int siginfo_t; -#endif - -int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout_ts, - const sigset_t *) { - int timeout = - (timeout_ts == nullptr) - ? -1 - : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000); - return POLL(fds, nfds, timeout); -} - -#endif - -using namespace lldb; -using namespace lldb_private; - -static sig_atomic_t g_signal_flags[NSIG]; - -#ifndef SIGNAL_POLLING_UNSUPPORTED -static void SignalHandler(int signo, siginfo_t *info, void *) { - assert(signo < NSIG); - g_signal_flags[signo] = 1; -} -#endif - -class MainLoop::RunImpl { -public: - RunImpl(MainLoop &loop); - ~RunImpl() = default; - - Status Poll(); - void ProcessEvents(); - -private: - MainLoop &loop; - -#if HAVE_SYS_EVENT_H - std::vector in_events; - struct kevent out_events[4]; - int num_events = -1; - -#else -#ifdef __ANDROID__ - fd_set read_fd_set; -#else - std::vector read_fds; -#endif - - sigset_t get_sigmask(); -#endif -}; - -#if HAVE_SYS_EVENT_H -MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { - in_events.reserve(loop.m_read_fds.size()); -} - -Status MainLoop::RunImpl::Poll() { - in_events.resize(loop.m_read_fds.size()); - unsigned i = 0; - for (auto &fd : loop.m_read_fds) - EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0); - - num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(), - out_events, llvm::array_lengthof(out_events), nullptr); - - if (num_events < 0) { - if (errno == EINTR) { - // in case of EINTR, let the main loop run one iteration - // we need to zero num_events to avoid assertions failing - num_events = 0; - } else - return Status(errno, eErrorTypePOSIX); - } - return Status(); -} - -void MainLoop::RunImpl::ProcessEvents() { - assert(num_events >= 0); - for (int i = 0; i < num_events; ++i) { - if (loop.m_terminate_request) - return; - switch (out_events[i].filter) { - case EVFILT_READ: - loop.ProcessReadObject(out_events[i].ident); - break; - case EVFILT_SIGNAL: - loop.ProcessSignal(out_events[i].ident); - break; - default: - llvm_unreachable("Unknown event"); - } - } -} -#else -MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { -#ifndef __ANDROID__ - read_fds.reserve(loop.m_read_fds.size()); -#endif -} - -sigset_t MainLoop::RunImpl::get_sigmask() { - sigset_t sigmask; -#if defined(_WIN32) - sigmask = 0; -#elif SIGNAL_POLLING_UNSUPPORTED - sigemptyset(&sigmask); -#else - int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask); - assert(ret == 0); - (void) ret; - - for (const auto &sig : loop.m_signals) - sigdelset(&sigmask, sig.first); -#endif - return sigmask; -} - -#ifdef __ANDROID__ -Status MainLoop::RunImpl::Poll() { - // ppoll(2) is not supported on older all android versions. Also, older - // versions android (API <= 19) implemented pselect in a non-atomic way, as a - // combination of pthread_sigmask and select. This is not sufficient for us, - // as we rely on the atomicity to correctly implement signal polling, so we - // call the underlying syscall ourselves. - - FD_ZERO(&read_fd_set); - int nfds = 0; - for (const auto &fd : loop.m_read_fds) { - FD_SET(fd.first, &read_fd_set); - nfds = std::max(nfds, fd.first + 1); - } - - union { - sigset_t set; - uint64_t pad; - } kernel_sigset; - memset(&kernel_sigset, 0, sizeof(kernel_sigset)); - kernel_sigset.set = get_sigmask(); - - struct { - void *sigset_ptr; - size_t sigset_len; - } extra_data = {&kernel_sigset, sizeof(kernel_sigset)}; - if (syscall(__NR_pselect6, nfds, &read_fd_set, nullptr, nullptr, nullptr, - &extra_data) == -1 && - errno != EINTR) - return Status(errno, eErrorTypePOSIX); - - return Status(); -} -#else -Status MainLoop::RunImpl::Poll() { - read_fds.clear(); - - sigset_t sigmask = get_sigmask(); - - for (const auto &fd : loop.m_read_fds) { - struct pollfd pfd; - pfd.fd = fd.first; - pfd.events = POLLIN; - pfd.revents = 0; - read_fds.push_back(pfd); - } - - if (ppoll(read_fds.data(), read_fds.size(), nullptr, &sigmask) == -1 && - errno != EINTR) - return Status(errno, eErrorTypePOSIX); - - return Status(); -} -#endif - -void MainLoop::RunImpl::ProcessEvents() { -#ifdef __ANDROID__ - // Collect first all readable file descriptors into a separate vector and - // then iterate over it to invoke callbacks. Iterating directly over - // loop.m_read_fds is not possible because the callbacks can modify the - // container which could invalidate the iterator. - std::vector fds; - for (const auto &fd : loop.m_read_fds) - if (FD_ISSET(fd.first, &read_fd_set)) - fds.push_back(fd.first); - - for (const auto &handle : fds) { -#else - for (const auto &fd : read_fds) { - if ((fd.revents & (POLLIN | POLLHUP)) == 0) - continue; - IOObject::WaitableHandle handle = fd.fd; -#endif - if (loop.m_terminate_request) - return; - - loop.ProcessReadObject(handle); - } - - std::vector signals; - for (const auto &entry : loop.m_signals) - if (g_signal_flags[entry.first] != 0) - signals.push_back(entry.first); - - for (const auto &signal : signals) { - if (loop.m_terminate_request) - return; - g_signal_flags[signal] = 0; - loop.ProcessSignal(signal); - } -} -#endif - -MainLoop::MainLoop() { -#if HAVE_SYS_EVENT_H - m_kqueue = kqueue(); - assert(m_kqueue >= 0); -#endif -} -MainLoop::~MainLoop() { -#if HAVE_SYS_EVENT_H - close(m_kqueue); -#endif - assert(m_read_fds.size() == 0); - assert(m_signals.size() == 0); -} - -MainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp, - const Callback &callback, - Status &error) { -#ifdef _WIN32 - if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) { - error.SetErrorString("MainLoop: non-socket types unsupported on Windows"); - return nullptr; - } -#endif - if (!object_sp || !object_sp->IsValid()) { - error.SetErrorString("IO object is not valid."); - return nullptr; - } - - const bool inserted = - m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second; - if (!inserted) { - error.SetErrorStringWithFormat("File descriptor %d already monitored.", - object_sp->GetWaitableHandle()); - return nullptr; - } - - return CreateReadHandle(object_sp); -} - -// We shall block the signal, then install the signal handler. The signal will -// be unblocked in the Run() function to check for signal delivery. -MainLoop::SignalHandleUP -MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { -#ifdef SIGNAL_POLLING_UNSUPPORTED - error.SetErrorString("Signal polling is not supported on this platform."); - return nullptr; -#else - auto signal_it = m_signals.find(signo); - if (signal_it != m_signals.end()) { - auto callback_it = signal_it->second.callbacks.insert( - signal_it->second.callbacks.end(), callback); - return SignalHandleUP(new SignalHandle(*this, signo, callback_it)); - } - - SignalInfo info; - info.callbacks.push_back(callback); - struct sigaction new_action; - new_action.sa_sigaction = &SignalHandler; - new_action.sa_flags = SA_SIGINFO; - sigemptyset(&new_action.sa_mask); - sigaddset(&new_action.sa_mask, signo); - sigset_t old_set; - - g_signal_flags[signo] = 0; - - // Even if using kqueue, the signal handler will still be invoked, so it's - // important to replace it with our "benign" handler. - int ret = sigaction(signo, &new_action, &info.old_action); - (void)ret; - assert(ret == 0 && "sigaction failed"); - -#if HAVE_SYS_EVENT_H - struct kevent ev; - EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); - ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr); - assert(ret == 0); -#endif - - // If we're using kqueue, the signal needs to be unblocked in order to - // receive it. If using pselect/ppoll, we need to block it, and later unblock - // it as a part of the system call. - ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK, - &new_action.sa_mask, &old_set); - assert(ret == 0 && "pthread_sigmask failed"); - info.was_blocked = sigismember(&old_set, signo); - auto insert_ret = m_signals.insert({signo, info}); - - return SignalHandleUP(new SignalHandle( - *this, signo, insert_ret.first->second.callbacks.begin())); -#endif -} - -void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) { - bool erased = m_read_fds.erase(handle); - UNUSED_IF_ASSERT_DISABLED(erased); - assert(erased); -} - -void MainLoop::UnregisterSignal(int signo, - std::list::iterator callback_it) { -#if SIGNAL_POLLING_UNSUPPORTED - Status("Signal polling is not supported on this platform."); -#else - auto it = m_signals.find(signo); - assert(it != m_signals.end()); - - it->second.callbacks.erase(callback_it); - // Do not remove the signal handler unless all callbacks have been erased. - if (!it->second.callbacks.empty()) - return; - - sigaction(signo, &it->second.old_action, nullptr); - - sigset_t set; - sigemptyset(&set); - sigaddset(&set, signo); - int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, - &set, nullptr); - assert(ret == 0); - (void)ret; - -#if HAVE_SYS_EVENT_H - struct kevent ev; - EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0); - ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr); - assert(ret == 0); -#endif - - m_signals.erase(it); -#endif -} - -Status MainLoop::Run() { - m_terminate_request = false; - - Status error; - RunImpl impl(*this); - - // run until termination or until we run out of things to listen to - while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) { - - error = impl.Poll(); - if (error.Fail()) - return error; - - impl.ProcessEvents(); - } - return Status(); -} - -void MainLoop::ProcessSignal(int signo) { - auto it = m_signals.find(signo); - if (it != m_signals.end()) { - // The callback may actually register/unregister signal handlers, - // so we need to create a copy first. - llvm::SmallVector callbacks_to_run{ - it->second.callbacks.begin(), it->second.callbacks.end()}; - for (auto &x : callbacks_to_run) - x(*this); // Do the work - } -} - -void MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) { - auto it = m_read_fds.find(handle); - if (it != m_read_fds.end()) - it->second(*this); // Do the work -} diff --git a/gnu/llvm/lldb/source/Host/common/StringConvert.cpp b/gnu/llvm/lldb/source/Host/common/StringConvert.cpp deleted file mode 100644 index b4eb9275536..00000000000 --- a/gnu/llvm/lldb/source/Host/common/StringConvert.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===-- StringConvert.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 - -#include "lldb/Host/StringConvert.h" - -namespace lldb_private { -namespace StringConvert { - -int32_t ToSInt32(const char *s, int32_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - const long sval = ::strtol(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN)); - return (int32_t)sval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -uint32_t ToUInt32(const char *s, uint32_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - const unsigned long uval = ::strtoul(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = (uval <= UINT32_MAX); - return (uint32_t)uval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -int64_t ToSInt64(const char *s, int64_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - int64_t uval = ::strtoll(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -uint64_t ToUInt64(const char *s, uint64_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - uint64_t uval = ::strtoull(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -double ToDouble(const char *s, double fail_value, bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - double val = strtod(s, &end); - if (*end == '\0') { - if (success_ptr) - *success_ptr = true; - return val; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} -} -} diff --git a/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp b/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp index d87ec08f126..215208c6eed 100644 --- a/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp +++ b/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -36,34 +37,15 @@ llvm::VersionTuple HostInfoOpenBSD::GetOSVersion() { return llvm::VersionTuple(); } -bool HostInfoOpenBSD::GetOSBuildString(std::string &s) { +std::optional HostInfoOpenBSD::GetOSBuildString() { int mib[2] = {CTL_KERN, KERN_OSREV}; - char osrev_str[12]; uint32_t osrev = 0; size_t osrev_len = sizeof(osrev); - if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) { - ::snprintf(osrev_str, sizeof(osrev_str), "%-8.8u", osrev); - s.assign(osrev_str); - return true; - } - - s.clear(); - return false; -} - -bool HostInfoOpenBSD::GetOSKernelDescription(std::string &s) { - struct utsname un; - - ::memset(&un, 0, sizeof(utsname)); - s.clear(); - - if (uname(&un) < 0) - return false; + if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) + return llvm::formatv("{0,8:8}", osrev).str(); - s.assign(un.version); - - return true; + return std::nullopt; } FileSpec HostInfoOpenBSD::GetProgramFileSpec() { @@ -76,6 +58,6 @@ bool HostInfoOpenBSD::ComputeSupportExeDirectory(FileSpec &file_spec) { file_spec.IsAbsolute() && FileSystem::Instance().Exists(file_spec)) return true; - file_spec.GetDirectory().SetCString("/usr/bin"); + file_spec.SetDirectory("/usr/bin"); return true; } diff --git a/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp b/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp index 9c2ab2fca9c..ef87d8c8153 100644 --- a/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp +++ b/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp @@ -26,13 +26,11 @@ using namespace lldb_private; #endif #endif // #ifdef __ANDROID__ -namespace { +static const int kDomain = AF_UNIX; +static const int kType = SOCK_STREAM; -const int kDomain = AF_UNIX; -const int kType = SOCK_STREAM; - -bool SetSockAddr(llvm::StringRef name, const size_t name_offset, - sockaddr_un *saddr_un, socklen_t &saddr_un_len) { +static bool SetSockAddr(llvm::StringRef name, const size_t name_offset, + sockaddr_un *saddr_un, socklen_t &saddr_un_len) { if (name.size() + name_offset > sizeof(saddr_un->sun_path)) return false; @@ -56,7 +54,6 @@ bool SetSockAddr(llvm::StringRef name, const size_t name_offset, return true; } -} // namespace DomainSocket::DomainSocket(bool should_close, bool child_processes_inherit) : Socket(ProtocolUnixDomain, should_close, child_processes_inherit) {} @@ -127,29 +124,33 @@ void DomainSocket::DeleteSocketFile(llvm::StringRef name) { } std::string DomainSocket::GetSocketName() const { - if (m_socket != kInvalidSocketValue) { - struct sockaddr_un saddr_un; - saddr_un.sun_family = AF_UNIX; - socklen_t sock_addr_len = sizeof(struct sockaddr_un); - if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) == - 0) { - std::string name(saddr_un.sun_path + GetNameOffset(), - sock_addr_len - - offsetof(struct sockaddr_un, sun_path) - + if (m_socket == kInvalidSocketValue) + return ""; + + struct sockaddr_un saddr_un; + saddr_un.sun_family = AF_UNIX; + socklen_t sock_addr_len = sizeof(struct sockaddr_un); + if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) != + 0) + return ""; + + if (sock_addr_len <= offsetof(struct sockaddr_un, sun_path)) + return ""; // Unnamed domain socket + + llvm::StringRef name(saddr_un.sun_path + GetNameOffset(), + sock_addr_len - offsetof(struct sockaddr_un, sun_path) - GetNameOffset()); - if (name.back() == '\0') name.pop_back(); - return name; - } - } - return ""; + name = name.rtrim('\0'); + + return name.str(); } std::string DomainSocket::GetRemoteConnectionURI() const { - if (m_socket != kInvalidSocketValue) { - return std::string(llvm::formatv( - "{0}://{1}", - GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", - GetSocketName())); - } - return ""; + std::string name = GetSocketName(); + if (name.empty()) + return name; + + return llvm::formatv( + "{0}://{1}", + GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name); } diff --git a/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp b/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp index 1cc22c405e0..227faf26292 100644 --- a/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp @@ -38,12 +38,10 @@ enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE #define PIPE2_SUPPORTED 0 #endif -namespace { - -constexpr auto OPEN_WRITER_SLEEP_TIMEOUT_MSECS = 100; +static constexpr auto OPEN_WRITER_SLEEP_TIMEOUT_MSECS = 100; #if defined(FD_CLOEXEC) && !PIPE2_SUPPORTED -bool SetCloexecFlag(int fd) { +static bool SetCloexecFlag(int fd) { int flags = ::fcntl(fd, F_GETFD); if (flags == -1) return false; @@ -51,10 +49,9 @@ bool SetCloexecFlag(int fd) { } #endif -std::chrono::time_point Now() { +static std::chrono::time_point Now() { return std::chrono::steady_clock::now(); } -} // namespace PipePosix::PipePosix() : m_fds{PipePosix::kInvalidDescriptor, PipePosix::kInvalidDescriptor} {} diff --git a/gnu/llvm/lldb/source/Host/windows/Windows.cpp b/gnu/llvm/lldb/source/Host/windows/Windows.cpp deleted file mode 100644 index 787f35930ba..00000000000 --- a/gnu/llvm/lldb/source/Host/windows/Windows.cpp +++ /dev/null @@ -1,117 +0,0 @@ -//===-- Windows.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 -// -//===----------------------------------------------------------------------===// - -// This file provides Windows support functions - -#include "lldb/Host/PosixApi.h" -#include "lldb/Host/windows/windows.h" - -#include "llvm/Support/ConvertUTF.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -int vasprintf(char **ret, const char *fmt, va_list ap) { - char *buf; - int len; - size_t buflen; - va_list ap2; - - va_copy(ap2, ap); - len = vsnprintf(NULL, 0, fmt, ap2); - - if (len >= 0 && - (buf = (char *)malloc((buflen = (size_t)(len + 1)))) != NULL) { - len = vsnprintf(buf, buflen, fmt, ap); - *ret = buf; - } else { - *ret = NULL; - len = -1; - } - - va_end(ap2); - return len; -} - -char *strcasestr(const char *s, const char *find) { - char c, sc; - size_t len; - - if ((c = *find++) != 0) { - c = tolower((unsigned char)c); - len = strlen(find); - do { - do { - if ((sc = *s++) == 0) - return 0; - } while ((char)tolower((unsigned char)sc) != c); - } while (strncasecmp(s, find, len) != 0); - s--; - } - return const_cast(s); -} - -#ifdef _MSC_VER - -char *basename(char *path) { - char *l1 = strrchr(path, '\\'); - char *l2 = strrchr(path, '/'); - if (l2 > l1) - l1 = l2; - if (!l1) - return path; // no base name - return &l1[1]; -} - -char *dirname(char *path) { - char *l1 = strrchr(path, '\\'); - char *l2 = strrchr(path, '/'); - if (l2 > l1) - l1 = l2; - if (!l1) - return NULL; // no dir name - *l1 = 0; - return path; -} - -int strcasecmp(const char *s1, const char *s2) { return stricmp(s1, s2); } - -int strncasecmp(const char *s1, const char *s2, size_t n) { - return strnicmp(s1, s2, n); -} - -#if _MSC_VER < 1900 -namespace lldb_private { -int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) { - int old_errno = errno; - int r = ::vsnprintf(buffer, count, format, argptr); - int new_errno = errno; - buffer[count - 1] = '\0'; - if (r == -1 || r == count) { - FILE *nul = fopen("nul", "w"); - int bytes_written = ::vfprintf(nul, format, argptr); - fclose(nul); - if (bytes_written < count) - errno = new_errno; - else { - errno = old_errno; - r = bytes_written; - } - } - return r; -} -} // namespace lldb_private -#endif - -#endif // _MSC_VER diff --git a/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp b/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp index f15bf7cf01c..c5c9706b39c 100644 --- a/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -12,10 +12,11 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/Socket.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/ReproducerProvider.h" +#include "lldb/Target/Statistics.h" +#include "lldb/Utility/Diagnostics.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Timer.h" -#include "lldb/lldb-private.h" +#include "lldb/Version/Version.h" #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -32,7 +33,6 @@ #include using namespace lldb_private; -using namespace lldb_private::repro; SystemInitializerCommon::SystemInitializerCommon( HostInfo::SharedLibraryDirectoryHelper *helper) @@ -40,58 +40,6 @@ SystemInitializerCommon::SystemInitializerCommon( SystemInitializerCommon::~SystemInitializerCommon() = default; -/// Initialize the FileSystem based on the current reproducer mode. -static llvm::Error InitializeFileSystem() { - auto &r = repro::Reproducer::Instance(); - if (repro::Loader *loader = r.GetLoader()) { - FileSpec vfs_mapping = loader->GetFile(); - if (vfs_mapping) { - if (llvm::Error e = FileSystem::Initialize(vfs_mapping)) - return e; - } else { - FileSystem::Initialize(); - } - - // Set the current working directory form the reproducer. - llvm::Expected working_dir = - repro::GetDirectoryFrom(loader); - if (!working_dir) - return working_dir.takeError(); - if (std::error_code ec = FileSystem::Instance() - .GetVirtualFileSystem() - ->setCurrentWorkingDirectory(*working_dir)) { - return llvm::errorCodeToError(ec); - } - - // Set the home directory from the reproducer. - llvm::Expected home_dir = - repro::GetDirectoryFrom(loader); - if (!home_dir) - return home_dir.takeError(); - FileSystem::Instance().SetHomeDirectory(*home_dir); - - return llvm::Error::success(); - } - - if (repro::Generator *g = r.GetGenerator()) { - repro::VersionProvider &vp = g->GetOrCreate(); - vp.SetVersion(lldb_private::GetVersion()); - - repro::FileProvider &fp = g->GetOrCreate(); - FileSystem::Initialize(fp.GetFileCollector()); - - fp.RecordInterestingDirectory( - g->GetOrCreate().GetDirectory()); - fp.RecordInterestingDirectory( - g->GetOrCreate().GetDirectory()); - - return llvm::Error::success(); - } - - FileSystem::Initialize(); - return llvm::Error::success(); -} - llvm::Error SystemInitializerCommon::Initialize() { #if defined(_WIN32) const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG"); @@ -115,17 +63,10 @@ llvm::Error SystemInitializerCommon::Initialize() { } #endif - // If the reproducer wasn't initialized before, we can safely assume it's - // off. - if (!Reproducer::Initialized()) { - if (auto e = Reproducer::Initialize(ReproducerMode::Off, llvm::None)) - return e; - } - - if (auto e = InitializeFileSystem()) - return e; + InitializeLldbChannel(); - Log::Initialize(); + Diagnostics::Initialize(); + FileSystem::Initialize(); HostInfo::Initialize(m_shlib_dir_helper); llvm::Error error = Socket::Initialize(); @@ -157,5 +98,5 @@ void SystemInitializerCommon::Terminate() { HostInfo::Terminate(); Log::DisableAllLogChannels(); FileSystem::Terminate(); - Reproducer::Terminate(); + Diagnostics::Terminate(); } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp index e37fbec9ea3..4594ba36b44 100644 --- a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -8,6 +8,7 @@ #include "ABISysV_arm64.h" +#include #include #include "llvm/ADT/STLExtras.h" @@ -23,6 +24,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Scalar.h" @@ -65,7 +67,7 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp, if (!reg_ctx) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + Log *log = GetLog(LLDBLog::Expressions); if (log) { StreamString s; @@ -145,7 +147,7 @@ bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const { if (value_type) { bool is_signed = false; size_t bit_width = 0; - llvm::Optional bit_size = value_type.GetBitSize(&thread); + std::optional bit_size = value_type.GetBitSize(&thread); if (!bit_size) return false; if (value_type.IsIntegerOrEnumerationType(is_signed)) { @@ -276,7 +278,7 @@ Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, if (byte_size <= 16) { if (byte_size <= RegisterValue::GetMaxByteSize()) { RegisterValue reg_value; - error = reg_value.SetValueFromData(v0_info, data, 0, true); + error = reg_value.SetValueFromData(*v0_info, data, 0, true); if (error.Success()) { if (!reg_ctx->WriteRegister(v0_info, reg_value)) error.SetErrorString("failed to write register v0"); @@ -303,7 +305,7 @@ Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, if (v0_info) { if (byte_size <= v0_info->byte_size) { RegisterValue reg_value; - error = reg_value.SetValueFromData(v0_info, data, 0, true); + error = reg_value.SetValueFromData(*v0_info, data, 0, true); if (error.Success()) { if (!reg_ctx->WriteRegister(v0_info, reg_value)) error.SetErrorString("failed to write register v0"); @@ -467,7 +469,7 @@ static bool LoadValueFromConsecutiveGPRRegisters( uint32_t &NGRN, // NGRN (see ABI documentation) uint32_t &NSRN, // NSRN (see ABI documentation) DataExtractor &data) { - llvm::Optional byte_size = + std::optional byte_size = value_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); if (byte_size || *byte_size == 0) @@ -486,7 +488,7 @@ static bool LoadValueFromConsecutiveGPRRegisters( if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) { if (!base_type) return false; - llvm::Optional base_byte_size = + std::optional base_byte_size = base_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); if (!base_byte_size) return false; @@ -511,8 +513,8 @@ static bool LoadValueFromConsecutiveGPRRegisters( // Make sure we have enough room in "heap_data_up" if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) { const size_t bytes_copied = reg_value.GetAsMemoryData( - reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size, - byte_order, error); + *reg_info, heap_data_up->GetBytes() + data_offset, + *base_byte_size, byte_order, error); if (bytes_copied != *base_byte_size) return false; data_offset += bytes_copied; @@ -547,7 +549,7 @@ static bool LoadValueFromConsecutiveGPRRegisters( const size_t curr_byte_size = std::min(8, bytes_left); const size_t bytes_copied = reg_value.GetAsMemoryData( - reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size, + *reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size, byte_order, error); if (bytes_copied == 0) return false; @@ -560,9 +562,12 @@ static bool LoadValueFromConsecutiveGPRRegisters( } else { const RegisterInfo *reg_info = nullptr; if (is_return_value) { - // We are assuming we are decoding this immediately after returning from - // a function call and that the address of the structure is in x8 - reg_info = reg_ctx->GetRegisterInfoByName("x8", 0); + // The SysV arm64 ABI doesn't require you to write the return location + // back to x8 before returning from the function the way the x86_64 ABI + // does. It looks like all the users of this ABI currently choose not to + // do that, and so we can't reconstruct stack based returns on exit + // from the function. + return false; } else { // We are assuming we are stopped at the first instruction in a function // and that the ABI is being respected so all parameters appear where @@ -578,9 +583,6 @@ static bool LoadValueFromConsecutiveGPRRegisters( ++NGRN; } - if (reg_info == nullptr) - return false; - const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS); @@ -616,8 +618,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( if (!reg_ctx) return return_valobj_sp; - llvm::Optional byte_size = - return_compiler_type.GetByteSize(&thread); + std::optional byte_size = return_compiler_type.GetByteSize(&thread); if (!byte_size) return return_valobj_sp; @@ -660,10 +661,10 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) { Status error; if (x0_reg_value.GetAsMemoryData( - x0_reg_info, heap_data_up->GetBytes() + 0, 8, + *x0_reg_info, heap_data_up->GetBytes() + 0, 8, byte_order, error) && x1_reg_value.GetAsMemoryData( - x1_reg_info, heap_data_up->GetBytes() + 8, 8, + *x1_reg_info, heap_data_up->GetBytes() + 8, 8, byte_order, error)) { DataExtractor data( DataBufferSP(heap_data_up.release()), byte_order, @@ -754,7 +755,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( RegisterValue reg_value; if (reg_ctx->ReadRegister(v0_info, reg_value)) { Status error; - if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(), + if (reg_value.GetAsMemoryData(*v0_info, heap_data_up->GetBytes(), heap_data_up->GetByteSize(), byte_order, error)) { DataExtractor data(DataBufferSP(heap_data_up.release()), byte_order, @@ -790,14 +791,20 @@ lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) { // Reads code or data address mask for the current Linux process. static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp, llvm::StringRef reg_name) { - // Linux configures user-space virtual addresses with top byte ignored. - // We set default value of mask such that top byte is masked out. - uint64_t address_mask = ~((1ULL << 56) - 1); - // If Pointer Authentication feature is enabled then Linux exposes - // PAC data and code mask register. Try reading relevant register - // below and merge it with default address mask calculated above. + // 0 means there isn't a mask or it has not been read yet. + // We do not return the top byte mask unless thread_sp is valid. + // This prevents calls to this function before the thread is setup locking + // in the value to just the top byte mask, in cases where pointer + // authentication might also be active. + uint64_t address_mask = 0; lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); if (thread_sp) { + // Linux configures user-space virtual addresses with top byte ignored. + // We set default value of mask such that top byte is masked out. + address_mask = ~((1ULL << 56) - 1); + // If Pointer Authentication feature is enabled then Linux exposes + // PAC data and code mask register. Try reading relevant register + // below and merge it with default address mask calculated above. lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); if (reg_ctx_sp) { const RegisterInfo *reg_info = @@ -880,14 +887,3 @@ void ABISysV_arm64::Initialize() { void ABISysV_arm64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_arm64::GetPluginNameStatic() { - static ConstString g_name("SysV-arm64"); - return g_name; -} - -// PluginInterface protocol - -ConstString ABISysV_arm64::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ABISysV_arm64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 72560976cf7..170a4053809 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -14,6 +14,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" @@ -24,28 +25,35 @@ using namespace lldb; using namespace lldb_private; -/// Locates the address of the rendezvous structure. Returns the address on -/// success and LLDB_INVALID_ADDRESS on failure. -static addr_t ResolveRendezvousAddress(Process *process) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); +DYLDRendezvous::DYLDRendezvous(Process *process) + : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), + m_executable_interpreter(false), m_current(), m_previous(), + m_loaded_modules(), m_soentries(), m_added_soentries(), + m_removed_soentries() { + m_thread_info.valid = false; + UpdateExecutablePath(); +} + +addr_t DYLDRendezvous::ResolveRendezvousAddress() { + Log *log = GetLog(LLDBLog::DynamicLoader); addr_t info_location; addr_t info_addr; Status error; - if (!process) { + if (!m_process) { LLDB_LOGF(log, "%s null process provided", __FUNCTION__); return LLDB_INVALID_ADDRESS; } // Try to get it from our process. This might be a remote process and might // grab it via some remote-specific mechanism. - info_location = process->GetImageInfoAddress(); + info_location = m_process->GetImageInfoAddress(); LLDB_LOGF(log, "%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); // If the process fails to return an address, fall back to seeing if the // local object file can help us find it. if (info_location == LLDB_INVALID_ADDRESS) { - Target *target = &process->GetTarget(); + Target *target = &m_process->GetTarget(); if (target) { ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); Address addr = obj_file->GetImageInfoAddress(target); @@ -56,6 +64,20 @@ static addr_t ResolveRendezvousAddress(Process *process) { "%s resolved via direct object file approach to 0x%" PRIx64, __FUNCTION__, info_location); } else { + const Symbol *_r_debug = + target->GetExecutableModule()->FindFirstSymbolWithNameAndType( + ConstString("_r_debug")); + if (_r_debug) { + info_addr = _r_debug->GetAddress().GetLoadAddress(target); + if (info_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "%s resolved by finding symbol '_r_debug' whose value is " + "0x%" PRIx64, + __FUNCTION__, info_addr); + m_executable_interpreter = true; + return info_addr; + } + } LLDB_LOGF(log, "%s FAILED - direct object file approach did not yield a " "valid address", @@ -70,9 +92,9 @@ static addr_t ResolveRendezvousAddress(Process *process) { } LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, - __FUNCTION__, process->GetAddressByteSize(), info_location); + __FUNCTION__, m_process->GetAddressByteSize(), info_location); - info_addr = process->ReadPointerFromMemory(info_location, error); + info_addr = m_process->ReadPointerFromMemory(info_location, error); if (error.Fail()) { LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s", __FUNCTION__, error.AsCString()); @@ -90,22 +112,14 @@ static addr_t ResolveRendezvousAddress(Process *process) { return info_addr; } -DYLDRendezvous::DYLDRendezvous(Process *process) - : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(), - m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(), - m_removed_soentries() { - m_thread_info.valid = false; - UpdateExecutablePath(); -} - void DYLDRendezvous::UpdateExecutablePath() { if (m_process) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer(); if (exe_mod) { m_exe_file_spec = exe_mod->GetPlatformFileSpec(); LLDB_LOGF(log, "DYLDRendezvous::%s exe module executable path set: '%s'", - __FUNCTION__, m_exe_file_spec.GetCString()); + __FUNCTION__, m_exe_file_spec.GetPath().c_str()); } else { LLDB_LOGF(log, "DYLDRendezvous::%s cannot cache exe module path: null " @@ -116,7 +130,7 @@ void DYLDRendezvous::UpdateExecutablePath() { } bool DYLDRendezvous::Resolve() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); const size_t word_size = 4; Rendezvous info; @@ -132,7 +146,8 @@ bool DYLDRendezvous::Resolve() { __FUNCTION__, uint64_t(address_size), uint64_t(padding)); if (m_rendezvous_addr == LLDB_INVALID_ADDRESS) - cursor = info_addr = ResolveRendezvousAddress(m_process); + cursor = info_addr = + ResolveRendezvousAddress(); else cursor = info_addr = m_rendezvous_addr; LLDB_LOGF(log, "DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, @@ -175,6 +190,14 @@ bool DYLDRendezvous::IsValid() { } DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const { + // If we have a core file, we will read the current rendezvous state + // from the core file's memory into m_current which can be in an inconsistent + // state, so we can't rely on its state to determine what we should do. We + // always need it to load all of the shared libraries one time when we attach + // to a core file. + if (IsCoreFile()) + return eTakeSnapshot; + switch (m_current.state) { case eConsistent: @@ -195,14 +218,7 @@ DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const { case eAdd: case eDelete: - // Some versions of the android dynamic linker might send two - // notifications with state == eAdd back to back. Ignore them until we - // get an eConsistent notification. - if (!(m_previous.state == eConsistent || - (m_previous.state == eAdd && m_current.state == eDelete))) - return eNoAction; - - return eTakeSnapshot; + return eNoAction; } return eNoAction; @@ -214,9 +230,9 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() { if (action == eNoAction) return false; + m_added_soentries.clear(); + m_removed_soentries.clear(); if (action == eTakeSnapshot) { - m_added_soentries.clear(); - m_removed_soentries.clear(); // We already have the loaded list from the previous update so no need to // find all the modules again. if (!m_loaded_modules.m_list.empty()) @@ -245,11 +261,11 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() { } bool DYLDRendezvous::UpdateSOEntries() { + m_added_soentries.clear(); + m_removed_soentries.clear(); switch (GetAction()) { case eTakeSnapshot: m_soentries.clear(); - m_added_soentries.clear(); - m_removed_soentries.clear(); return TakeSnapshot(m_soentries); case eAddModules: return AddSOEntries(); @@ -296,8 +312,10 @@ bool DYLDRendezvous::SaveSOEntriesFromRemote( return false; // Only add shared libraries and not the executable. - if (!SOEntryIsMainExecutable(entry)) + if (!SOEntryIsMainExecutable(entry)) { + UpdateFileSpecIfNecessary(entry); m_soentries.push_back(entry); + } } m_loaded_modules = module_list; @@ -324,6 +342,7 @@ bool DYLDRendezvous::AddSOEntriesFromRemote( // Only add shared libraries and not the executable. if (!SOEntryIsMainExecutable(entry)) { + UpdateFileSpecIfNecessary(entry); m_soentries.push_back(entry); m_added_soentries.push_back(entry); } @@ -383,8 +402,9 @@ bool DYLDRendezvous::AddSOEntries() { if (SOEntryIsMainExecutable(entry)) continue; - pos = std::find(m_soentries.begin(), m_soentries.end(), entry); - if (pos == m_soentries.end()) { + UpdateFileSpecIfNecessary(entry); + + if (!llvm::is_contained(m_soentries, entry)) { m_soentries.push_back(entry); m_added_soentries.push_back(entry); } @@ -403,8 +423,7 @@ bool DYLDRendezvous::RemoveSOEntries() { return false; for (iterator I = begin(); I != end(); ++I) { - pos = std::find(entry_list.begin(), entry_list.end(), *I); - if (pos == entry_list.end()) + if (!llvm::is_contained(entry_list, *I)) m_removed_soentries.push_back(*I); } @@ -425,6 +444,10 @@ bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) { case llvm::Triple::Linux: if (triple.isAndroid()) return entry.file_spec == m_exe_file_spec; + // If we are debugging ld.so, then all SOEntries should be treated as + // libraries, including the "main" one (denoted by an empty string). + if (!entry.file_spec && m_executable_interpreter) + return false; return !entry.file_spec; default: return false; @@ -448,6 +471,8 @@ bool DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) { if (SOEntryIsMainExecutable(entry)) continue; + UpdateFileSpecIfNecessary(entry); + entry_list.push_back(entry); } @@ -513,6 +538,19 @@ void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, } } +void DYLDRendezvous::UpdateFileSpecIfNecessary(SOEntry &entry) { + // Updates filename if empty. It is useful while debugging ld.so, + // when the link map returns empty string for the main executable. + if (!entry.file_spec) { + MemoryRegionInfo region; + Status region_status = + m_process->GetMemoryRegionInfo(entry.dyn_addr, region); + if (!region.GetName().IsEmpty()) + entry.file_spec.SetFile(region.GetName().AsCString(), + FileSpec::Style::native); + } +} + bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) { entry.clear(); @@ -627,7 +665,7 @@ void DYLDRendezvous::DumpToLog(Log *log) const { log->PutCString("DYLDRendezvous SOEntries:"); for (int i = 1; I != E; ++I, ++i) { - LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->file_spec.GetCString()); + LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->file_spec.GetPath().c_str()); LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr); LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr); LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr); @@ -635,3 +673,7 @@ void DYLDRendezvous::DumpToLog(Log *log) const { LLDB_LOGF(log, " Prev : %" PRIx64, I->prev); } } + +bool DYLDRendezvous::IsCoreFile() const { + return !m_process->IsLiveDebugSession(); +} diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index ac5f3d4a5a7..1f05dbe3535 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -21,10 +21,12 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ProcessInfo.h" #include +#include using namespace lldb; using namespace lldb_private; @@ -38,22 +40,11 @@ void DynamicLoaderPOSIXDYLD::Initialize() { void DynamicLoaderPOSIXDYLD::Terminate() {} -lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() { - return GetPluginNameStatic(); -} - -lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() { - static ConstString g_name("linux-dyld"); - return g_name; -} - -const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() { +llvm::StringRef DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() { return "Dynamic loader plug-in that watches for shared library " "loads/unloads in POSIX processes."; } -uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; } - DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, bool force) { bool create = force; @@ -88,7 +79,7 @@ DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { } void DynamicLoaderPOSIXDYLD::DidAttach() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); m_auxv = std::make_unique(m_process->GetAuxvData()); @@ -97,10 +88,6 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); - // ask the process if it can load any of its own modules - auto error = m_process->LoadModules(); - LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}"); - ModuleSP executable_sp = GetTargetExecutable(); ResolveExecutableModule(executable_sp); m_rendezvous.UpdateExecutablePath(); @@ -178,7 +165,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { } void DynamicLoaderPOSIXDYLD::DidLaunch() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__); ModuleSP executable; @@ -226,7 +213,11 @@ void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) { } void DynamicLoaderPOSIXDYLD::ProbeEntry() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); + + // If we have a core file, we don't need any breakpoints. + if (IsCoreFile()) + return; const addr_t entry = GetEntryPoint(); if (entry == LLDB_INVALID_ADDRESS) { @@ -269,7 +260,7 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( if (!baton) return false; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast(baton); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, @@ -311,7 +302,12 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( } bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); + + // If we have a core file, we don't need any breakpoints. + if (IsCoreFile()) + return false; + if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { LLDB_LOG(log, "Rendezvous breakpoint breakpoint id {0} for pid {1}" @@ -324,7 +320,7 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { addr_t break_addr; Target &target = m_process->GetTarget(); BreakpointSP dyld_break; - if (m_rendezvous.IsValid()) { + if (m_rendezvous.IsValid() && m_rendezvous.GetBreakAddress() != 0) { break_addr = m_rendezvous.GetBreakAddress(); LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}", m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, @@ -334,28 +330,37 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { LLDB_LOG(log, "Rendezvous structure is not set up yet. " "Trying to locate rendezvous breakpoint in the interpreter " "by symbol name."); - ModuleSP interpreter = LoadInterpreterModule(); - if (!interpreter) { - LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set."); - return false; - } - - // Function names from different dynamic loaders that are known to be used - // as rendezvous between the loader and debuggers. + // Function names from different dynamic loaders that are known to be + // used as rendezvous between the loader and debuggers. static std::vector DebugStateCandidates{ "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", "r_debug_state", "_r_debug_state", "_rtld_debug_state", }; - FileSpecList containingModules; - containingModules.Append(interpreter->GetFileSpec()); - dyld_break = target.CreateBreakpoint( - &containingModules, nullptr /* containingSourceFiles */, - DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, - 0, /* offset */ - eLazyBoolNo, /* skip_prologue */ - true, /* internal */ - false /* request_hardware */); + ModuleSP interpreter = LoadInterpreterModule(); + if (!interpreter) { + FileSpecList containingModules; + containingModules.Append( + m_process->GetTarget().GetExecutableModulePointer()->GetFileSpec()); + + dyld_break = target.CreateBreakpoint( + &containingModules, /*containingSourceFiles=*/nullptr, + DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, + /*m_offset=*/0, + /*skip_prologue=*/eLazyBoolNo, + /*internal=*/true, + /*request_hardware=*/false); + } else { + FileSpecList containingModules; + containingModules.Append(interpreter->GetFileSpec()); + dyld_break = target.CreateBreakpoint( + &containingModules, /*containingSourceFiles=*/nullptr, + DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, + /*m_offset=*/0, + /*skip_prologue=*/eLazyBoolNo, + /*internal=*/true, + /*request_hardware=*/false); + } } if (dyld_break->GetNumResolvedLocations() != 1) { @@ -390,7 +395,7 @@ bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( if (!baton) return false; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast(baton); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, @@ -439,23 +444,31 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() { for (; I != E; ++I) { ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); - if (module_sp.get()) { - if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( - &m_process->GetTarget()) == m_interpreter_base && - module_sp != m_interpreter_module.lock()) { - // If this is a duplicate instance of ld.so, unload it. We may end up - // with it if we load it via a different path than before (symlink - // vs real path). + if (!module_sp.get()) + continue; + + if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( + &m_process->GetTarget()) == m_interpreter_base) { + ModuleSP interpreter_sp = m_interpreter_module.lock(); + if (m_interpreter_module.lock() == nullptr) { + m_interpreter_module = module_sp; + } else if (module_sp == interpreter_sp) { + // Module already loaded. + continue; + } else { + // If this is a duplicate instance of ld.so, unload it. We may end + // up with it if we load it via a different path than before + // (symlink vs real path). // TODO: remove this once we either fix library matching or avoid // loading the interpreter when setting the rendezvous breakpoint. UnloadSections(module_sp); loaded_modules.Remove(module_sp); continue; } - - loaded_modules.AppendIfNeeded(module_sp); - new_modules.Append(module_sp); } + + loaded_modules.AppendIfNeeded(module_sp); + new_modules.Append(module_sp); } m_process->GetTarget().ModulesDidLoad(new_modules); } @@ -490,7 +503,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, if (sym == nullptr || !sym->IsTrampoline()) return thread_plan_sp; - ConstString sym_name = sym->GetName(); + ConstString sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); if (!sym_name) return thread_plan_sp; @@ -538,7 +551,7 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO() { MemoryRegionInfo info; Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info); if (status.Fail()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOG(log, "Failed to get vdso region info: {0}", status); return; } @@ -559,7 +572,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info); if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes || info.GetName().IsEmpty()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOG(log, "Failed to get interpreter region info: {0}", status); return nullptr; } @@ -567,7 +580,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { FileSpec file(info.GetName().GetCString()); ModuleSpec module_spec(file, target.GetArchitecture()); - if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, + if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, true /* notify */)) { UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, false); @@ -577,11 +590,43 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { return nullptr; } +ModuleSP DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { + if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( + file, link_map_addr, base_addr, base_addr_is_offset)) + return module_sp; + + // This works around an dynamic linker "bug" on android <= 23, where the + // dynamic linker would report the application name + // (e.g. com.example.myapplication) instead of the main process binary + // (/system/bin/app_process(32)). The logic is not sound in general (it + // assumes base_addr is the real address, even though it actually is a load + // bias), but it happens to work on android because app_process has a file + // address of zero. + // This should be removed after we drop support for android-23. + if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) { + MemoryRegionInfo memory_info; + Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info); + if (error.Success() && memory_info.GetMapped() && + memory_info.GetRange().GetRangeBase() == base_addr && + !(memory_info.GetName().IsEmpty())) { + if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( + FileSpec(memory_info.GetName().GetStringRef()), link_map_addr, + base_addr, base_addr_is_offset)) + return module_sp; + } + } + + return nullptr; +} + void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { DYLDRendezvous::iterator I; DYLDRendezvous::iterator E; ModuleList module_list; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LoadVDSO(); @@ -612,15 +657,16 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { I->file_spec.GetFilename()); module_list.Append(module_sp); } else { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF( log, "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, - __FUNCTION__, I->file_spec.GetCString(), I->base_addr); + __FUNCTION__, I->file_spec.GetPath().c_str(), I->base_addr); } } m_process->GetTarget().ModulesDidLoad(module_list); + m_initial_modules_added = true; } addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { @@ -650,11 +696,11 @@ addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { } void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() { - if (llvm::Optional vdso_base = + if (std::optional vdso_base = m_auxv->GetAuxValue(AuxVector::AUXV_AT_SYSINFO_EHDR)) m_vdso_base = *vdso_base; - if (llvm::Optional interpreter_base = + if (std::optional interpreter_base = m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE)) m_interpreter_base = *interpreter_base; } @@ -666,7 +712,7 @@ addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() { if (m_auxv == nullptr) return LLDB_INVALID_ADDRESS; - llvm::Optional entry_point = + std::optional entry_point = m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY); if (!entry_point) return LLDB_INVALID_ADDRESS; @@ -720,7 +766,7 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid; addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::Performed TLS lookup: " "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 @@ -736,7 +782,7 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( lldb::ModuleSP &module_sp) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Log *log = GetLog(LLDBLog::DynamicLoader); if (m_process == nullptr) return; @@ -794,3 +840,7 @@ bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo( return module_sp->GetFileSpec().GetPath() == "[vdso]"; } + +bool DynamicLoaderPOSIXDYLD::IsCoreFile() const { + return !m_process->IsLiveDebugSession(); +} diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp deleted file mode 100644 index e5b868fc0fc..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//===-- LibCxxBitset.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 "LibCxx.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { - -class BitsetFrontEnd : public SyntheticChildrenFrontEnd { -public: - BitsetFrontEnd(ValueObject &valobj); - - size_t GetIndexOfChildWithName(ConstString name) override { - return formatters::ExtractIndexFromString(name.GetCString()); - } - - bool MightHaveChildren() override { return true; } - bool Update() override; - size_t CalculateNumChildren() override { return m_elements.size(); } - ValueObjectSP GetChildAtIndex(size_t idx) override; - -private: - // The lifetime of a ValueObject and all its derivative ValueObjects - // (children, clones, etc.) is managed by a ClusterManager. These - // objects are only destroyed when every shared pointer to any of them - // is destroyed, so we must not store a shared pointer to any ValueObject - // derived from our backend ValueObject (since we're in the same cluster). - // Value objects created from raw data (i.e. in a different cluster) must - // be referenced via shared pointer to keep them alive, however. - std::vector m_elements; - ValueObject* m_first = nullptr; - CompilerType m_bool_type; - ByteOrder m_byte_order = eByteOrderInvalid; - uint8_t m_byte_size = 0; -}; -} // namespace - -BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj) - : SyntheticChildrenFrontEnd(valobj) { - m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool); - if (auto target_sp = m_backend.GetTargetSP()) { - m_byte_order = target_sp->GetArchitecture().GetByteOrder(); - m_byte_size = target_sp->GetArchitecture().GetAddressByteSize(); - Update(); - } -} - -bool BitsetFrontEnd::Update() { - m_elements.clear(); - m_first = nullptr; - - TargetSP target_sp = m_backend.GetTargetSP(); - if (!target_sp) - return false; - size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay(); - - size_t size = 0; - if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0)) - size = arg->value.getLimitedValue(capping_size); - - m_elements.assign(size, ValueObjectSP()); - - m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get(); - return false; -} - -ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { - if (idx >= m_elements.size() || !m_first) - return ValueObjectSP(); - - if (m_elements[idx]) - return m_elements[idx]; - - ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false); - CompilerType type; - ValueObjectSP chunk; - // For small bitsets __first_ is not an array, but a plain size_t. - if (m_first->GetCompilerType().IsArrayType(&type)) { - llvm::Optional bit_size = - type.GetBitSize(ctx.GetBestExecutionContextScope()); - if (!bit_size || *bit_size == 0) - return {}; - chunk = m_first->GetChildAtIndex(idx / *bit_size, true); - } else { - type = m_first->GetCompilerType(); - chunk = m_first->GetSP(); - } - if (!type || !chunk) - return {}; - - llvm::Optional bit_size = - type.GetBitSize(ctx.GetBestExecutionContextScope()); - if (!bit_size || *bit_size == 0) - return {}; - size_t chunk_idx = idx % *bit_size; - uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx)); - DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size); - - m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), - data, ctx, m_bool_type); - - return m_elements[idx]; -} - -SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator( - CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) - return new BitsetFrontEnd(*valobj_sp); - return nullptr; -} diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp deleted file mode 100644 index c0c81963285..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp +++ /dev/null @@ -1,84 +0,0 @@ -//===-- LibCxxOptional.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 "LibCxx.h" -#include "lldb/DataFormatters/FormattersHelpers.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { - -class OptionalFrontEnd : public SyntheticChildrenFrontEnd { -public: - OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { - Update(); - } - - size_t GetIndexOfChildWithName(ConstString name) override { - return formatters::ExtractIndexFromString(name.GetCString()); - } - - bool MightHaveChildren() override { return true; } - bool Update() override; - size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; } - ValueObjectSP GetChildAtIndex(size_t idx) override; - -private: - /// True iff the option contains a value. - bool m_has_value = false; -}; -} // namespace - -bool OptionalFrontEnd::Update() { - ValueObjectSP engaged_sp( - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)); - - if (!engaged_sp) - return false; - - // __engaged_ is a bool flag and is true if the optional contains a value. - // Converting it to unsigned gives us a size of 1 if it contains a value - // and 0 if not. - m_has_value = engaged_sp->GetValueAsUnsigned(0) == 1; - - return false; -} - -ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { - if (!m_has_value) - return ValueObjectSP(); - - // __val_ contains the underlying value of an optional if it has one. - // Currently because it is part of an anonymous union GetChildMemberWithName() - // does not peer through and find it unless we are at the parent itself. - // We can obtain the parent through __engaged_. - ValueObjectSP val_sp( - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) - ->GetParent() - ->GetChildAtIndex(0, true) - ->GetChildMemberWithName(ConstString("__val_"), true)); - - if (!val_sp) - return ValueObjectSP(); - - CompilerType holder_type = val_sp->GetCompilerType(); - - if (!holder_type) - return ValueObjectSP(); - - return val_sp->Clone(ConstString("Value")); -} - -SyntheticChildrenFrontEnd * -formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, - lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) - return new OptionalFrontEnd(*valobj_sp); - return nullptr; -} diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 21beba045be..2fc52931cfc 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include "lldb/Core/FileSpecList.h" @@ -26,6 +27,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/Status.h" @@ -55,36 +57,36 @@ using namespace llvm::ELF; LLDB_PLUGIN_DEFINE(ObjectFileELF) -namespace { - // ELF note owner definitions -const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; -const char *const LLDB_NT_OWNER_GNU = "GNU"; -const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; -const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; -const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; -const char *const LLDB_NT_OWNER_ANDROID = "Android"; -const char *const LLDB_NT_OWNER_CORE = "CORE"; -const char *const LLDB_NT_OWNER_LINUX = "LINUX"; +static const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; +static const char *const LLDB_NT_OWNER_GNU = "GNU"; +static const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; +static const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; +static const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; +static const char *const LLDB_NT_OWNER_ANDROID = "Android"; +static const char *const LLDB_NT_OWNER_CORE = "CORE"; +static const char *const LLDB_NT_OWNER_LINUX = "LINUX"; // ELF note type definitions -const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; -const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; +static const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; +static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; -const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; -const elf_word LLDB_NT_GNU_ABI_SIZE = 16; +static const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; +static const elf_word LLDB_NT_GNU_ABI_SIZE = 16; -const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; +static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; -const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; -const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; -const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; -const elf_word LLDB_NT_NETBSD_PROCINFO = 1; +static const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; +static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; +static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; +static const elf_word LLDB_NT_NETBSD_PROCINFO = 1; // GNU ABI note OS constants -const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; -const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; -const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; +static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; +static const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; +static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; + +namespace { //===----------------------------------------------------------------------===// /// \class ELFRelocation @@ -112,19 +114,22 @@ public: static unsigned RelocSymbol64(const ELFRelocation &rel); - static unsigned RelocOffset32(const ELFRelocation &rel); + static elf_addr RelocOffset32(const ELFRelocation &rel); - static unsigned RelocOffset64(const ELFRelocation &rel); + static elf_addr RelocOffset64(const ELFRelocation &rel); - static unsigned RelocAddend32(const ELFRelocation &rel); + static elf_sxword RelocAddend32(const ELFRelocation &rel); - static unsigned RelocAddend64(const ELFRelocation &rel); + static elf_sxword RelocAddend64(const ELFRelocation &rel); + + bool IsRela() { return (reloc.is()); } private: typedef llvm::PointerUnion RelocUnion; RelocUnion reloc; }; +} // end anonymous namespace ELFRelocation::ELFRelocation(unsigned type) { if (type == DT_REL || type == SHT_REL) @@ -180,36 +185,34 @@ unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) { return ELFRela::RelocSymbol64(*rel.reloc.get()); } -unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) { +elf_addr ELFRelocation::RelocOffset32(const ELFRelocation &rel) { if (rel.reloc.is()) return rel.reloc.get()->r_offset; else return rel.reloc.get()->r_offset; } -unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) { +elf_addr ELFRelocation::RelocOffset64(const ELFRelocation &rel) { if (rel.reloc.is()) return rel.reloc.get()->r_offset; else return rel.reloc.get()->r_offset; } -unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) { +elf_sxword ELFRelocation::RelocAddend32(const ELFRelocation &rel) { if (rel.reloc.is()) return 0; else return rel.reloc.get()->r_addend; } -unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { +elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) { if (rel.reloc.is()) return 0; else return rel.reloc.get()->r_addend; } -} // end anonymous namespace - static user_id_t SegmentID(size_t PHdrIndex) { return ~user_id_t(PHdrIndex); } @@ -236,7 +239,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); if (cstr == nullptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); + Log *log = GetLog(LLDBLog::Symbols); LLDB_LOGF(log, "Failed to parse note name lacking nul terminator"); return false; @@ -310,11 +313,35 @@ static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) { } } +static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) { + uint32_t endian = header.e_ident[EI_DATA]; + if (endian == ELFDATA2LSB) + return ArchSpec::eCore_ppc64le_generic; + else + return ArchSpec::eCore_ppc64_generic; +} + +static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) { + uint32_t fileclass = header.e_ident[EI_CLASS]; + switch (fileclass) { + case llvm::ELF::ELFCLASS32: + return ArchSpec::eLoongArchSubType_loongarch32; + case llvm::ELF::ELFCLASS64: + return ArchSpec::eLoongArchSubType_loongarch64; + default: + return ArchSpec::eLoongArchSubType_unknown; + } +} + static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { if (header.e_machine == llvm::ELF::EM_MIPS) return mipsVariantFromElfFlags(header); + else if (header.e_machine == llvm::ELF::EM_PPC64) + return ppc64VariantFromElfFlags(header); else if (header.e_machine == llvm::ELF::EM_RISCV) return riscvVariantFromElfFlags(header); + else if (header.e_machine == llvm::ELF::EM_LOONGARCH) + return loongarchVariantFromElfFlags(header); return LLDB_INVALID_CPUTYPE; } @@ -335,26 +362,19 @@ void ObjectFileELF::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() { - static ConstString g_name("elf"); - return g_name; -} - -const char *ObjectFileELF::GetPluginDescriptionStatic() { - return "ELF object file reader."; -} - ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, - DataBufferSP &data_sp, + DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length) { + bool mapped_writable = false; if (!data_sp) { - data_sp = MapFileData(*file, length, file_offset); + data_sp = MapFileDataWritable(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; + mapped_writable = true; } assert(data_sp); @@ -368,10 +388,19 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, // Update the data to contain the entire file if it doesn't already if (data_sp->GetByteSize() < length) { - data_sp = MapFileData(*file, length, file_offset); + data_sp = MapFileDataWritable(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; + mapped_writable = true; + magic = data_sp->GetBytes(); + } + + // If we didn't map the data as writable take ownership of the buffer. + if (!mapped_writable) { + data_sp = std::make_shared(data_sp->GetBytes(), + data_sp->GetByteSize()); + data_offset = 0; magic = data_sp->GetBytes(); } @@ -388,7 +417,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, } ObjectFile *ObjectFileELF::CreateMemoryInstance( - const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, + const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) { const uint8_t *magic = data_sp->GetBytes(); @@ -418,8 +447,8 @@ bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, } static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) { - return llvm::crc32( - init, llvm::makeArrayRef(data.GetDataStart(), data.GetByteSize())); + return llvm::crc32(init, + llvm::ArrayRef(data.GetDataStart(), data.GetByteSize())); } uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( @@ -514,7 +543,7 @@ size_t ObjectFileELF::GetModuleSpecifications( const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); const size_t initial_count = specs.GetSize(); @@ -615,13 +644,13 @@ size_t ObjectFileELF::GetModuleSpecifications( if (gnu_debuglink_crc) { // Use 4 bytes of crc from the .gnu_debuglink section. u32le data(gnu_debuglink_crc); - uuid = UUID::fromData(&data, sizeof(data)); + uuid = UUID(&data, sizeof(data)); } else if (core_notes_crc) { // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make // it look different form .gnu_debuglink crc followed by 4 bytes // of note segments crc. u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; - uuid = UUID::fromData(data, sizeof(data)); + uuid = UUID(data, sizeof(data)); } } @@ -634,16 +663,10 @@ size_t ObjectFileELF::GetModuleSpecifications( return specs.GetSize() - initial_count; } -// PluginInterface protocol -lldb_private::ConstString ObjectFileELF::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; } // ObjectFile protocol ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, - DataBufferSP &data_sp, lldb::offset_t data_offset, + DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length) : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) { @@ -652,7 +675,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, } ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, - DataBufferSP &header_data_sp, + DataBufferSP header_data_sp, const lldb::ProcessSP &process_sp, addr_t header_addr) : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {} @@ -782,7 +805,7 @@ UUID ObjectFileELF::GetUUID() { // look different form .gnu_debuglink crc - followed by 4 bytes of note // segments crc. u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; - m_uuid = UUID::fromData(data, sizeof(data)); + m_uuid = UUID(data, sizeof(data)); } } else { if (!m_gnu_debuglink_crc) @@ -790,7 +813,7 @@ UUID ObjectFileELF::GetUUID() { if (m_gnu_debuglink_crc) { // Use 4 bytes of crc from the .gnu_debuglink section. u32le data(m_gnu_debuglink_crc); - m_uuid = UUID::fromData(&data, sizeof(data)); + m_uuid = UUID(&data, sizeof(data)); } } } @@ -798,9 +821,9 @@ UUID ObjectFileELF::GetUUID() { return m_uuid; } -llvm::Optional ObjectFileELF::GetDebugLink() { +std::optional ObjectFileELF::GetDebugLink() { if (m_gnu_debuglink_file.empty()) - return llvm::None; + return std::nullopt; return FileSpec(m_gnu_debuglink_file); } @@ -1014,7 +1037,7 @@ lldb_private::Status ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); Status error; lldb::offset_t offset = 0; @@ -1128,7 +1151,7 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, if (note.n_descsz >= 4) { if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) { // Save the build id as the UUID for the module. - uuid = UUID::fromData(buf, note.n_descsz); + uuid = UUID(buf, note.n_descsz); } else { error.SetErrorString("failed to read GNU_BUILD_ID note payload"); return error; @@ -1190,26 +1213,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, // register info arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); } else if (note.n_name == LLDB_NT_OWNER_CORE) { - // Parse the NT_FILE to look for stuff in paths to shared libraries As - // the contents look like this in a 64 bit ELF core file: count = - // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index - // start end file_ofs path ===== - // 0x0000000000401000 0x0000000000000000 /tmp/a.out [ 1] - // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [ - // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out - // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 - // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000 - // 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux- - // gnu/libc-2.19.so [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 - // 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so [ 6] - // 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64 - // -linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 - // 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so [ 8] - // 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64 - // -linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 - // 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so In the 32 bit ELFs - // the count, page_size, start, end, file_ofs are uint32_t For reference: - // see readelf source code (in binutils). + // Parse the NT_FILE to look for stuff in paths to shared libraries + // The contents look like this in a 64 bit ELF core file: + // + // count = 0x000000000000000a (10) + // page_size = 0x0000000000001000 (4096) + // Index start end file_ofs path + // ===== ------------------ ------------------ ------------------ ------------------------------------- + // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out + // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out + // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out + // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so + // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so + // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so + // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so + // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so + // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so + // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so + // + // In the 32 bit ELFs the count, page_size, start, end, file_ofs are + // uint32_t. + // + // For reference: see readelf source code (in binutils). if (note.n_type == NT_FILE) { uint64_t count = data.GetAddress(&offset); const char *cstr; @@ -1377,11 +1402,33 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); } + if (arch_spec.GetMachine() == llvm::Triple::riscv32 || + arch_spec.GetMachine() == llvm::Triple::riscv64) { + uint32_t flags = arch_spec.GetFlags(); + + if (header.e_flags & llvm::ELF::EF_RISCV_RVC) + flags |= ArchSpec::eRISCV_rvc; + if (header.e_flags & llvm::ELF::EF_RISCV_RVE) + flags |= ArchSpec::eRISCV_rve; + + if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) == + llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) + flags |= ArchSpec::eRISCV_float_abi_single; + else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) == + llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) + flags |= ArchSpec::eRISCV_float_abi_double; + else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) == + llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) + flags |= ArchSpec::eRISCV_float_abi_quad; + + arch_spec.SetFlags(flags); + } + // If there are no section headers we are done. if (header.e_shnum == 0) return 0; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); section_headers.resize(header.e_shnum); if (section_headers.size() != header.e_shnum) @@ -1577,7 +1624,7 @@ lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { } static SectionType GetSectionTypeFromName(llvm::StringRef Name) { - if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) { + if (Name.consume_front(".debug_")) { return llvm::StringSwitch(Name) .Case("abbrev", eSectionTypeDWARFDebugAbbrev) .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) @@ -1694,9 +1741,9 @@ class VMAddressProvider { ObjectFile::Type ObjectType; addr_t NextVMAddress = 0; VMMap::Allocator Alloc; - VMMap Segments = VMMap(Alloc); - VMMap Sections = VMMap(Alloc); - lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); + VMMap Segments{Alloc}; + VMMap Sections{Alloc}; + lldb_private::Log *Log = GetLog(LLDBLog::Modules); size_t SegmentCount = 0; std::string SegmentName; @@ -1720,22 +1767,22 @@ public: return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str(); } - llvm::Optional GetAddressInfo(const ELFProgramHeader &H) { + std::optional GetAddressInfo(const ELFProgramHeader &H) { if (H.p_memsz == 0) { LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?", SegmentName); - return llvm::None; + return std::nullopt; } if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) { LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?", SegmentName); - return llvm::None; + return std::nullopt; } return VMRange(H.p_vaddr, H.p_memsz); } - llvm::Optional GetAddressInfo(const ELFSectionHeader &H) { + std::optional GetAddressInfo(const ELFSectionHeader &H) { VMRange Range = GetVMRange(H); SectionSP Segment; auto It = Segments.find(Range.GetRangeBase()); @@ -1755,7 +1802,7 @@ public: if (Range.GetByteSize() > 0 && Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) { LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?"); - return llvm::None; + return std::nullopt; } if (Segment) Range.Slide(-Segment->GetFileAddress()); @@ -1905,7 +1952,7 @@ std::shared_ptr ObjectFileELF::GetGnuDebugDataObjectFile() { auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData); if (err) { GetModule()->ReportWarning( - "An error occurred while decompression the section %s: %s", + "An error occurred while decompression the section {0}: {1}", section->GetName().AsCString(), llvm::toString(std::move(err)).c_str()); return nullptr; } @@ -2193,23 +2240,6 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, // symbols. See above for more details. uint64_t symbol_value = symbol.st_value + symbol_value_offset; - if (symbol_section_sp == nullptr && shndx == SHN_ABS && - symbol.st_size != 0) { - // We don't have a section for a symbol with non-zero size. Create a new - // section for it so the address range covered by the symbol is also - // covered by the module (represented through the section list). It is - // needed so module lookup for the addresses covered by this symbol will - // be successfull. This case happens for absolute symbols. - ConstString fake_section_name(std::string(".absolute.") + symbol_name); - symbol_section_sp = - std::make_shared
(module_sp, this, SHN_ABS, fake_section_name, - eSectionTypeAbsoluteAddress, symbol_value, - symbol.st_size, 0, 0, 0, SHF_ALLOC); - - module_section_list->AddSection(symbol_section_sp); - section_list->AddSection(symbol_section_sp); - } - if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile) symbol_value -= symbol_section_sp->GetFileAddress(); @@ -2563,6 +2593,50 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, rel_data, symtab_data, strtab_data); } +static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel, + DataExtractor &debug_data, + Section *rel_section) { + Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel)); + if (symbol) { + addr_t value = symbol->GetAddressRef().GetFileAddress(); + DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast(data_buffer_sp.get()); + uint64_t *dst = reinterpret_cast( + data_buffer->GetBytes() + rel_section->GetFileOffset() + + ELFRelocation::RelocOffset64(rel)); + uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); + memcpy(dst, &val_offset, sizeof(uint64_t)); + } +} + +static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel, + DataExtractor &debug_data, + Section *rel_section, bool is_signed) { + Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel)); + if (symbol) { + addr_t value = symbol->GetAddressRef().GetFileAddress(); + value += ELFRelocation::RelocAddend32(rel); + if ((!is_signed && (value > UINT32_MAX)) || + (is_signed && + ((int64_t)value > INT32_MAX || (int64_t)value < INT32_MIN))) { + Log *log = GetLog(LLDBLog::Modules); + LLDB_LOGF(log, "Failed to apply debug info relocations"); + return; + } + uint32_t truncated_addr = (value & 0xFFFFFFFF); + DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast(data_buffer_sp.get()); + uint32_t *dst = reinterpret_cast( + data_buffer->GetBytes() + rel_section->GetFileOffset() + + ELFRelocation::RelocOffset32(rel)); + memcpy(dst, &truncated_addr, sizeof(uint32_t)); + } +} + unsigned ObjectFileELF::ApplyRelocations( Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr, @@ -2584,71 +2658,92 @@ unsigned ObjectFileELF::ApplyRelocations( } for (unsigned i = 0; i < num_relocations; ++i) { - if (!rel.Parse(rel_data, &offset)) + if (!rel.Parse(rel_data, &offset)) { + GetModule()->ReportError(".rel{0}[{1:d}] failed to parse relocation", + rel_section->GetName().AsCString(), i); break; - + } Symbol *symbol = nullptr; if (hdr->Is32Bit()) { switch (reloc_type(rel)) { case R_386_32: - case R_386_PC32: - default: - // FIXME: This asserts with this input: - // - // foo.cpp - // int main(int argc, char **argv) { return 0; } - // - // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o - // - // and running this on the foo.o module. - assert(false && "unexpected relocation type"); - } - } else { - switch (reloc_type(rel)) { - case R_AARCH64_ABS64: - case R_X86_64_64: { symbol = symtab->FindSymbolByID(reloc_symbol(rel)); if (symbol) { - addr_t value = symbol->GetAddressRef().GetFileAddress(); + addr_t f_offset = + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel); DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); - uint64_t *dst = reinterpret_cast( - data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + - ELFRelocation::RelocOffset64(rel)); - uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); - memcpy(dst, &val_offset, sizeof(uint64_t)); - } - break; - } - case R_X86_64_32: - case R_X86_64_32S: - case R_AARCH64_ABS32: { - symbol = symtab->FindSymbolByID(reloc_symbol(rel)); - if (symbol) { + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast(data_buffer_sp.get()); + uint32_t *dst = reinterpret_cast( + data_buffer->GetBytes() + f_offset); + addr_t value = symbol->GetAddressRef().GetFileAddress(); - value += ELFRelocation::RelocAddend32(rel); - if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) || - (reloc_type(rel) == R_X86_64_32S && - ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || - (reloc_type(rel) == R_AARCH64_ABS32 && - ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { - Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); - LLDB_LOGF(log, "Failed to apply debug info relocations"); - break; + if (rel.IsRela()) { + value += ELFRelocation::RelocAddend32(rel); + } else { + value += *dst; } - uint32_t truncated_addr = (value & 0xFFFFFFFF); - DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); - uint32_t *dst = reinterpret_cast( - data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + - ELFRelocation::RelocOffset32(rel)); - memcpy(dst, &truncated_addr, sizeof(uint32_t)); + *dst = value; + } else { + GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}", + rel_section->GetName().AsCString(), i, + reloc_symbol(rel)); } break; + case R_386_PC32: + default: + GetModule()->ReportError("unsupported 32-bit relocation:" + " .rel{0}[{1}], type {2}", + rel_section->GetName().AsCString(), i, + reloc_type(rel)); } - case R_X86_64_PC32: + } else { + switch (hdr->e_machine) { + case llvm::ELF::EM_AARCH64: + switch (reloc_type(rel)) { + case R_AARCH64_ABS64: + ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section); + break; + case R_AARCH64_ABS32: + ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true); + break; + default: + assert(false && "unexpected relocation type"); + } + break; + case llvm::ELF::EM_LOONGARCH: + switch (reloc_type(rel)) { + case R_LARCH_64: + ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section); + break; + case R_LARCH_32: + ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true); + break; + default: + assert(false && "unexpected relocation type"); + } + break; + case llvm::ELF::EM_X86_64: + switch (reloc_type(rel)) { + case R_X86_64_64: + ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section); + break; + case R_X86_64_32: + ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, + false); + break; + case R_X86_64_32S: + ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true); + break; + case R_X86_64_PC32: + default: + assert(false && "unexpected relocation type"); + } + break; default: - assert(false && "unexpected relocation type"); + assert(false && "unsupported machine"); } } } @@ -2703,156 +2798,133 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, return 0; } -Symtab *ObjectFileELF::GetSymtab() { +void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) { ModuleSP module_sp(GetModule()); if (!module_sp) - return nullptr; + return; - Progress progress(llvm::formatv("Parsing symbol table for {0}", - m_file.GetFilename().AsCString(""))); + Progress progress( + llvm::formatv("Parsing symbol table for {0}", + m_file.GetFilename().AsCString(""))); + ElapsedTime elapsed(module_sp->GetSymtabParseTime()); // We always want to use the main object file so we (hopefully) only have one // cached copy of our symtab, dynamic sections, etc. ObjectFile *module_obj_file = module_sp->GetObjectFile(); if (module_obj_file && module_obj_file != this) - return module_obj_file->GetSymtab(); - - if (m_symtab_up == nullptr) { - SectionList *section_list = module_sp->GetSectionList(); - if (!section_list) - return nullptr; + return module_obj_file->ParseSymtab(lldb_symtab); - uint64_t symbol_id = 0; - std::lock_guard guard(module_sp->GetMutex()); - - // Sharable objects and dynamic executables usually have 2 distinct symbol - // tables, one named ".symtab", and the other ".dynsym". The dynsym is a - // smaller version of the symtab that only contains global symbols. The - // information found in the dynsym is therefore also found in the symtab, - // while the reverse is not necessarily true. - Section *symtab = - section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); - if (symtab) { - m_symtab_up = std::make_unique(symtab->GetObjectFile()); - symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab); - } + SectionList *section_list = module_sp->GetSectionList(); + if (!section_list) + return; - // The symtab section is non-allocable and can be stripped, while the - // .dynsym section which should always be always be there. To support the - // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo - // section, nomatter if .symtab was already parsed or not. This is because - // minidebuginfo normally removes the .symtab symbols which have their - // matching .dynsym counterparts. - if (!symtab || - GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) { - Section *dynsym = - section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) - .get(); - if (dynsym) { - if (!m_symtab_up) - m_symtab_up = std::make_unique(dynsym->GetObjectFile()); - symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym); - } - } + uint64_t symbol_id = 0; - // DT_JMPREL - // If present, this entry's d_ptr member holds the address of - // relocation - // entries associated solely with the procedure linkage table. - // Separating - // these relocation entries lets the dynamic linker ignore them during - // process initialization, if lazy binding is enabled. If this entry is - // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must - // also be present. - const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); - if (symbol) { - const ELFDynamic *pltrelsz = FindDynamicSymbol(DT_PLTRELSZ); - assert(pltrelsz != NULL); - // Synthesize trampoline symbols to help navigate the PLT. - addr_t addr = symbol->d_ptr; - Section *reloc_section = - section_list->FindSectionContainingFileAddress(addr).get(); - if (reloc_section && pltrelsz->d_val > 0) { - user_id_t reloc_id = reloc_section->GetID(); - const ELFSectionHeaderInfo *reloc_header = - GetSectionHeaderByIndex(reloc_id); - if (reloc_header) { - if (m_symtab_up == nullptr) - m_symtab_up = - std::make_unique(reloc_section->GetObjectFile()); - - ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header, - reloc_id); - } - } - } - - if (DWARFCallFrameInfo *eh_frame = - GetModule()->GetUnwindTable().GetEHFrameInfo()) { - if (m_symtab_up == nullptr) - m_symtab_up = std::make_unique(this); - ParseUnwindSymbols(m_symtab_up.get(), eh_frame); + // Sharable objects and dynamic executables usually have 2 distinct symbol + // tables, one named ".symtab", and the other ".dynsym". The dynsym is a + // smaller version of the symtab that only contains global symbols. The + // information found in the dynsym is therefore also found in the symtab, + // while the reverse is not necessarily true. + Section *symtab = + section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); + if (symtab) + symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab); + + // The symtab section is non-allocable and can be stripped, while the + // .dynsym section which should always be always be there. To support the + // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo + // section, nomatter if .symtab was already parsed or not. This is because + // minidebuginfo normally removes the .symtab symbols which have their + // matching .dynsym counterparts. + if (!symtab || + GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) { + Section *dynsym = + section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) + .get(); + if (dynsym) + symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym); + } + + // DT_JMPREL + // If present, this entry's d_ptr member holds the address of + // relocation + // entries associated solely with the procedure linkage table. + // Separating + // these relocation entries lets the dynamic linker ignore them during + // process initialization, if lazy binding is enabled. If this entry is + // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must + // also be present. + const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); + if (symbol) { + const ELFDynamic *pltrelsz = FindDynamicSymbol(DT_PLTRELSZ); + assert(pltrelsz != NULL); + // Synthesize trampoline symbols to help navigate the PLT. + addr_t addr = symbol->d_ptr; + Section *reloc_section = + section_list->FindSectionContainingFileAddress(addr).get(); + if (reloc_section && pltrelsz->d_val > 0) { + user_id_t reloc_id = reloc_section->GetID(); + const ELFSectionHeaderInfo *reloc_header = + GetSectionHeaderByIndex(reloc_id); + if (reloc_header) + ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id); } + } - // If we still don't have any symtab then create an empty instance to avoid - // do the section lookup next time. - if (m_symtab_up == nullptr) - m_symtab_up = std::make_unique(this); - - // In the event that there's no symbol entry for the entry point we'll - // artificially create one. We delegate to the symtab object the figuring - // out of the proper size, this will usually make it span til the next - // symbol it finds in the section. This means that if there are missing - // symbols the entry point might span beyond its function definition. - // We're fine with this as it doesn't make it worse than not having a - // symbol entry at all. - if (CalculateType() == eTypeExecutable) { - ArchSpec arch = GetArchitecture(); - auto entry_point_addr = GetEntryPointAddress(); - bool is_valid_entry_point = - entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset(); - addr_t entry_point_file_addr = entry_point_addr.GetFileAddress(); - if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress( - entry_point_file_addr)) { - uint64_t symbol_id = m_symtab_up->GetNumSymbols(); - // Don't set the name for any synthetic symbols, the Symbol - // object will generate one if needed when the name is accessed - // via accessors. - SectionSP section_sp = entry_point_addr.GetSection(); - Symbol symbol( - /*symID=*/symbol_id, - /*name=*/llvm::StringRef(), // Name will be auto generated. - /*type=*/eSymbolTypeCode, - /*external=*/true, - /*is_debug=*/false, - /*is_trampoline=*/false, - /*is_artificial=*/true, - /*section_sp=*/section_sp, - /*offset=*/0, - /*size=*/0, // FDE can span multiple symbols so don't use its size. - /*size_is_valid=*/false, - /*contains_linker_annotations=*/false, - /*flags=*/0); - // When the entry point is arm thumb we need to explicitly set its - // class address to reflect that. This is important because expression - // evaluation relies on correctly setting a breakpoint at this - // address. - if (arch.GetMachine() == llvm::Triple::arm && - (entry_point_file_addr & 1)) { - symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1); - m_address_class_map[entry_point_file_addr ^ 1] = - AddressClass::eCodeAlternateISA; - } else { - m_address_class_map[entry_point_file_addr] = AddressClass::eCode; - } - m_symtab_up->AddSymbol(symbol); + if (DWARFCallFrameInfo *eh_frame = + GetModule()->GetUnwindTable().GetEHFrameInfo()) { + ParseUnwindSymbols(&lldb_symtab, eh_frame); + } + + // In the event that there's no symbol entry for the entry point we'll + // artificially create one. We delegate to the symtab object the figuring + // out of the proper size, this will usually make it span til the next + // symbol it finds in the section. This means that if there are missing + // symbols the entry point might span beyond its function definition. + // We're fine with this as it doesn't make it worse than not having a + // symbol entry at all. + if (CalculateType() == eTypeExecutable) { + ArchSpec arch = GetArchitecture(); + auto entry_point_addr = GetEntryPointAddress(); + bool is_valid_entry_point = + entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset(); + addr_t entry_point_file_addr = entry_point_addr.GetFileAddress(); + if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress( + entry_point_file_addr)) { + uint64_t symbol_id = lldb_symtab.GetNumSymbols(); + // Don't set the name for any synthetic symbols, the Symbol + // object will generate one if needed when the name is accessed + // via accessors. + SectionSP section_sp = entry_point_addr.GetSection(); + Symbol symbol( + /*symID=*/symbol_id, + /*name=*/llvm::StringRef(), // Name will be auto generated. + /*type=*/eSymbolTypeCode, + /*external=*/true, + /*is_debug=*/false, + /*is_trampoline=*/false, + /*is_artificial=*/true, + /*section_sp=*/section_sp, + /*offset=*/0, + /*size=*/0, // FDE can span multiple symbols so don't use its size. + /*size_is_valid=*/false, + /*contains_linker_annotations=*/false, + /*flags=*/0); + // When the entry point is arm thumb we need to explicitly set its + // class address to reflect that. This is important because expression + // evaluation relies on correctly setting a breakpoint at this + // address. + if (arch.GetMachine() == llvm::Triple::arm && + (entry_point_file_addr & 1)) { + symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1); + m_address_class_map[entry_point_file_addr ^ 1] = + AddressClass::eCodeAlternateISA; + } else { + m_address_class_map[entry_point_file_addr] = AddressClass::eCode; } + lldb_symtab.AddSymbol(symbol); } - - m_symtab_up->CalculateSymbolSizes(); } - - return m_symtab_up.get(); } void ObjectFileELF::RelocateSection(lldb_private::Section *section) @@ -3355,8 +3427,7 @@ size_t ObjectFileELF::ReadSectionData(Section *section, return section->GetObjectFile()->ReadSectionData(section, section_data); size_t result = ObjectFile::ReadSectionData(section, section_data); - if (result == 0 || !llvm::object::Decompressor::isCompressedELFSection( - section->Get(), section->GetName().GetStringRef())) + if (result == 0 || !(section->Get() & llvm::ELF::SHF_COMPRESSED)) return result; auto Decompressor = llvm::object::Decompressor::create( @@ -3366,7 +3437,7 @@ size_t ObjectFileELF::ReadSectionData(Section *section, GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); if (!Decompressor) { GetModule()->ReportWarning( - "Unable to initialize decompressor for section '%s': %s", + "Unable to initialize decompressor for section '{0}': {1}", section->GetName().GetCString(), llvm::toString(Decompressor.takeError()).c_str()); section_data.Clear(); @@ -3376,12 +3447,10 @@ size_t ObjectFileELF::ReadSectionData(Section *section, auto buffer_sp = std::make_shared(Decompressor->getDecompressedSize(), 0); if (auto error = Decompressor->decompress( - {reinterpret_cast(buffer_sp->GetBytes()), - size_t(buffer_sp->GetByteSize())})) { - GetModule()->ReportWarning( - "Decompression of section '%s' failed: %s", - section->GetName().GetCString(), - llvm::toString(std::move(error)).c_str()); + {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) { + GetModule()->ReportWarning("Decompression of section '{0}' failed: {1}", + section->GetName().GetCString(), + llvm::toString(std::move(error)).c_str()); section_data.Clear(); return 0; } @@ -3429,3 +3498,10 @@ ObjectFileELF::GetLoadableData(Target &target) { } return loadables; } + +lldb::WritableDataBufferSP +ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size, + uint64_t Offset) { + return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size, + Offset); +} diff --git a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index cf94ea730b4..7aa5620b14d 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -20,6 +20,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" @@ -40,7 +41,7 @@ static uint32_t g_initialize_count = 0; PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force, arch ? arch->GetArchitectureName() : "", arch ? arch->GetTriple().getTriple() : ""); @@ -71,25 +72,10 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { return PlatformSP(); } -ConstString PlatformOpenBSD::GetPluginNameStatic(bool is_host) { - if (is_host) { - static ConstString g_host_name(Platform::GetHostPlatformName()); - return g_host_name; - } else { - static ConstString g_remote_name("remote-openbsd"); - return g_remote_name; - } -} - -const char *PlatformOpenBSD::GetPluginDescriptionStatic(bool is_host) { +llvm::StringRef PlatformOpenBSD::GetPluginDescriptionStatic(bool is_host) { if (is_host) return "Local OpenBSD user platform plug-in."; - else - return "Remote OpenBSD user platform plug-in."; -} - -ConstString PlatformOpenBSD::GetPluginName() { - return GetPluginNameStatic(IsHost()); + return "Remote OpenBSD user platform plug-in."; } void PlatformOpenBSD::Initialize() { @@ -121,53 +107,22 @@ void PlatformOpenBSD::Terminate() { /// Default Constructor PlatformOpenBSD::PlatformOpenBSD(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { - ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSOpenBSD()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } - } +{ + if (is_host) { + m_supported_architectures.push_back(HostInfo::GetArchitecture()); } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to OpenBSD - triple.setOS(llvm::Triple::OpenBSD); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - case 2: - triple.setArchName("aarch64"); - break; - case 3: - triple.setArchName("arm"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = + CreateArchList({llvm::Triple::x86_64, llvm::Triple::x86, + llvm::Triple::aarch64, llvm::Triple::arm}, + llvm::Triple::OpenBSD); } - return false; +} + +std::vector +PlatformOpenBSD::GetSupportedArchitectures(const ArchSpec &process_host_arch) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch); + return m_supported_architectures; } void PlatformOpenBSD::GetStatus(Stream &strm) { @@ -199,121 +154,6 @@ bool PlatformOpenBSD::CanDebugProcess() { } } -// For local debugging, OpenBSD will override the debug logic to use llgs-launch -// rather than lldb-launch, llgs-attach. This differs from current lldb- -// launch, debugserver-attach approach on MacOSX. -lldb::ProcessSP -PlatformOpenBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be NULL, if NULL create a new - // target, else use existing one - Status &error) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOG(log, "target {0}", target); - - // If we're a remote host, use standard behavior from parent class. - if (!IsHost()) - return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error); - - // - // For local debugging, we'll insist on having ProcessGDBRemote create the - // process. - // - - ProcessSP process_sp; - - // Make sure we stop at the entry point - launch_info.GetFlags().Set(eLaunchFlagDebug); - - // We always launch the process we are going to debug in a separate process - // group, since then we can handle ^C interrupts ourselves w/o having to - // worry about the target getting them as well. - launch_info.SetLaunchInSeparateProcessGroup(true); - - // Ensure we have a target. - if (target == nullptr) { - LLDB_LOG(log, "creating new target"); - TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget(debugger, "", "", eLoadDependentsNo, - nullptr, new_target_sp); - if (error.Fail()) { - LLDB_LOG(log, "failed to create new target: {0}", error); - return process_sp; - } - - target = new_target_sp.get(); - if (!target) { - error.SetErrorString("CreateTarget() returned nullptr"); - LLDB_LOG(log, "error: {0}", error); - return process_sp; - } - } - - // Mark target as currently selected target. - //debugger.GetTargetList().SetSelectedTarget(target); - - // Now create the gdb-remote process. - LLDB_LOG(log, "having target create process with gdb-remote plugin"); - process_sp = target->CreateProcess( - launch_info.GetListener(), "gdb-remote", nullptr, true); - - if (!process_sp) { - error.SetErrorString("CreateProcess() failed for gdb-remote process"); - LLDB_LOG(log, "error: {0}", error); - return process_sp; - } - - LLDB_LOG(log, "successfully created process"); - // Adjust launch for a hijacker. - ListenerSP listener_sp; - if (!launch_info.GetHijackListener()) { - LLDB_LOG(log, "setting up hijacker"); - listener_sp = - Listener::MakeListener("lldb.PlatformOpenBSD.DebugProcess.hijack"); - launch_info.SetHijackListener(listener_sp); - process_sp->HijackProcessEvents(listener_sp); - } - - // Log file actions. - if (log) { - LLDB_LOG(log, "launching process with the following file actions:"); - StreamString stream; - size_t i = 0; - const FileAction *file_action; - while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) { - file_action->Dump(stream); - LLDB_LOG(log, "{0}", stream.GetData()); - stream.Clear(); - } - } - - // Do the launch. - error = process_sp->Launch(launch_info); - if (error.Success()) { - // Handle the hijacking of process events. - if (listener_sp) { - const StateType state = process_sp->WaitForProcessToStop( - llvm::None, NULL, false, listener_sp); - - LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state); - } - - // Hook up process PTY if we have one (which we should for local debugging - // with llgs). - int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); - if (pty_fd != PseudoTerminal::invalid_fd) { - process_sp->SetSTDIOFileDescriptor(pty_fd); - LLDB_LOG(log, "hooked up STDIO pty to process"); - } else - LLDB_LOG(log, "not using process STDIO pty"); - } else { - LLDB_LOG(log, "process launch failed: {0}", error); - // FIXME figure out appropriate cleanup here. Do we delete the target? Do - // we delete the process? Does our caller do that? - } - - return process_sp; -} - void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() { m_trap_handlers.push_back(ConstString("_sigtramp")); } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h index 03fe3d645cc..f9fed95af93 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h @@ -25,28 +25,28 @@ public: // lldb_private::PluginInterface functions static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); - static ConstString GetPluginNameStatic(bool is_host); - - static const char *GetPluginDescriptionStatic(bool is_host); + static llvm::StringRef GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-openbsd"; + } - ConstString GetPluginName() override; + static llvm::StringRef GetPluginDescriptionStatic(bool is_host); - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(IsHost()); + } // lldb_private::Platform functions - const char *GetDescription() override { + llvm::StringRef GetDescription() override { return GetPluginDescriptionStatic(IsHost()); } void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector + GetSupportedArchitectures(const ArchSpec &process_host_arch) override; bool CanDebugProcess() override; - lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, Status &error) override; - void CalculateTrapHandlerSymbolNames() override; MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, @@ -56,6 +56,7 @@ public: lldb_private::FileSpec LocateExecutable(const char *basename) override; + std::vector m_supported_architectures; }; } // namespace platform_openbsd diff --git a/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt index 733b6738413..ec35a428a88 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt @@ -21,3 +21,4 @@ add_subdirectory(Utility) add_subdirectory(elf-core) add_subdirectory(mach-core) add_subdirectory(minidump) +add_subdirectory(FreeBSDKernel) diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp deleted file mode 100644 index 0bd48933d4d..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp +++ /dev/null @@ -1,685 +0,0 @@ -//===-- IntelPTManager.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 -#include -#include - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/MathExtras.h" - -#include "IntelPTManager.h" -#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Host/linux/Support.h" -#include "lldb/Utility/StreamString.h" - -#include -#include - -using namespace lldb; -using namespace lldb_private; -using namespace process_linux; -using namespace llvm; - -const char *kOSEventIntelPTTypeFile = - "/sys/bus/event_source/devices/intel_pt/type"; - -const char *kPSBPeriodCapFile = - "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc"; - -const char *kPSBPeriodValidValuesFile = - "/sys/bus/event_source/devices/intel_pt/caps/psb_periods"; - -const char *kTSCBitOffsetFile = - "/sys/bus/event_source/devices/intel_pt/format/tsc"; - -const char *kPSBPeriodBitOffsetFile = - "/sys/bus/event_source/devices/intel_pt/format/psb_period"; - -enum IntelPTConfigFileType { - Hex = 0, - // 0 or 1 - ZeroOne, - Decimal, - // a bit index file always starts with the prefix config: following by an int, - // which represents the offset of the perf_event_attr.config value where to - // store a given configuration. - BitOffset -}; - -static Expected ReadIntelPTConfigFile(const char *file, - IntelPTConfigFileType type) { - ErrorOr> stream = - MemoryBuffer::getFileAsStream(file); - - if (!stream) - return createStringError(inconvertibleErrorCode(), - "Can't open the file '%s'", file); - - uint32_t value = 0; - StringRef text_buffer = stream.get()->getBuffer(); - - if (type == BitOffset) { - const char *prefix = "config:"; - if (!text_buffer.startswith(prefix)) - return createStringError(inconvertibleErrorCode(), - "The file '%s' contents doesn't start with '%s'", - file, prefix); - text_buffer = text_buffer.substr(strlen(prefix)); - } - - auto getRadix = [&]() { - switch (type) { - case Hex: - return 16; - case ZeroOne: - case Decimal: - case BitOffset: - return 10; - } - }; - - auto createError = [&](const char *expected_value_message) { - return createStringError( - inconvertibleErrorCode(), - "The file '%s' has an invalid value. It should be %s.", file, - expected_value_message); - }; - - if (text_buffer.trim().consumeInteger(getRadix(), value) || - (type == ZeroOne && value != 0 && value != 1)) { - switch (type) { - case Hex: - return createError("an unsigned hexadecimal int"); - case ZeroOne: - return createError("0 or 1"); - case Decimal: - case BitOffset: - return createError("an unsigned decimal int"); - } - } - return value; -} -/// Return the Linux perf event type for Intel PT. -static Expected GetOSEventType() { - return ReadIntelPTConfigFile(kOSEventIntelPTTypeFile, - IntelPTConfigFileType::Decimal); -} - -static Error CheckPsbPeriod(size_t psb_period) { - Expected cap = - ReadIntelPTConfigFile(kPSBPeriodCapFile, IntelPTConfigFileType::ZeroOne); - if (!cap) - return cap.takeError(); - if (*cap == 0) - return createStringError(inconvertibleErrorCode(), - "psb_period is unsupported in the system."); - - Expected valid_values = ReadIntelPTConfigFile( - kPSBPeriodValidValuesFile, IntelPTConfigFileType::Hex); - if (!valid_values) - return valid_values.takeError(); - - if (valid_values.get() & (1 << psb_period)) - return Error::success(); - - std::ostringstream error; - // 0 is always a valid value - error << "Invalid psb_period. Valid values are: 0"; - uint32_t mask = valid_values.get(); - while (mask) { - int index = __builtin_ctz(mask); - if (index > 0) - error << ", " << index; - // clear the lowest bit - mask &= mask - 1; - } - error << "."; - return createStringError(inconvertibleErrorCode(), error.str().c_str()); -} - -size_t IntelPTThreadTrace::GetTraceBufferSize() const { - return m_mmap_meta->aux_size; -} - -static Expected -GeneratePerfEventConfigValue(bool enable_tsc, Optional psb_period) { - uint64_t config = 0; - // tsc is always supported - if (enable_tsc) { - if (Expected offset = ReadIntelPTConfigFile( - kTSCBitOffsetFile, IntelPTConfigFileType::BitOffset)) - config |= 1 << *offset; - else - return offset.takeError(); - } - if (psb_period) { - if (Error error = CheckPsbPeriod(*psb_period)) - return std::move(error); - - if (Expected offset = ReadIntelPTConfigFile( - kPSBPeriodBitOffsetFile, IntelPTConfigFileType::BitOffset)) - config |= *psb_period << *offset; - else - return offset.takeError(); - } - return config; -} - -Error IntelPTThreadTrace::StartTrace(lldb::pid_t pid, lldb::tid_t tid, - uint64_t buffer_size, bool enable_tsc, - Optional psb_period) { -#ifndef PERF_ATTR_SIZE_VER5 - llvm_unreachable("Intel PT Linux perf event not supported"); -#else - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); - - m_tid = tid; - LLDB_LOG(log, "called thread id {0}", tid); - uint64_t page_size = getpagesize(); - - if (__builtin_popcount(buffer_size) != 1 || buffer_size < 4096) { - return createStringError( - inconvertibleErrorCode(), - "The trace buffer size must be a power of 2 greater than or equal to " - "4096 (2^12) bytes. It was %" PRIu64 ".", - buffer_size); - } - uint64_t numpages = static_cast( - llvm::PowerOf2Floor((buffer_size + page_size - 1) / page_size)); - numpages = std::max(1, numpages); - buffer_size = page_size * numpages; - - perf_event_attr attr; - memset(&attr, 0, sizeof(attr)); - attr.size = sizeof(attr); - attr.exclude_kernel = 1; - attr.sample_type = PERF_SAMPLE_TIME; - attr.sample_id_all = 1; - attr.exclude_hv = 1; - attr.exclude_idle = 1; - attr.mmap = 1; - - if (Expected config_value = - GeneratePerfEventConfigValue(enable_tsc, psb_period)) { - attr.config = *config_value; - LLDB_LOG(log, "intel pt config {0}", attr.config); - } else { - return config_value.takeError(); - } - - if (Expected intel_pt_type = GetOSEventType()) { - attr.type = *intel_pt_type; - LLDB_LOG(log, "intel pt type {0}", attr.type); - } else { - return intel_pt_type.takeError(); - } - - LLDB_LOG(log, "buffer size {0} ", buffer_size); - - errno = 0; - auto fd = - syscall(SYS_perf_event_open, &attr, static_cast<::tid_t>(tid), -1, -1, 0); - if (fd == -1) { - LLDB_LOG(log, "syscall error {0}", errno); - return createStringError(inconvertibleErrorCode(), - "perf event syscall failed"); - } - - m_fd = std::unique_ptr(new int(fd), file_close()); - - errno = 0; - auto base = - mmap(nullptr, (buffer_size + page_size), PROT_WRITE, MAP_SHARED, fd, 0); - - if (base == MAP_FAILED) { - LLDB_LOG(log, "mmap base error {0}", errno); - return createStringError(inconvertibleErrorCode(), - "Meta buffer allocation failed"); - } - - m_mmap_meta = std::unique_ptr( - reinterpret_cast(base), - munmap_delete(buffer_size + page_size)); - - m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size; - m_mmap_meta->aux_size = buffer_size; - - errno = 0; - auto mmap_aux = mmap(nullptr, buffer_size, PROT_READ, MAP_SHARED, fd, - static_cast(m_mmap_meta->aux_offset)); - - if (mmap_aux == MAP_FAILED) { - LLDB_LOG(log, "second mmap done {0}", errno); - return createStringError(inconvertibleErrorCode(), - "Trace buffer allocation failed"); - } - m_mmap_aux = std::unique_ptr( - reinterpret_cast(mmap_aux), munmap_delete(buffer_size)); - return Error::success(); -#endif -} - -llvm::MutableArrayRef IntelPTThreadTrace::GetDataBuffer() const { -#ifndef PERF_ATTR_SIZE_VER5 - llvm_unreachable("Intel PT Linux perf event not supported"); -#else - return MutableArrayRef( - (reinterpret_cast(m_mmap_meta.get()) + - m_mmap_meta->data_offset), - m_mmap_meta->data_size); -#endif -} - -llvm::MutableArrayRef IntelPTThreadTrace::GetAuxBuffer() const { -#ifndef PERF_ATTR_SIZE_VER5 - llvm_unreachable("Intel PT Linux perf event not supported"); -#else - return MutableArrayRef(m_mmap_aux.get(), m_mmap_meta->aux_size); -#endif -} - -Expected> IntelPTThreadTrace::GetCPUInfo() { - static llvm::Optional> cpu_info; - if (!cpu_info) { - auto buffer_or_error = getProcFile("cpuinfo"); - if (!buffer_or_error) - return Status(buffer_or_error.getError()).ToError(); - MemoryBuffer &buffer = **buffer_or_error; - cpu_info = std::vector( - reinterpret_cast(buffer.getBufferStart()), - reinterpret_cast(buffer.getBufferEnd())); - } - return *cpu_info; -} - -llvm::Expected -IntelPTThreadTrace::Create(lldb::pid_t pid, lldb::tid_t tid, size_t buffer_size, - bool enable_tsc, Optional psb_period) { - IntelPTThreadTraceUP thread_trace_up(new IntelPTThreadTrace()); - - if (llvm::Error err = thread_trace_up->StartTrace(pid, tid, buffer_size, - enable_tsc, psb_period)) - return std::move(err); - - return std::move(thread_trace_up); -} - -Expected> -IntelPTThreadTrace::GetIntelPTBuffer(size_t offset, size_t size) const { - std::vector data(size, 0); - MutableArrayRef buffer_ref(data); - Status error = ReadPerfTraceAux(buffer_ref, 0); - if (error.Fail()) - return error.ToError(); - return data; -} - -Status -IntelPTThreadTrace::ReadPerfTraceAux(llvm::MutableArrayRef &buffer, - size_t offset) const { -#ifndef PERF_ATTR_SIZE_VER5 - llvm_unreachable("perf event not supported"); -#else - // Disable the perf event to force a flush out of the CPU's internal buffer. - // Besides, we can guarantee that the CPU won't override any data as we are - // reading the buffer. - // - // The Intel documentation says: - // - // Packets are first buffered internally and then written out asynchronously. - // To collect packet output for postprocessing, a collector needs first to - // ensure that all packet data has been flushed from internal buffers. - // Software can ensure this by stopping packet generation by clearing - // IA32_RTIT_CTL.TraceEn (see “Disabling Packet Generation” in - // Section 35.2.7.2). - // - // This is achieved by the PERF_EVENT_IOC_DISABLE ioctl request, as mentioned - // in the man page of perf_event_open. - ioctl(*m_fd, PERF_EVENT_IOC_DISABLE); - - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); - Status error; - uint64_t head = m_mmap_meta->aux_head; - - LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head); - - /** - * When configured as ring buffer, the aux buffer keeps wrapping around - * the buffer and its not possible to detect how many times the buffer - * wrapped. Initially the buffer is filled with zeros,as shown below - * so in order to get complete buffer we first copy firstpartsize, followed - * by any left over part from beginning to aux_head - * - * aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size - * aux_head->||<- firstpartsize ->| - * - * */ - - ReadCyclicBuffer(buffer, GetAuxBuffer(), static_cast(head), offset); - LLDB_LOG(log, "ReadCyclic BUffer Done"); - - // Reenable tracing now we have read the buffer - ioctl(*m_fd, PERF_EVENT_IOC_ENABLE); - return error; -#endif -} - -Status -IntelPTThreadTrace::ReadPerfTraceData(llvm::MutableArrayRef &buffer, - size_t offset) const { -#ifndef PERF_ATTR_SIZE_VER5 - llvm_unreachable("perf event not supported"); -#else - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); - uint64_t bytes_remaining = buffer.size(); - Status error; - - uint64_t head = m_mmap_meta->data_head; - - /* - * The data buffer and aux buffer have different implementations - * with respect to their definition of head pointer. In the case - * of Aux data buffer the head always wraps around the aux buffer - * and we don't need to care about it, whereas the data_head keeps - * increasing and needs to be wrapped by modulus operator - */ - - LLDB_LOG(log, "bytes_remaining - {0}", bytes_remaining); - - auto data_buffer = GetDataBuffer(); - - if (head > data_buffer.size()) { - head = head % data_buffer.size(); - LLDB_LOG(log, "Data size -{0} Head - {1}", m_mmap_meta->data_size, head); - - ReadCyclicBuffer(buffer, data_buffer, static_cast(head), offset); - bytes_remaining -= buffer.size(); - } else { - LLDB_LOG(log, "Head - {0}", head); - if (offset >= head) { - LLDB_LOG(log, "Invalid Offset "); - error.SetErrorString("invalid offset"); - buffer = buffer.slice(buffer.size()); - return error; - } - - auto data = data_buffer.slice(offset, (head - offset)); - auto remaining = std::copy(data.begin(), data.end(), buffer.begin()); - bytes_remaining -= (remaining - buffer.begin()); - } - buffer = buffer.drop_back(bytes_remaining); - return error; -#endif -} - -void IntelPTThreadTrace::ReadCyclicBuffer(llvm::MutableArrayRef &dst, - llvm::MutableArrayRef src, - size_t src_cyc_index, size_t offset) { - - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); - - if (dst.empty() || src.empty()) { - dst = dst.drop_back(dst.size()); - return; - } - - if (dst.data() == nullptr || src.data() == nullptr) { - dst = dst.drop_back(dst.size()); - return; - } - - if (src_cyc_index > src.size()) { - dst = dst.drop_back(dst.size()); - return; - } - - if (offset >= src.size()) { - LLDB_LOG(log, "Too Big offset "); - dst = dst.drop_back(dst.size()); - return; - } - - llvm::SmallVector, 2> parts = { - src.slice(src_cyc_index), src.take_front(src_cyc_index)}; - - if (offset > parts[0].size()) { - parts[1] = parts[1].slice(offset - parts[0].size()); - parts[0] = parts[0].drop_back(parts[0].size()); - } else if (offset == parts[0].size()) { - parts[0] = parts[0].drop_back(parts[0].size()); - } else { - parts[0] = parts[0].slice(offset); - } - auto next = dst.begin(); - auto bytes_left = dst.size(); - for (auto part : parts) { - size_t chunk_size = std::min(part.size(), bytes_left); - next = std::copy_n(part.begin(), chunk_size, next); - bytes_left -= chunk_size; - } - dst = dst.drop_back(bytes_left); -} - -TraceThreadState IntelPTThreadTrace::GetState() const { - return {static_cast(m_tid), - {TraceBinaryData{"threadTraceBuffer", - static_cast(GetTraceBufferSize())}}}; -} - -/// IntelPTThreadTraceCollection - -bool IntelPTThreadTraceCollection::TracesThread(lldb::tid_t tid) const { - return m_thread_traces.count(tid); -} - -Error IntelPTThreadTraceCollection::TraceStop(lldb::tid_t tid) { - auto it = m_thread_traces.find(tid); - if (it == m_thread_traces.end()) - return createStringError(inconvertibleErrorCode(), - "Thread %" PRIu64 " not currently traced", tid); - m_total_buffer_size -= it->second->GetTraceBufferSize(); - m_thread_traces.erase(tid); - return Error::success(); -} - -Error IntelPTThreadTraceCollection::TraceStart( - lldb::tid_t tid, const TraceIntelPTStartRequest &request) { - if (TracesThread(tid)) - return createStringError(inconvertibleErrorCode(), - "Thread %" PRIu64 " already traced", tid); - - Expected trace_up = IntelPTThreadTrace::Create( - m_pid, tid, request.threadBufferSize, request.enableTsc, - request.psbPeriod.map([](int64_t period) { return (size_t)period; })); - if (!trace_up) - return trace_up.takeError(); - - m_total_buffer_size += (*trace_up)->GetTraceBufferSize(); - m_thread_traces.try_emplace(tid, std::move(*trace_up)); - return Error::success(); -} - -size_t IntelPTThreadTraceCollection::GetTotalBufferSize() const { - return m_total_buffer_size; -} - -std::vector -IntelPTThreadTraceCollection::GetThreadStates() const { - std::vector states; - for (const auto &it : m_thread_traces) - states.push_back(it.second->GetState()); - return states; -} - -Expected -IntelPTThreadTraceCollection::GetTracedThread(lldb::tid_t tid) const { - auto it = m_thread_traces.find(tid); - if (it == m_thread_traces.end()) - return createStringError(inconvertibleErrorCode(), - "Thread %" PRIu64 " not currently traced", tid); - return *it->second.get(); -} - -void IntelPTThreadTraceCollection::Clear() { - m_thread_traces.clear(); - m_total_buffer_size = 0; -} - -/// IntelPTProcessTrace - -bool IntelPTProcessTrace::TracesThread(lldb::tid_t tid) const { - return m_thread_traces.TracesThread(tid); -} - -Error IntelPTProcessTrace::TraceStop(lldb::tid_t tid) { - return m_thread_traces.TraceStop(tid); -} - -Error IntelPTProcessTrace::TraceStart(lldb::tid_t tid) { - if (m_thread_traces.GetTotalBufferSize() + m_tracing_params.threadBufferSize > - static_cast(*m_tracing_params.processBufferSizeLimit)) - return createStringError( - inconvertibleErrorCode(), - "Thread %" PRIu64 " can't be traced as the process trace size limit " - "has been reached. Consider retracing with a higher " - "limit.", - tid); - - return m_thread_traces.TraceStart(tid, m_tracing_params); -} - -const IntelPTThreadTraceCollection & -IntelPTProcessTrace::GetThreadTraces() const { - return m_thread_traces; -} - -/// IntelPTManager - -Error IntelPTManager::TraceStop(lldb::tid_t tid) { - if (IsProcessTracingEnabled() && m_process_trace->TracesThread(tid)) - return m_process_trace->TraceStop(tid); - return m_thread_traces.TraceStop(tid); -} - -Error IntelPTManager::TraceStop(const TraceStopRequest &request) { - if (request.IsProcessTracing()) { - Clear(); - return Error::success(); - } else { - Error error = Error::success(); - for (int64_t tid : *request.tids) - error = joinErrors(std::move(error), - TraceStop(static_cast(tid))); - return error; - } -} - -Error IntelPTManager::TraceStart( - const TraceIntelPTStartRequest &request, - const std::vector &process_threads) { - if (request.IsProcessTracing()) { - if (IsProcessTracingEnabled()) { - return createStringError( - inconvertibleErrorCode(), - "Process currently traced. Stop process tracing first"); - } - m_process_trace = IntelPTProcessTrace(m_pid, request); - - Error error = Error::success(); - for (lldb::tid_t tid : process_threads) - error = joinErrors(std::move(error), m_process_trace->TraceStart(tid)); - return error; - } else { - Error error = Error::success(); - for (int64_t tid : *request.tids) - error = joinErrors(std::move(error), - m_thread_traces.TraceStart(tid, request)); - return error; - } -} - -Error IntelPTManager::OnThreadCreated(lldb::tid_t tid) { - if (!IsProcessTracingEnabled()) - return Error::success(); - return m_process_trace->TraceStart(tid); -} - -Error IntelPTManager::OnThreadDestroyed(lldb::tid_t tid) { - if (IsProcessTracingEnabled() && m_process_trace->TracesThread(tid)) - return m_process_trace->TraceStop(tid); - else if (m_thread_traces.TracesThread(tid)) - return m_thread_traces.TraceStop(tid); - return Error::success(); -} - -Expected IntelPTManager::GetState() const { - Expected> cpu_info = IntelPTThreadTrace::GetCPUInfo(); - if (!cpu_info) - return cpu_info.takeError(); - - TraceGetStateResponse state; - state.processBinaryData.push_back( - {"cpuInfo", static_cast(cpu_info->size())}); - - std::vector thread_states = - m_thread_traces.GetThreadStates(); - state.tracedThreads.insert(state.tracedThreads.end(), thread_states.begin(), - thread_states.end()); - - if (IsProcessTracingEnabled()) { - thread_states = m_process_trace->GetThreadTraces().GetThreadStates(); - state.tracedThreads.insert(state.tracedThreads.end(), thread_states.begin(), - thread_states.end()); - } - return toJSON(state); -} - -Expected -IntelPTManager::GetTracedThread(lldb::tid_t tid) const { - if (IsProcessTracingEnabled() && m_process_trace->TracesThread(tid)) - return m_process_trace->GetThreadTraces().GetTracedThread(tid); - return m_thread_traces.GetTracedThread(tid); -} - -Expected> -IntelPTManager::GetBinaryData(const TraceGetBinaryDataRequest &request) const { - if (request.kind == "threadTraceBuffer") { - if (Expected trace = - GetTracedThread(*request.tid)) - return trace->GetIntelPTBuffer(request.offset, request.size); - else - return trace.takeError(); - } else if (request.kind == "cpuInfo") { - return IntelPTThreadTrace::GetCPUInfo(); - } - return createStringError(inconvertibleErrorCode(), - "Unsuported trace binary data kind: %s", - request.kind.c_str()); -} - -void IntelPTManager::ClearProcessTracing() { m_process_trace = None; } - -bool IntelPTManager::IsSupported() { - Expected intel_pt_type = GetOSEventType(); - if (!intel_pt_type) { - llvm::consumeError(intel_pt_type.takeError()); - return false; - } - return true; -} - -bool IntelPTManager::IsProcessTracingEnabled() const { - return (bool)m_process_trace; -} - -void IntelPTManager::Clear() { - ClearProcessTracing(); - m_thread_traces.Clear(); -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTManager.h b/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTManager.h deleted file mode 100644 index 38566a22107..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTManager.h +++ /dev/null @@ -1,263 +0,0 @@ -//===-- IntelPTManager.h -------------------------------------- -*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_IntelPTManager_H_ -#define liblldb_IntelPTManager_H_ - -#include "lldb/Utility/Status.h" -#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" -#include "lldb/lldb-types.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" - -#include -#include -#include - -namespace lldb_private { - -namespace process_linux { - -/// This class keeps track of one tracing instance of -/// Intel(R) Processor Trace on Linux OS at thread level. -/// -/// The kernel interface for us is the perf_event_open. -class IntelPTThreadTrace; -typedef std::unique_ptr IntelPTThreadTraceUP; - -class IntelPTThreadTrace { - - class munmap_delete { - size_t m_length; - - public: - munmap_delete(size_t length) : m_length(length) {} - void operator()(void *ptr) { - if (m_length) - munmap(ptr, m_length); - } - }; - - class file_close { - - public: - file_close() = default; - void operator()(int *ptr) { - if (ptr == nullptr) - return; - if (*ptr == -1) - return; - close(*ptr); - std::default_delete()(ptr); - } - }; - - std::unique_ptr m_mmap_meta; - std::unique_ptr m_mmap_aux; - std::unique_ptr m_fd; - lldb::tid_t m_tid; - - /// Start tracing a thread - /// - /// \param[in] pid - /// The pid of the process whose thread will be traced. - /// - /// \param[in] buffer_size - /// Size of the thread buffer in bytes. - /// - /// \param[in] enable_tsc - /// Whether to use enable TSC timestamps or not. - /// More information in TraceIntelPT::GetStartConfigurationHelp(). - /// - /// \param[in] psb_period - /// This value defines the period in which PSB packets will be generated. - /// More information in TraceIntelPT::GetStartConfigurationHelp(). - /// - /// \return - /// \a llvm::Error::success if tracing was successful, or an - /// \a llvm::Error otherwise. - llvm::Error StartTrace(lldb::pid_t pid, lldb::tid_t tid, uint64_t buffer_size, - bool enable_tsc, llvm::Optional psb_period); - - llvm::MutableArrayRef GetAuxBuffer() const; - llvm::MutableArrayRef GetDataBuffer() const; - - IntelPTThreadTrace() - : m_mmap_meta(nullptr, munmap_delete(0)), - m_mmap_aux(nullptr, munmap_delete(0)), m_fd(nullptr, file_close()) {} - -public: - /// Get the content of /proc/cpuinfo that can be later used to decode traces. - static llvm::Expected> GetCPUInfo(); - - /// Start tracing a thread. - /// - /// See \a StartTrace. - /// - /// \return - /// A \a IntelPTThreadTrace instance if tracing was successful, or - /// an \a llvm::Error otherwise. - static llvm::Expected - Create(lldb::pid_t pid, lldb::tid_t tid, size_t buffer_size, bool enable_tsc, - llvm::Optional psb_period); - - /// Read the trace buffer of the currently traced thread. - /// - /// \param[in] offset - /// Offset of the data to read. - /// - /// \param[in] size - /// Number of bytes to read. - /// - /// \return - /// A vector with the requested binary data. The vector will have the - /// size of the requested \a size. Non-available positions will be - /// filled with zeroes. - llvm::Expected> GetIntelPTBuffer(size_t offset, - size_t size) const; - - Status ReadPerfTraceAux(llvm::MutableArrayRef &buffer, - size_t offset = 0) const; - - Status ReadPerfTraceData(llvm::MutableArrayRef &buffer, - size_t offset = 0) const; - - /// Get the size in bytes of the aux section of the thread or process traced - /// by this object. - size_t GetTraceBufferSize() const; - - /// Read data from a cyclic buffer - /// - /// \param[in] [out] buf - /// Destination buffer, the buffer will be truncated to written size. - /// - /// \param[in] src - /// Source buffer which must be a cyclic buffer. - /// - /// \param[in] src_cyc_index - /// The index pointer (start of the valid data in the cyclic - /// buffer). - /// - /// \param[in] offset - /// The offset to begin reading the data in the cyclic buffer. - static void ReadCyclicBuffer(llvm::MutableArrayRef &dst, - llvm::MutableArrayRef src, - size_t src_cyc_index, size_t offset); - - /// Return the thread-specific part of the jLLDBTraceGetState packet. - TraceThreadState GetState() const; -}; - -/// Manages a list of thread traces. -class IntelPTThreadTraceCollection { -public: - IntelPTThreadTraceCollection(lldb::pid_t pid) : m_pid(pid) {} - - /// Dispose of all traces - void Clear(); - - bool TracesThread(lldb::tid_t tid) const; - - size_t GetTotalBufferSize() const; - - std::vector GetThreadStates() const; - - llvm::Expected - GetTracedThread(lldb::tid_t tid) const; - - llvm::Error TraceStart(lldb::tid_t tid, - const TraceIntelPTStartRequest &request); - - llvm::Error TraceStop(lldb::tid_t tid); - -private: - lldb::pid_t m_pid; - llvm::DenseMap m_thread_traces; - /// Total actual thread buffer size in bytes - size_t m_total_buffer_size = 0; -}; - -/// Manages a "process trace" instance. -class IntelPTProcessTrace { -public: - IntelPTProcessTrace(lldb::pid_t pid, const TraceIntelPTStartRequest &request) - : m_thread_traces(pid), m_tracing_params(request) {} - - bool TracesThread(lldb::tid_t tid) const; - - const IntelPTThreadTraceCollection &GetThreadTraces() const; - - llvm::Error TraceStart(lldb::tid_t tid); - - llvm::Error TraceStop(lldb::tid_t tid); - -private: - IntelPTThreadTraceCollection m_thread_traces; - /// Params used to trace threads when the user started "process tracing". - TraceIntelPTStartRequest m_tracing_params; -}; - -/// Main class that manages intel-pt process and thread tracing. -class IntelPTManager { -public: - IntelPTManager(lldb::pid_t pid) : m_pid(pid), m_thread_traces(pid) {} - - static bool IsSupported(); - - /// If "process tracing" is enabled, then trace the given thread. - llvm::Error OnThreadCreated(lldb::tid_t tid); - - /// Stops tracing a tracing upon a destroy event. - llvm::Error OnThreadDestroyed(lldb::tid_t tid); - - /// Implementation of the jLLDBTraceStop packet - llvm::Error TraceStop(const TraceStopRequest &request); - - /// Implementation of the jLLDBTraceStart packet - /// - /// \param[in] process_threads - /// A list of all threads owned by the process. - llvm::Error TraceStart(const TraceIntelPTStartRequest &request, - const std::vector &process_threads); - - /// Implementation of the jLLDBTraceGetState packet - llvm::Expected GetState() const; - - /// Implementation of the jLLDBTraceGetBinaryData packet - llvm::Expected> - GetBinaryData(const TraceGetBinaryDataRequest &request) const; - - /// Dispose of all traces - void Clear(); - -private: - llvm::Error TraceStop(lldb::tid_t tid); - - /// Start tracing a specific thread. - llvm::Error TraceStart(lldb::tid_t tid, - const TraceIntelPTStartRequest &request); - - llvm::Expected - GetTracedThread(lldb::tid_t tid) const; - - bool IsProcessTracingEnabled() const; - - void ClearProcessTracing(); - - lldb::pid_t m_pid; - /// Threads traced due to "thread tracing" - IntelPTThreadTraceCollection m_thread_traces; - /// Threads traced due to "process tracing". Only one active "process tracing" - /// instance is assumed for a single process. - llvm::Optional m_process_trace; -}; - -} // namespace process_linux -} // namespace lldb_private - -#endif // liblldb_IntelPTManager_H_ diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp index 0cae26760f2..41cfa52a707 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp @@ -66,7 +66,7 @@ llvm::Expected> NativeProcessOpenBSD::Factory::Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, MainLoop &mainloop) const { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Process); Status status; ::pid_t pid = ProcessLauncherPosixFork() @@ -121,7 +121,7 @@ NativeProcessOpenBSD::Factory::Attach( lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop) const { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Process); LLDB_LOG(log, "pid = {0:x}", pid); // Retrieve the architecture for the running process. @@ -179,7 +179,7 @@ void NativeProcessOpenBSD::MonitorCallback(lldb::pid_t pid, int signal) { } void NativeProcessOpenBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Process); LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid); @@ -210,7 +210,7 @@ void NativeProcessOpenBSD::MonitorSignal(lldb::pid_t pid, int signal) { Status NativeProcessOpenBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data, int *result) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); + Log *log = GetLog(POSIXLog::Process); Status error; int ret; @@ -232,7 +232,7 @@ Status NativeProcessOpenBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, } Status NativeProcessOpenBSD::Resume(const ResumeActionList &resume_actions) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Process); LLDB_LOG(log, "pid {0}", GetID()); const auto &thread = m_threads[0]; @@ -321,7 +321,7 @@ Status NativeProcessOpenBSD::Signal(int signo) { } Status NativeProcessOpenBSD::Kill() { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Process); LLDB_LOG(log, "pid {0}", GetID()); Status error; @@ -401,7 +401,7 @@ Status NativeProcessOpenBSD::GetFileLoadAddress(const llvm::StringRef &file_name } void NativeProcessOpenBSD::SigchldHandler() { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Process); // Process all pending waitpid notifications. int status; ::pid_t wait_pid = @@ -447,7 +447,7 @@ bool NativeProcessOpenBSD::HasThreadNoLock(lldb::tid_t thread_id) { NativeThreadOpenBSD &NativeProcessOpenBSD::AddThread(lldb::tid_t thread_id) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); + Log *log = GetLog(POSIXLog::Thread); LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id); assert(!HasThreadNoLock(thread_id) && @@ -491,7 +491,7 @@ Status NativeProcessOpenBSD::ReadMemory(lldb::addr_t addr, void *buf, unsigned char *dst = static_cast(buf); struct ptrace_io_desc io; - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); + Log *log = GetLog(POSIXLog::Memory); LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); bytes_read = 0; @@ -519,7 +519,7 @@ Status NativeProcessOpenBSD::WriteMemory(lldb::addr_t addr, const void *buf, Status error; struct ptrace_io_desc io; - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); + Log *log = GetLog(POSIXLog::Memory); LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); bytes_written = 0; diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp index 7fe177e49e9..eeaa868f927 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp @@ -18,12 +18,12 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/APInt.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" +#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" // clang-format off #include @@ -102,7 +102,7 @@ Status NativeRegisterContextOpenBSD_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) { Status error; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Registers); if (!reg_info) { error.SetErrorString("reg_info NULL"); @@ -142,7 +142,7 @@ NativeRegisterContextOpenBSD_arm64::ReadRegister(const RegisterInfo *reg_info, offset = reg_info->byte_offset - GetRegisterInfo().GetPAuthOffset(); reg_value = (uint64_t)m_pacmask[offset > 0]; if (reg_value.GetByteSize() > reg_info->byte_size) { - reg_value.SetType(reg_info); + reg_value.SetType(*reg_info); } return error; @@ -241,7 +241,7 @@ NativeRegisterContextOpenBSD_arm64::ReadRegister(const RegisterInfo *reg_info, } if (reg_value.GetByteSize() > reg_info->byte_size) { - reg_value.SetType(reg_info); + reg_value.SetType(*reg_info); } return error; @@ -251,7 +251,7 @@ Status NativeRegisterContextOpenBSD_arm64::WriteRegister( const RegisterInfo *reg_info, const RegisterValue ®_value) { Status error; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(POSIXLog::Registers); if (!reg_info) { error.SetErrorString("reg_info NULL"); @@ -385,7 +385,7 @@ Status NativeRegisterContextOpenBSD_arm64::WriteRegister( } Status NativeRegisterContextOpenBSD_arm64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); @@ -440,7 +440,7 @@ Status NativeRegisterContextOpenBSD_arm64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextOpenBSD_arm64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h index 106d1b610b7..bb59797fbfb 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h @@ -56,7 +56,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp index 1c9d7aa7609..b05dde6001a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp @@ -598,7 +598,7 @@ Status NativeRegisterContextOpenBSD_x86_64::WriteRegister( } Status NativeRegisterContextOpenBSD_x86_64::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { + lldb::WritableDataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); @@ -651,7 +651,7 @@ Status NativeRegisterContextOpenBSD_x86_64::WriteAllRegisterValues( return error; } - uint8_t *src = data_sp->GetBytes(); + const uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextOpenBSD_x86_64::%s " "DataBuffer::GetBytes() returned a null " diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h index 44497d758c0..60e13da6347 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h @@ -42,7 +42,7 @@ public: Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp index 90f14244aa0..766f9a014b1 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp @@ -35,13 +35,13 @@ NativeThreadOpenBSD::NativeThreadOpenBSD(NativeProcessOpenBSD &process, void NativeThreadOpenBSD::SetStoppedBySignal(uint32_t signo, const siginfo_t *info) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); + Log *log = GetLog(POSIXLog::Thread); LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo); SetStopped(); m_stop_info.reason = StopReason::eStopReasonSignal; - m_stop_info.details.signal.signo = signo; + m_stop_info.signo = signo; m_stop_description.clear(); if (info) { @@ -60,19 +60,19 @@ void NativeThreadOpenBSD::SetStoppedBySignal(uint32_t signo, void NativeThreadOpenBSD::SetStoppedByBreakpoint() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonBreakpoint; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadOpenBSD::SetStoppedByTrace() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonTrace; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadOpenBSD::SetStoppedByExec() { SetStopped(); m_stop_info.reason = StopReason::eStopReasonExec; - m_stop_info.details.signal.signo = SIGTRAP; + m_stop_info.signo = SIGTRAP; } void NativeThreadOpenBSD::SetStopped() { @@ -97,7 +97,7 @@ lldb::StateType NativeThreadOpenBSD::GetState() { return m_state; } bool NativeThreadOpenBSD::GetStopReason(ThreadStopInfo &stop_info, std::string &description) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); + Log *log = GetLog(POSIXLog::Thread); description.clear(); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt index 2d4b42fa4df..5bafac2f49f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -1,6 +1,5 @@ add_lldb_library(lldbPluginProcessUtility AuxVector.cpp - DynamicRegisterInfo.cpp FreeBSDSignals.cpp GDBRemoteSignals.cpp HistoryThread.cpp @@ -40,9 +39,11 @@ add_lldb_library(lldbPluginProcessUtility RegisterContextOpenBSD_x86_64.cpp RegisterContextPOSIX_arm.cpp RegisterContextPOSIX_arm64.cpp + RegisterContextPOSIX_loongarch64.cpp RegisterContextPOSIX_mips64.cpp RegisterContextPOSIX_powerpc.cpp RegisterContextPOSIX_ppc64le.cpp + RegisterContextPOSIX_riscv64.cpp RegisterContextPOSIX_s390x.cpp RegisterContextPOSIX_x86.cpp RegisterContextThreadMemory.cpp @@ -50,7 +51,9 @@ add_lldb_library(lldbPluginProcessUtility RegisterContextWindows_x86_64.cpp RegisterInfoPOSIX_arm.cpp RegisterInfoPOSIX_arm64.cpp + RegisterInfoPOSIX_loongarch64.cpp RegisterInfoPOSIX_ppc64le.cpp + RegisterInfoPOSIX_riscv64.cpp StopInfoMachException.cpp ThreadMemory.cpp @@ -65,4 +68,5 @@ add_lldb_library(lldbPluginProcessUtility lldbUtility LINK_COMPONENTS Support + TargetParser ) diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp deleted file mode 100644 index a85d7bd6f52..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ /dev/null @@ -1,811 +0,0 @@ -//===-- DynamicRegisterInfo.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 "DynamicRegisterInfo.h" - -#include "lldb/Core/StreamFile.h" -#include "lldb/DataFormatters/FormatManager.h" -#include "lldb/Host/StringConvert.h" -#include "lldb/Interpreter/OptionArgParser.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/RegularExpression.h" -#include "lldb/Utility/StringExtractor.h" -#include "lldb/Utility/StructuredData.h" - -using namespace lldb; -using namespace lldb_private; - -DynamicRegisterInfo::DynamicRegisterInfo( - const lldb_private::StructuredData::Dictionary &dict, - const lldb_private::ArchSpec &arch) { - SetRegisterInfo(dict, arch); -} - -DynamicRegisterInfo::DynamicRegisterInfo(DynamicRegisterInfo &&info) { - MoveFrom(std::move(info)); -} - -DynamicRegisterInfo & -DynamicRegisterInfo::operator=(DynamicRegisterInfo &&info) { - MoveFrom(std::move(info)); - return *this; -} - -void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) { - m_regs = std::move(info.m_regs); - m_sets = std::move(info.m_sets); - m_set_reg_nums = std::move(info.m_set_reg_nums); - m_set_names = std::move(info.m_set_names); - m_value_regs_map = std::move(info.m_value_regs_map); - m_invalidate_regs_map = std::move(info.m_invalidate_regs_map); - m_dynamic_reg_size_map = std::move(info.m_dynamic_reg_size_map); - - m_reg_data_byte_size = info.m_reg_data_byte_size; - m_finalized = info.m_finalized; - - if (m_finalized) { - const size_t num_sets = m_sets.size(); - for (size_t set = 0; set < num_sets; ++set) - m_sets[set].registers = m_set_reg_nums[set].data(); - } - - info.Clear(); -} - -size_t -DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, - const ArchSpec &arch) { - assert(!m_finalized); - StructuredData::Array *sets = nullptr; - if (dict.GetValueForKeyAsArray("sets", sets)) { - const uint32_t num_sets = sets->GetSize(); - for (uint32_t i = 0; i < num_sets; ++i) { - ConstString set_name; - if (sets->GetItemAtIndexAsString(i, set_name) && !set_name.IsEmpty()) { - m_sets.push_back({set_name.AsCString(), nullptr, 0, nullptr}); - } else { - Clear(); - printf("error: register sets must have valid names\n"); - return 0; - } - } - m_set_reg_nums.resize(m_sets.size()); - } - - StructuredData::Array *regs = nullptr; - if (!dict.GetValueForKeyAsArray("registers", regs)) - return 0; - - const uint32_t num_regs = regs->GetSize(); - // typedef std::map > - // InvalidateNameMap; - // InvalidateNameMap invalidate_map; - for (uint32_t i = 0; i < num_regs; ++i) { - StructuredData::Dictionary *reg_info_dict = nullptr; - if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) { - Clear(); - printf("error: items in the 'registers' array must be dictionaries\n"); - regs->DumpToStdout(); - return 0; - } - - // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, - // 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2, - // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, - RegisterInfo reg_info; - std::vector value_regs; - std::vector invalidate_regs; - memset(®_info, 0, sizeof(reg_info)); - - ConstString name_val; - ConstString alt_name_val; - if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) { - Clear(); - printf("error: registers must have valid names and offsets\n"); - reg_info_dict->DumpToStdout(); - return 0; - } - reg_info.name = name_val.GetCString(); - reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr); - reg_info.alt_name = alt_name_val.GetCString(); - - reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, - UINT32_MAX); - - const ByteOrder byte_order = arch.GetByteOrder(); - - if (reg_info.byte_offset == UINT32_MAX) { - // No offset for this register, see if the register has a value - // expression which indicates this register is part of another register. - // Value expressions are things like "rax[31:0]" which state that the - // current register's value is in a concrete register "rax" in bits 31:0. - // If there is a value expression we can calculate the offset - bool success = false; - llvm::StringRef slice_str; - if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) { - // Slices use the following format: - // REGNAME[MSBIT:LSBIT] - // REGNAME - name of the register to grab a slice of - // MSBIT - the most significant bit at which the current register value - // starts at - // LSBIT - the least significant bit at which the current register value - // ends at - static RegularExpression g_bitfield_regex( - llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]")); - llvm::SmallVector matches; - if (g_bitfield_regex.Execute(slice_str, &matches)) { - std::string reg_name_str = matches[1].str(); - std::string msbit_str = matches[2].str(); - std::string lsbit_str = matches[3].str(); - const uint32_t msbit = - StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); - const uint32_t lsbit = - StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); - if (msbit != UINT32_MAX && lsbit != UINT32_MAX) { - if (msbit > lsbit) { - const uint32_t msbyte = msbit / 8; - const uint32_t lsbyte = lsbit / 8; - - const RegisterInfo *containing_reg_info = - GetRegisterInfo(reg_name_str); - if (containing_reg_info) { - const uint32_t max_bit = containing_reg_info->byte_size * 8; - if (msbit < max_bit && lsbit < max_bit) { - m_invalidate_regs_map[containing_reg_info - ->kinds[eRegisterKindLLDB]] - .push_back(i); - m_value_regs_map[i].push_back( - containing_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[i].push_back( - containing_reg_info->kinds[eRegisterKindLLDB]); - - if (byte_order == eByteOrderLittle) { - success = true; - reg_info.byte_offset = - containing_reg_info->byte_offset + lsbyte; - } else if (byte_order == eByteOrderBig) { - success = true; - reg_info.byte_offset = - containing_reg_info->byte_offset + msbyte; - } else { - llvm_unreachable("Invalid byte order"); - } - } else { - if (msbit > max_bit) - printf("error: msbit (%u) must be less than the bitsize " - "of the register (%u)\n", - msbit, max_bit); - else - printf("error: lsbit (%u) must be less than the bitsize " - "of the register (%u)\n", - lsbit, max_bit); - } - } else { - printf("error: invalid concrete register \"%s\"\n", - reg_name_str.c_str()); - } - } else { - printf("error: msbit (%u) must be greater than lsbit (%u)\n", - msbit, lsbit); - } - } else { - printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, - lsbit); - } - } else { - // TODO: print error invalid slice string that doesn't follow the - // format - printf("error: failed to match against register bitfield regex\n"); - } - } else { - StructuredData::Array *composite_reg_list = nullptr; - if (reg_info_dict->GetValueForKeyAsArray("composite", - composite_reg_list)) { - const size_t num_composite_regs = composite_reg_list->GetSize(); - if (num_composite_regs > 0) { - uint32_t composite_offset = UINT32_MAX; - for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; - ++composite_idx) { - ConstString composite_reg_name; - if (composite_reg_list->GetItemAtIndexAsString( - composite_idx, composite_reg_name, nullptr)) { - const RegisterInfo *composite_reg_info = - GetRegisterInfo(composite_reg_name.GetStringRef()); - if (composite_reg_info) { - composite_offset = std::min(composite_offset, - composite_reg_info->byte_offset); - m_value_regs_map[i].push_back( - composite_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[composite_reg_info - ->kinds[eRegisterKindLLDB]] - .push_back(i); - m_invalidate_regs_map[i].push_back( - composite_reg_info->kinds[eRegisterKindLLDB]); - } else { - // TODO: print error invalid slice string that doesn't follow - // the format - printf("error: failed to find composite register by name: " - "\"%s\"\n", - composite_reg_name.GetCString()); - } - } else { - printf( - "error: 'composite' list value wasn't a python string\n"); - } - } - if (composite_offset != UINT32_MAX) { - reg_info.byte_offset = composite_offset; - success = m_value_regs_map.find(i) != m_value_regs_map.end(); - } else { - printf("error: 'composite' registers must specify at least one " - "real register\n"); - } - } else { - printf("error: 'composite' list was empty\n"); - } - } - } - - if (!success) { - Clear(); - reg_info_dict->DumpToStdout(); - return 0; - } - } - - int64_t bitsize = 0; - if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) { - Clear(); - printf("error: invalid or missing 'bitsize' key/value pair in register " - "dictionary\n"); - reg_info_dict->DumpToStdout(); - return 0; - } - - reg_info.byte_size = bitsize / 8; - - llvm::StringRef dwarf_opcode_string; - if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes", - dwarf_opcode_string)) { - reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.size() / 2; - assert(reg_info.dynamic_size_dwarf_len > 0); - - std::vector dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len); - uint32_t j; - StringExtractor opcode_extractor(dwarf_opcode_string); - uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); - UNUSED_IF_ASSERT_DISABLED(ret_val); - assert(ret_val == reg_info.dynamic_size_dwarf_len); - - for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j) - m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]); - - reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data(); - } - - llvm::StringRef format_str; - if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) { - if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format, - nullptr) - .Fail()) { - Clear(); - printf("error: invalid 'format' value in register dictionary\n"); - reg_info_dict->DumpToStdout(); - return 0; - } - } else { - reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, - eFormatHex); - } - - llvm::StringRef encoding_str; - if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str)) - reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint); - else - reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, - eEncodingUint); - - size_t set = 0; - if (!reg_info_dict->GetValueForKeyAsInteger("set", set, -1) || - set >= m_sets.size()) { - Clear(); - printf("error: invalid 'set' value in register dictionary, valid values " - "are 0 - %i\n", - (int)set); - reg_info_dict->DumpToStdout(); - return 0; - } - - // Fill in the register numbers - reg_info.kinds[lldb::eRegisterKindLLDB] = i; - reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i; - uint32_t eh_frame_regno = LLDB_INVALID_REGNUM; - reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno, - LLDB_INVALID_REGNUM); - if (eh_frame_regno == LLDB_INVALID_REGNUM) - reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno, - LLDB_INVALID_REGNUM); - reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno; - reg_info_dict->GetValueForKeyAsInteger( - "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM); - llvm::StringRef generic_str; - if (reg_info_dict->GetValueForKeyAsString("generic", generic_str)) - reg_info.kinds[lldb::eRegisterKindGeneric] = - Args::StringToGenericRegister(generic_str); - else - reg_info_dict->GetValueForKeyAsInteger( - "generic", reg_info.kinds[lldb::eRegisterKindGeneric], - LLDB_INVALID_REGNUM); - - // Check if this register invalidates any other register values when it is - // modified - StructuredData::Array *invalidate_reg_list = nullptr; - if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", - invalidate_reg_list)) { - const size_t num_regs = invalidate_reg_list->GetSize(); - if (num_regs > 0) { - for (uint32_t idx = 0; idx < num_regs; ++idx) { - ConstString invalidate_reg_name; - uint64_t invalidate_reg_num; - if (invalidate_reg_list->GetItemAtIndexAsString( - idx, invalidate_reg_name)) { - const RegisterInfo *invalidate_reg_info = - GetRegisterInfo(invalidate_reg_name.GetStringRef()); - if (invalidate_reg_info) { - m_invalidate_regs_map[i].push_back( - invalidate_reg_info->kinds[eRegisterKindLLDB]); - } else { - // TODO: print error invalid slice string that doesn't follow the - // format - printf("error: failed to find a 'invalidate-regs' register for " - "\"%s\" while parsing register \"%s\"\n", - invalidate_reg_name.GetCString(), reg_info.name); - } - } else if (invalidate_reg_list->GetItemAtIndexAsInteger( - idx, invalidate_reg_num)) { - if (invalidate_reg_num != UINT64_MAX) - m_invalidate_regs_map[i].push_back(invalidate_reg_num); - else - printf("error: 'invalidate-regs' list value wasn't a valid " - "integer\n"); - } else { - printf("error: 'invalidate-regs' list value wasn't a python string " - "or integer\n"); - } - } - } else { - printf("error: 'invalidate-regs' contained an empty list\n"); - } - } - - // Calculate the register offset - const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; - - m_regs.push_back(reg_info); - m_set_reg_nums[set].push_back(i); - } - Finalize(arch); - return m_regs.size(); -} - -void DynamicRegisterInfo::AddRegister(RegisterInfo ®_info, - ConstString ®_name, - ConstString ®_alt_name, - ConstString &set_name) { - assert(!m_finalized); - const uint32_t reg_num = m_regs.size(); - reg_info.name = reg_name.AsCString(); - assert(reg_info.name); - reg_info.alt_name = reg_alt_name.AsCString(nullptr); - uint32_t i; - if (reg_info.value_regs) { - for (i = 0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) - m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); - } - if (reg_info.invalidate_regs) { - for (i = 0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) - m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); - } - if (reg_info.dynamic_size_dwarf_expr_bytes) { - for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i) - m_dynamic_reg_size_map[reg_num].push_back( - reg_info.dynamic_size_dwarf_expr_bytes[i]); - - reg_info.dynamic_size_dwarf_expr_bytes = - m_dynamic_reg_size_map[reg_num].data(); - } - - m_regs.push_back(reg_info); - uint32_t set = GetRegisterSetIndexByName(set_name, true); - assert(set < m_sets.size()); - assert(set < m_set_reg_nums.size()); - assert(set < m_set_names.size()); - m_set_reg_nums[set].push_back(reg_num); -} - -void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { - if (m_finalized) - return; - - m_finalized = true; - const size_t num_sets = m_sets.size(); - for (size_t set = 0; set < num_sets; ++set) { - assert(m_sets.size() == m_set_reg_nums.size()); - m_sets[set].num_registers = m_set_reg_nums[set].size(); - m_sets[set].registers = m_set_reg_nums[set].data(); - } - - // sort and unique all value registers and make sure each is terminated with - // LLDB_INVALID_REGNUM - - for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), - end = m_value_regs_map.end(); - pos != end; ++pos) { - if (pos->second.size() > 1) { - llvm::sort(pos->second.begin(), pos->second.end()); - reg_num_collection::iterator unique_end = - std::unique(pos->second.begin(), pos->second.end()); - if (unique_end != pos->second.end()) - pos->second.erase(unique_end, pos->second.end()); - } - assert(!pos->second.empty()); - if (pos->second.back() != LLDB_INVALID_REGNUM) - pos->second.push_back(LLDB_INVALID_REGNUM); - } - - // Now update all value_regs with each register info as needed - const size_t num_regs = m_regs.size(); - for (size_t i = 0; i < num_regs; ++i) { - if (m_value_regs_map.find(i) != m_value_regs_map.end()) - m_regs[i].value_regs = m_value_regs_map[i].data(); - else - m_regs[i].value_regs = nullptr; - } - - // Expand all invalidation dependencies - for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), - end = m_invalidate_regs_map.end(); - pos != end; ++pos) { - const uint32_t reg_num = pos->first; - - if (m_regs[reg_num].value_regs) { - reg_num_collection extra_invalid_regs; - for (const uint32_t invalidate_reg_num : pos->second) { - reg_to_regs_map::iterator invalidate_pos = - m_invalidate_regs_map.find(invalidate_reg_num); - if (invalidate_pos != m_invalidate_regs_map.end()) { - for (const uint32_t concrete_invalidate_reg_num : - invalidate_pos->second) { - if (concrete_invalidate_reg_num != reg_num) - extra_invalid_regs.push_back(concrete_invalidate_reg_num); - } - } - } - pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), - extra_invalid_regs.end()); - } - } - - // sort and unique all invalidate registers and make sure each is terminated - // with LLDB_INVALID_REGNUM - for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), - end = m_invalidate_regs_map.end(); - pos != end; ++pos) { - if (pos->second.size() > 1) { - llvm::sort(pos->second.begin(), pos->second.end()); - reg_num_collection::iterator unique_end = - std::unique(pos->second.begin(), pos->second.end()); - if (unique_end != pos->second.end()) - pos->second.erase(unique_end, pos->second.end()); - } - assert(!pos->second.empty()); - if (pos->second.back() != LLDB_INVALID_REGNUM) - pos->second.push_back(LLDB_INVALID_REGNUM); - } - - // Now update all invalidate_regs with each register info as needed - for (size_t i = 0; i < num_regs; ++i) { - if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end()) - m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data(); - else - m_regs[i].invalidate_regs = nullptr; - } - - // Check if we need to automatically set the generic registers in case they - // weren't set - bool generic_regs_specified = false; - for (const auto ® : m_regs) { - if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) { - generic_regs_specified = true; - break; - } - } - - if (!generic_regs_specified) { - switch (arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - case llvm::Triple::aarch64_be: - for (auto ® : m_regs) { - if (strcmp(reg.name, "pc") == 0) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - else if ((strcmp(reg.name, "fp") == 0) || - (strcmp(reg.name, "x29") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if ((strcmp(reg.name, "lr") == 0) || - (strcmp(reg.name, "x30") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; - else if ((strcmp(reg.name, "sp") == 0) || - (strcmp(reg.name, "x31") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - else if (strcmp(reg.name, "cpsr") == 0) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - } - break; - - case llvm::Triple::arm: - case llvm::Triple::armeb: - case llvm::Triple::thumb: - case llvm::Triple::thumbeb: - for (auto ® : m_regs) { - if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - else if ((strcmp(reg.name, "sp") == 0) || - (strcmp(reg.name, "r13") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - else if ((strcmp(reg.name, "lr") == 0) || - (strcmp(reg.name, "r14") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; - else if ((strcmp(reg.name, "r7") == 0) && - arch.GetTriple().getVendor() == llvm::Triple::Apple) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if ((strcmp(reg.name, "r11") == 0) && - arch.GetTriple().getVendor() != llvm::Triple::Apple) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if (strcmp(reg.name, "fp") == 0) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if (strcmp(reg.name, "cpsr") == 0) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - } - break; - - case llvm::Triple::x86: - for (auto ® : m_regs) { - if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - else if ((strcmp(reg.name, "esp") == 0) || - (strcmp(reg.name, "sp") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - else if ((strcmp(reg.name, "ebp") == 0) || - (strcmp(reg.name, "fp") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if ((strcmp(reg.name, "eflags") == 0) || - (strcmp(reg.name, "flags") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - } - break; - - case llvm::Triple::x86_64: - for (auto ® : m_regs) { - if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - else if ((strcmp(reg.name, "rsp") == 0) || - (strcmp(reg.name, "sp") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - else if ((strcmp(reg.name, "rbp") == 0) || - (strcmp(reg.name, "fp") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if ((strcmp(reg.name, "rflags") == 0) || - (strcmp(reg.name, "flags") == 0)) - reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - } - break; - - default: - break; - } - } - - // At this stage call ConfigureOffsets to calculate register offsets for - // targets supporting dynamic offset calculation. It also calculates - // total byte size of register data. - ConfigureOffsets(); - - // Check if register info is reconfigurable - // AArch64 SVE register set has configurable register sizes - if (arch.GetTriple().isAArch64()) { - for (const auto ® : m_regs) { - if (strcmp(reg.name, "vg") == 0) { - m_is_reconfigurable = true; - break; - } - } - } -} - -void DynamicRegisterInfo::ConfigureOffsets() { - // We are going to create a map between remote (eRegisterKindProcessPlugin) - // and local (eRegisterKindLLDB) register numbers. This map will give us - // remote register numbers in increasing order for offset calculation. - std::map remote_to_local_regnum_map; - for (const auto ® : m_regs) - remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] = - reg.kinds[eRegisterKindLLDB]; - - // At this stage we manually calculate g/G packet offsets of all primary - // registers, only if target XML or qRegisterInfo packet did not send - // an offset explicitly. - uint32_t reg_offset = 0; - for (auto const ®num_pair : remote_to_local_regnum_map) { - if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 && - m_regs[regnum_pair.second].value_regs == nullptr) { - m_regs[regnum_pair.second].byte_offset = reg_offset; - - reg_offset = m_regs[regnum_pair.second].byte_offset + - m_regs[regnum_pair.second].byte_size; - } - } - - // Now update all value_regs with each register info as needed - for (auto ® : m_regs) { - if (reg.value_regs != nullptr) { - // Assign a valid offset to all pseudo registers if not assigned by stub. - // Pseudo registers with value_regs list populated will share same offset - // as that of their corresponding primary register in value_regs list. - if (reg.byte_offset == LLDB_INVALID_INDEX32) { - uint32_t value_regnum = reg.value_regs[0]; - if (value_regnum != LLDB_INVALID_INDEX32) - reg.byte_offset = - GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum]) - ->byte_offset; - } - } - - reg_offset = reg.byte_offset + reg.byte_size; - if (m_reg_data_byte_size < reg_offset) - m_reg_data_byte_size = reg_offset; - } -} - -bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; } - -size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); } - -size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); } - -size_t DynamicRegisterInfo::GetRegisterDataByteSize() const { - return m_reg_data_byte_size; -} - -const RegisterInfo * -DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) const { - if (i < m_regs.size()) - return &m_regs[i]; - return nullptr; -} - -RegisterInfo *DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) { - if (i < m_regs.size()) - return &m_regs[i]; - return nullptr; -} - -const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind, - uint32_t num) const { - uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num); - if (reg_index != LLDB_INVALID_REGNUM) - return &m_regs[reg_index]; - return nullptr; -} - -const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const { - if (i < m_sets.size()) - return &m_sets[i]; - return nullptr; -} - -uint32_t DynamicRegisterInfo::GetRegisterSetIndexByName(ConstString &set_name, - bool can_create) { - name_collection::iterator pos, end = m_set_names.end(); - for (pos = m_set_names.begin(); pos != end; ++pos) { - if (*pos == set_name) - return std::distance(m_set_names.begin(), pos); - } - - m_set_names.push_back(set_name); - m_set_reg_nums.resize(m_set_reg_nums.size() + 1); - RegisterSet new_set = {set_name.AsCString(), nullptr, 0, nullptr}; - m_sets.push_back(new_set); - return m_sets.size() - 1; -} - -uint32_t -DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber(uint32_t kind, - uint32_t num) const { - reg_collection::const_iterator pos, end = m_regs.end(); - for (pos = m_regs.begin(); pos != end; ++pos) { - if (pos->kinds[kind] == num) - return std::distance(m_regs.begin(), pos); - } - - return LLDB_INVALID_REGNUM; -} - -void DynamicRegisterInfo::Clear() { - m_regs.clear(); - m_sets.clear(); - m_set_reg_nums.clear(); - m_set_names.clear(); - m_value_regs_map.clear(); - m_invalidate_regs_map.clear(); - m_dynamic_reg_size_map.clear(); - m_reg_data_byte_size = 0; - m_finalized = false; -} - -void DynamicRegisterInfo::Dump() const { - StreamFile s(stdout, false); - const size_t num_regs = m_regs.size(); - s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n", - static_cast(this), static_cast(num_regs)); - for (size_t i = 0; i < num_regs; ++i) { - s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name); - s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s", - m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding, - FormatManager::GetFormatAsCString(m_regs[i].format)); - if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM) - s.Printf(", process plugin = %3u", - m_regs[i].kinds[eRegisterKindProcessPlugin]); - if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) - s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]); - if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) - s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]); - if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) - s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]); - if (m_regs[i].alt_name) - s.Printf(", alt-name = %s", m_regs[i].alt_name); - if (m_regs[i].value_regs) { - s.Printf(", value_regs = [ "); - for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) { - s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name); - } - s.Printf("]"); - } - if (m_regs[i].invalidate_regs) { - s.Printf(", invalidate_regs = [ "); - for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; - ++j) { - s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name); - } - s.Printf("]"); - } - s.EOL(); - } - - const size_t num_sets = m_sets.size(); - s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n", - static_cast(this), static_cast(num_sets)); - for (size_t i = 0; i < num_sets; ++i) { - s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, - m_sets[i].name); - for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) { - s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name); - } - s.Printf("]\n"); - } -} - -const lldb_private::RegisterInfo * -DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const { - for (auto ®_info : m_regs) - if (reg_info.name == reg_name) - return ®_info; - return nullptr; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h deleted file mode 100644 index 7e90454c6d9..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ /dev/null @@ -1,102 +0,0 @@ -//===-- DynamicRegisterInfo.h -----------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H - -#include -#include - -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/StructuredData.h" -#include "lldb/lldb-private.h" - -class DynamicRegisterInfo { -protected: - DynamicRegisterInfo(DynamicRegisterInfo &) = default; - DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default; - -public: - DynamicRegisterInfo() = default; - - DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, - const lldb_private::ArchSpec &arch); - - virtual ~DynamicRegisterInfo() = default; - - DynamicRegisterInfo(DynamicRegisterInfo &&info); - DynamicRegisterInfo &operator=(DynamicRegisterInfo &&info); - - size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, - const lldb_private::ArchSpec &arch); - - void AddRegister(lldb_private::RegisterInfo ®_info, - lldb_private::ConstString ®_name, - lldb_private::ConstString ®_alt_name, - lldb_private::ConstString &set_name); - - void Finalize(const lldb_private::ArchSpec &arch); - - size_t GetNumRegisters() const; - - size_t GetNumRegisterSets() const; - - size_t GetRegisterDataByteSize() const; - - const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i) const; - - lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i); - - const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const; - - uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name, - bool can_create); - - uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, - uint32_t num) const; - - const lldb_private::RegisterInfo *GetRegisterInfo(uint32_t kind, - uint32_t num) const; - - void Dump() const; - - void Clear(); - - bool IsReconfigurable(); - - const lldb_private::RegisterInfo * - GetRegisterInfo(llvm::StringRef reg_name) const; - -protected: - // Classes that inherit from DynamicRegisterInfo can see and modify these - typedef std::vector reg_collection; - typedef std::vector set_collection; - typedef std::vector reg_num_collection; - typedef std::vector set_reg_num_collection; - typedef std::vector name_collection; - typedef std::map reg_to_regs_map; - typedef std::vector dwarf_opcode; - typedef std::map dynamic_reg_size_map; - - void MoveFrom(DynamicRegisterInfo &&info); - - void ConfigureOffsets(); - - reg_collection m_regs; - set_collection m_sets; - set_reg_num_collection m_set_reg_nums; - name_collection m_set_names; - reg_to_regs_map m_value_regs_map; - reg_to_regs_map m_invalidate_regs_map; - dynamic_reg_size_map m_dynamic_reg_size_map; - size_t m_reg_data_byte_size = 0u; // The number of bytes required to store - // all registers - bool m_finalized = false; - bool m_is_reconfigurable = false; -}; -#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp deleted file mode 100644 index c91d7cb5ac3..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp +++ /dev/null @@ -1,314 +0,0 @@ -//===-- GDBRemoteCommunicationReplayServer.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 - -#include "lldb/Host/Config.h" -#include "llvm/ADT/ScopeExit.h" - -#include "GDBRemoteCommunicationReplayServer.h" -#include "ProcessGDBRemoteLog.h" - -// C Includes -// C++ Includes -#include - -// Project includes -#include "lldb/Host/ThreadLauncher.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/Event.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StringExtractorGDBRemote.h" - -using namespace llvm; -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::process_gdb_remote; - -/// Check if the given expected packet matches the actual packet. -static bool unexpected(llvm::StringRef expected, llvm::StringRef actual) { - // The 'expected' string contains the raw data, including the leading $ and - // trailing checksum. The 'actual' string contains only the packet's content. - if (expected.contains(actual)) - return false; - // Contains a PID which might be different. - if (expected.contains("vAttach")) - return false; - // Contains a ascii-hex-path. - if (expected.contains("QSetSTD")) - return false; - // Contains environment values. - if (expected.contains("QEnvironment")) - return false; - - return true; -} - -/// Check if we should reply to the given packet. -static bool skip(llvm::StringRef data) { - assert(!data.empty() && "Empty packet?"); - - // We've already acknowledge the '+' packet so we're done here. - if (data == "+") - return true; - - /// Don't 't reply to ^C. We need this because of stop reply packets, which - /// are only returned when the target halts. Reproducers synchronize these - /// 'asynchronous' replies, by recording them as a regular replies to the - /// previous packet (e.g. vCont). As a result, we should ignore real - /// asynchronous requests. - if (data.data()[0] == 0x03) - return true; - - return false; -} - -GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer() - : GDBRemoteCommunication("gdb-replay", "gdb-replay.rx_packet"), - m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"), - m_async_listener_sp( - Listener::MakeListener("lldb.gdb-replay.async-listener")), - m_async_thread_state_mutex() { - m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, - "async thread continue"); - m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, - "async thread should exit"); - - const uint32_t async_event_mask = - eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit; - m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, - async_event_mask); -} - -GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() { - StopAsyncThread(); -} - -GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( - Timeout timeout, Status &error, bool &interrupt, bool &quit) { - std::lock_guard guard(m_async_thread_state_mutex); - - StringExtractorGDBRemote packet; - PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false); - - if (packet_result != PacketResult::Success) { - if (!IsConnected()) { - error.SetErrorString("lost connection"); - quit = true; - } else { - error.SetErrorString("timeout"); - } - return packet_result; - } - - m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); - - // Check if we should reply to this packet. - if (skip(packet.GetStringRef())) - return PacketResult::Success; - - // This completes the handshake. Since m_send_acks was true, we can unset it - // already. - if (packet.GetStringRef() == "QStartNoAckMode") - m_send_acks = false; - - // A QEnvironment packet is sent for every environment variable. If the - // number of environment variables is different during replay, the replies - // become out of sync. - if (packet.GetStringRef().find("QEnvironment") == 0) - return SendRawPacketNoLock("$OK#9a"); - - Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - while (!m_packet_history.empty()) { - // Pop last packet from the history. - GDBRemotePacket entry = m_packet_history.back(); - m_packet_history.pop_back(); - - // Decode run-length encoding. - const std::string expanded_data = - GDBRemoteCommunication::ExpandRLE(entry.packet.data); - - // We've handled the handshake implicitly before. Skip the packet and move - // on. - if (entry.packet.data == "+") - continue; - - if (entry.type == GDBRemotePacket::ePacketTypeSend) { - if (unexpected(expanded_data, packet.GetStringRef())) { - LLDB_LOG(log, - "GDBRemoteCommunicationReplayServer expected packet: '{0}'", - expanded_data); - LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'", - packet.GetStringRef()); -#ifndef NDEBUG - // This behaves like a regular assert, but prints the expected and - // received packet before aborting. - printf("Reproducer expected packet: '%s'\n", expanded_data.c_str()); - printf("Reproducer received packet: '%s'\n", - packet.GetStringRef().data()); - llvm::report_fatal_error("Encountered unexpected packet during replay"); -#endif - return PacketResult::ErrorSendFailed; - } - - // Ignore QEnvironment packets as they're handled earlier. - if (expanded_data.find("QEnvironment") == 1) { - assert(m_packet_history.back().type == - GDBRemotePacket::ePacketTypeRecv); - m_packet_history.pop_back(); - } - - continue; - } - - if (entry.type == GDBRemotePacket::ePacketTypeInvalid) { - LLDB_LOG( - log, - "GDBRemoteCommunicationReplayServer skipped invalid packet: '{0}'", - packet.GetStringRef()); - continue; - } - - LLDB_LOG(log, - "GDBRemoteCommunicationReplayServer replied to '{0}' with '{1}'", - packet.GetStringRef(), entry.packet.data); - return SendRawPacketNoLock(entry.packet.data); - } - - quit = true; - - return packet_result; -} - -llvm::Error -GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) { - auto error_or_file = MemoryBuffer::getFile(path.GetPath()); - if (auto err = error_or_file.getError()) - return errorCodeToError(err); - - yaml::Input yin((*error_or_file)->getBuffer()); - yin >> m_packet_history; - - if (auto err = yin.error()) - return errorCodeToError(err); - - // We want to manipulate the vector like a stack so we need to reverse the - // order of the packets to have the oldest on at the back. - std::reverse(m_packet_history.begin(), m_packet_history.end()); - - return Error::success(); -} - -bool GDBRemoteCommunicationReplayServer::StartAsyncThread() { - std::lock_guard guard(m_async_thread_state_mutex); - if (!m_async_thread.IsJoinable()) { - // Create a thread that watches our internal state and controls which - // events make it to clients (into the DCProcess event queue). - llvm::Expected async_thread = ThreadLauncher::LaunchThread( - "", - GDBRemoteCommunicationReplayServer::AsyncThread, this); - if (!async_thread) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), - async_thread.takeError(), - "failed to launch host thread: {}"); - return false; - } - m_async_thread = *async_thread; - } - - // Wait for handshake. - m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); - - return m_async_thread.IsJoinable(); -} - -void GDBRemoteCommunicationReplayServer::StopAsyncThread() { - std::lock_guard guard(m_async_thread_state_mutex); - - if (!m_async_thread.IsJoinable()) - return; - - // Request thread to stop. - m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit); - - // Disconnect client. - Disconnect(); - - // Stop the thread. - m_async_thread.Join(nullptr); - m_async_thread.Reset(); -} - -void GDBRemoteCommunicationReplayServer::ReceivePacket( - GDBRemoteCommunicationReplayServer &server, bool &done) { - Status error; - bool interrupt; - auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1), - error, interrupt, done); - if (packet_result != GDBRemoteCommunication::PacketResult::Success && - packet_result != - GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) { - done = true; - } else { - server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); - } -} - -thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) { - GDBRemoteCommunicationReplayServer *server = - (GDBRemoteCommunicationReplayServer *)arg; - auto D = make_scope_exit([&]() { server->Disconnect(); }); - EventSP event_sp; - bool done = false; - while (!done) { - if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { - const uint32_t event_type = event_sp->GetType(); - if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) { - switch (event_type) { - case eBroadcastBitAsyncContinue: - ReceivePacket(*server, done); - if (done) - return {}; - break; - case eBroadcastBitAsyncThreadShouldExit: - default: - return {}; - } - } - } - } - - return {}; -} - -Status GDBRemoteCommunicationReplayServer::Connect( - process_gdb_remote::GDBRemoteCommunicationClient &client) { - repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); - if (!loader) - return Status("No loader provided."); - - static std::unique_ptr> - multi_loader = repro::MultiLoader::Create( - repro::Reproducer::Instance().GetLoader()); - if (!multi_loader) - return Status("No gdb remote provider found."); - - llvm::Optional history_file = multi_loader->GetNextFile(); - if (!history_file) - return Status("No gdb remote packet log found."); - - if (auto error = LoadReplayHistory(FileSpec(*history_file))) - return Status("Unable to load replay history"); - - if (auto error = GDBRemoteCommunication::ConnectLocally(client, *this)) - return Status("Unable to connect to replay server"); - - return {}; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h deleted file mode 100644 index 2f8770d0acc..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h +++ /dev/null @@ -1,88 +0,0 @@ -//===-- GDBRemoteCommunicationReplayServer.h --------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H -#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H - -// Other libraries and framework includes -#include "GDBRemoteCommunication.h" -#include "GDBRemoteCommunicationClient.h" -#include "GDBRemoteCommunicationHistory.h" - -// Project includes -#include "lldb/Host/HostThread.h" -#include "lldb/Utility/Broadcaster.h" -#include "lldb/lldb-private-forward.h" -#include "llvm/Support/Error.h" - -// C Includes -// C++ Includes -#include -#include -#include - -class StringExtractorGDBRemote; - -namespace lldb_private { -namespace process_gdb_remote { - -class ProcessGDBRemote; - -/// Dummy GDB server that replays packets from the GDB Remote Communication -/// history. This is used to replay GDB packets. -class GDBRemoteCommunicationReplayServer : public GDBRemoteCommunication { -public: - GDBRemoteCommunicationReplayServer(); - - ~GDBRemoteCommunicationReplayServer() override; - - PacketResult GetPacketAndSendResponse(Timeout timeout, - Status &error, bool &interrupt, - bool &quit); - - bool HandshakeWithClient() { return GetAck() == PacketResult::Success; } - - llvm::Error LoadReplayHistory(const FileSpec &path); - - bool StartAsyncThread(); - void StopAsyncThread(); - - Status Connect(process_gdb_remote::GDBRemoteCommunicationClient &client); - -protected: - enum { - eBroadcastBitAsyncContinue = (1 << 0), - eBroadcastBitAsyncThreadShouldExit = (1 << 1), - }; - - static void ReceivePacket(GDBRemoteCommunicationReplayServer &server, - bool &done); - static lldb::thread_result_t AsyncThread(void *arg); - - /// Replay history with the oldest packet at the end. - std::vector m_packet_history; - - /// Server thread. - Broadcaster m_async_broadcaster; - lldb::ListenerSP m_async_listener_sp; - HostThread m_async_thread; - std::recursive_mutex m_async_thread_state_mutex; - - bool m_skip_acks = false; - -private: - GDBRemoteCommunicationReplayServer( - const GDBRemoteCommunicationReplayServer &) = delete; - const GDBRemoteCommunicationReplayServer & - operator=(const GDBRemoteCommunicationReplayServer &) = delete; -}; - -} // namespace process_gdb_remote -} // namespace lldb_private - -#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index b2b80255272..f71240672bc 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Config.h" @@ -30,6 +31,7 @@ #include "lldb/Target/Platform.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" @@ -56,11 +58,9 @@ const static uint32_t g_default_packet_timeout_sec = 0; // not specified #endif // GDBRemoteCommunicationServerCommon constructor -GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( - const char *comm_name, const char *listener_name) - : GDBRemoteCommunicationServer(comm_name, listener_name), - m_process_launch_info(), m_process_launch_error(), m_proc_infos(), - m_proc_infos_index(0) { +GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon() + : GDBRemoteCommunicationServer(), m_process_launch_info(), + m_process_launch_error(), m_proc_infos(), m_proc_infos_index(0) { RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A, &GDBRemoteCommunicationServerCommon::Handle_A); RegisterMemberFunctionHandler( @@ -156,6 +156,9 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_vFile_size, &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vFile_fstat, + &GDBRemoteCommunicationServerCommon::Handle_vFile_FStat); RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_vFile_stat, &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); @@ -264,18 +267,18 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( } #endif - std::string s; - if (HostInfo::GetOSBuildString(s)) { + if (std::optional s = HostInfo::GetOSBuildString()) { response.PutCString("os_build:"); - response.PutStringAsRawHex8(s); + response.PutStringAsRawHex8(*s); response.PutChar(';'); } - if (HostInfo::GetOSKernelDescription(s)) { + if (std::optional s = HostInfo::GetOSKernelDescription()) { response.PutCString("os_kernel:"); - response.PutStringAsRawHex8(s); + response.PutStringAsRawHex8(*s); response.PutChar(';'); } + std::string s; #if defined(__APPLE__) #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) @@ -300,7 +303,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( response.PutChar(';'); } #endif // #if defined(__APPLE__) - + // coverity[unsigned_compare] if (g_default_packet_timeout_sec > 0) response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec); @@ -423,14 +426,14 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qUserName( StringExtractorGDBRemote &packet) { #if LLDB_ENABLE_POSIX - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); // Packet format: "qUserName:%i" where %i is the uid packet.SetFilePos(::strlen("qUserName:")); uint32_t uid = packet.GetU32(UINT32_MAX); if (uid != UINT32_MAX) { - if (llvm::Optional name = + if (std::optional name = HostInfo::GetUserIDResolver().GetUserName(uid)) { StreamString response; response.PutStringAsRawHex8(*name); @@ -450,7 +453,7 @@ GDBRemoteCommunicationServerCommon::Handle_qGroupName( packet.SetFilePos(::strlen("qGroupName:")); uint32_t gid = packet.GetU32(UINT32_MAX); if (gid != UINT32_MAX) { - if (llvm::Optional name = + if (std::optional name = HostInfo::GetUserIDResolver().GetGroupName(gid)) { StreamString response; response.PutStringAsRawHex8(*name); @@ -501,10 +504,6 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( packet.GetHexByteStringTerminatedBy(path, ','); if (!path.empty()) { if (packet.GetChar() == ',') { - // FIXME - // The flag values for OpenOptions do not match the values used by GDB - // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags - // * rdar://problem/46788934 auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0)); if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); @@ -513,22 +512,21 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( // Do not close fd. auto file = FileSystem::Instance().Open(path_spec, flags, mode, false); - int save_errno = 0; + StreamString response; + response.PutChar('F'); + int descriptor = File::kInvalidDescriptor; if (file) { descriptor = file.get()->GetDescriptor(); + response.Printf("%x", descriptor); } else { + response.PutCString("-1"); std::error_code code = errorToErrorCode(file.takeError()); if (code.category() == std::system_category()) { - save_errno = code.value(); + response.Printf(",%x", code.value()); } } - StreamString response; - response.PutChar('F'); - response.Printf("%i", descriptor); - if (save_errno) - response.Printf(",%i", save_errno); return SendPacketNoLock(response.GetString()); } } @@ -536,11 +534,22 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( return SendErrorResponse(18); } +static GDBErrno system_errno_to_gdb(int err) { + switch (err) { +#define HANDLE_ERRNO(name, value) \ + case name: \ + return GDB_##name; +#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def" + default: + return GDB_EUNKNOWN; + } +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_vFile_Close( StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen("vFile:close:")); - int fd = packet.GetS32(-1); + int fd = packet.GetS32(-1, 16); int err = -1; int save_errno = 0; if (fd >= 0) { @@ -553,9 +562,9 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close( } StreamString response; response.PutChar('F'); - response.Printf("%i", err); + response.Printf("%x", err); if (save_errno) - response.Printf(",%i", save_errno); + response.Printf(",%x", system_errno_to_gdb(save_errno)); return SendPacketNoLock(response.GetString()); } @@ -564,28 +573,29 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pRead( StringExtractorGDBRemote &packet) { StreamGDBRemote response; packet.SetFilePos(::strlen("vFile:pread:")); - int fd = packet.GetS32(-1); + int fd = packet.GetS32(-1, 16); if (packet.GetChar() == ',') { - size_t count = packet.GetU64(SIZE_MAX); + size_t count = packet.GetHexMaxU64(false, SIZE_MAX); if (packet.GetChar() == ',') { - off_t offset = packet.GetU64(UINT32_MAX); + off_t offset = packet.GetHexMaxU32(false, UINT32_MAX); if (count == SIZE_MAX) { - response.Printf("F-1:%i", EINVAL); + response.Printf("F-1:%x", EINVAL); return SendPacketNoLock(response.GetString()); } std::string buffer(count, 0); - NativeFile file(fd, File::eOpenOptionRead, false); + NativeFile file(fd, File::eOpenOptionReadOnly, false); Status error = file.Read(static_cast(&buffer[0]), count, offset); - const ssize_t bytes_read = error.Success() ? count : -1; const int save_errno = error.GetError(); response.PutChar('F'); - response.Printf("%zi", bytes_read); - if (save_errno) - response.Printf(",%i", save_errno); - else { + if (error.Success()) { + response.Printf("%zx", count); response.PutChar(';'); - response.PutEscapedBytes(&buffer[0], bytes_read); + response.PutEscapedBytes(&buffer[0], count); + } else { + response.PutCString("-1"); + if (save_errno) + response.Printf(",%x", system_errno_to_gdb(save_errno)); } return SendPacketNoLock(response.GetString()); } @@ -601,23 +611,26 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite( StreamGDBRemote response; response.PutChar('F'); - int fd = packet.GetU32(UINT32_MAX); + int fd = packet.GetS32(-1, 16); if (packet.GetChar() == ',') { - off_t offset = packet.GetU64(UINT32_MAX); + off_t offset = packet.GetHexMaxU32(false, UINT32_MAX); if (packet.GetChar() == ',') { std::string buffer; if (packet.GetEscapedBinaryData(buffer)) { - NativeFile file(fd, File::eOpenOptionWrite, false); + NativeFile file(fd, File::eOpenOptionWriteOnly, false); size_t count = buffer.size(); Status error = file.Write(static_cast(&buffer[0]), count, offset); - const ssize_t bytes_written = error.Success() ? count : -1; const int save_errno = error.GetError(); - response.Printf("%zi", bytes_written); - if (save_errno) - response.Printf(",%i", save_errno); + if (error.Success()) + response.Printf("%zx", count); + else { + response.PutCString("-1"); + if (save_errno) + response.Printf(",%x", system_errno_to_gdb(save_errno)); + } } else { - response.Printf("-1,%i", EINVAL); + response.Printf("-1,%x", EINVAL); } return SendPacketNoLock(response.GetString()); } @@ -659,9 +672,10 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( std::error_code ec; const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); StreamString response; - response.Printf("F%u", mode); - if (mode == 0 || ec) - response.Printf(",%i", (int)Status(ec).GetError()); + if (mode != llvm::sys::fs::perms_not_known) + response.Printf("F%x", mode); + else + response.Printf("F-1,%x", (int)Status(ec).GetError()); return SendPacketNoLock(response.GetString()); } return SendErrorResponse(23); @@ -701,7 +715,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); StreamString response; - response.Printf("F%u,%u", error.GetError(), error.GetError()); + response.Printf("F%x,%x", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -713,7 +727,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink( packet.GetHexByteString(path); Status error(llvm::sys::fs::remove(path)); StreamString response; - response.Printf("F%u,%u", error.GetError(), error.GetError()); + response.Printf("F%x,%x", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -755,6 +769,54 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( return SendErrorResponse(24); } +template +static void fill_clamp(T &dest, U src, typename T::value_type fallback) { + static_assert(std::is_unsigned::value, + "Destination type must be unsigned."); + using UU = std::make_unsigned_t; + constexpr auto T_max = std::numeric_limits::max(); + dest = src >= 0 && static_cast(src) <= T_max ? src : fallback; +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerCommon::Handle_vFile_FStat( + StringExtractorGDBRemote &packet) { + StreamGDBRemote response; + packet.SetFilePos(::strlen("vFile:fstat:")); + int fd = packet.GetS32(-1, 16); + + struct stat file_stats; + if (::fstat(fd, &file_stats) == -1) { + const int save_errno = errno; + response.Printf("F-1,%x", system_errno_to_gdb(save_errno)); + return SendPacketNoLock(response.GetString()); + } + + GDBRemoteFStatData data; + fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0); + fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0); + data.gdb_st_mode = file_stats.st_mode; + fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX); + fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0); + fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0); + fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0); + data.gdb_st_size = file_stats.st_size; +#if !defined(_WIN32) + data.gdb_st_blksize = file_stats.st_blksize; + data.gdb_st_blocks = file_stats.st_blocks; +#else + data.gdb_st_blksize = 0; + data.gdb_st_blocks = 0; +#endif + fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0); + fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0); + fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0); + + response.Printf("F%zx;", sizeof(data)); + response.PutEscapedBytes(&data, sizeof(data)); + return SendPacketNoLock(response.GetString()); +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_vFile_Stat( StringExtractorGDBRemote &packet) { @@ -795,7 +857,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir( Status error(llvm::sys::fs::create_directory(path, mode)); StreamGDBRemote response; - response.Printf("F%u", error.GetError()); + response.Printf("F%x", error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -815,7 +877,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( Status error(llvm::sys::fs::setPermissions(path, perms)); StreamGDBRemote response; - response.Printf("F%u", error.GetError()); + response.Printf("F%x", error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -958,7 +1020,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { // encoded argument value list, but we will stay true to the documented // version of the 'A' packet here... - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); int actual_arg_index = 0; packet.SetFilePos(1); // Skip the 'A' @@ -1075,7 +1137,8 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( response.PutChar(';'); response.PutCString("file_path:"); - response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString()); + response.PutStringAsRawHex8( + matched_module_spec.GetFileSpec().GetPath().c_str()); response.PutChar(';'); response.PutCString("file_offset:"); response.PutHex64(file_offset); @@ -1150,7 +1213,7 @@ void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse( proc_info.GetUserID(), proc_info.GetGroupID(), proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); response.PutCString("name:"); - response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString()); + response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str()); response.PutChar(';'); response.PutCString("args:"); @@ -1287,5 +1350,6 @@ std::vector GDBRemoteCommunicationServerCommon::HandleFeatures( llvm::formatv("PacketSize={0}", max_packet_size), "QStartNoAckMode+", "qEcho+", + "native-signals+", }; } diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp deleted file mode 100644 index 7c7c5d73680..00000000000 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===-- SWIGPythonBridge.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 "lldb/Host/Config.h" -#include "lldb/lldb-enumerations.h" - -#if LLDB_ENABLE_PYTHON - -// LLDB Python header must be included first -#include "lldb-python.h" - -#include "SWIGPythonBridge.h" - -using namespace lldb; - -namespace lldb_private { - -template const char *GetPythonValueFormatString(T t); -template <> const char *GetPythonValueFormatString(char *) { return "s"; } -template <> const char *GetPythonValueFormatString(char) { return "b"; } -template <> const char *GetPythonValueFormatString(unsigned char) { - return "B"; -} -template <> const char *GetPythonValueFormatString(short) { return "h"; } -template <> const char *GetPythonValueFormatString(unsigned short) { - return "H"; -} -template <> const char *GetPythonValueFormatString(int) { return "i"; } -template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; } -template <> const char *GetPythonValueFormatString(long) { return "l"; } -template <> const char *GetPythonValueFormatString(unsigned long) { - return "k"; -} -template <> const char *GetPythonValueFormatString(long long) { return "L"; } -template <> const char *GetPythonValueFormatString(unsigned long long) { - return "K"; -} -template <> const char *GetPythonValueFormatString(float) { return "f"; } -template <> const char *GetPythonValueFormatString(double) { return "d"; } - -} // namespace lldb_private - -#endif // LLDB_ENABLE_PYTHON diff --git a/gnu/llvm/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp b/gnu/llvm/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp deleted file mode 100644 index c88ad9dc6a5..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//===-- TraceSessionFileParser.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 "TraceSessionFileParser.h" -#include "ThreadPostMortemTrace.h" - -#include - -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; -using namespace llvm; - -void TraceSessionFileParser::NormalizePath(lldb_private::FileSpec &file_spec) { - if (file_spec.IsRelative()) - file_spec.PrependPathComponent(m_session_file_dir); -} - -Error TraceSessionFileParser::ParseModule(lldb::TargetSP &target_sp, - const JSONModule &module) { - FileSpec system_file_spec(module.system_path); - NormalizePath(system_file_spec); - - FileSpec local_file_spec(module.file.hasValue() ? *module.file - : module.system_path); - NormalizePath(local_file_spec); - - ModuleSpec module_spec; - module_spec.GetFileSpec() = local_file_spec; - module_spec.GetPlatformFileSpec() = system_file_spec; - - if (module.uuid.hasValue()) - module_spec.GetUUID().SetFromStringRef(*module.uuid); - - Status error; - ModuleSP module_sp = - target_sp->GetOrCreateModule(module_spec, /*notify*/ false, &error); - - if (error.Fail()) - return error.ToError(); - - bool load_addr_changed = false; - module_sp->SetLoadAddress(*target_sp, module.load_address.value, false, - load_addr_changed); - return llvm::Error::success(); -} - -Error TraceSessionFileParser::CreateJSONError(json::Path::Root &root, - const json::Value &value) { - std::string err; - raw_string_ostream os(err); - root.printErrorContext(value, os); - return createStringError( - std::errc::invalid_argument, "%s\n\nContext:\n%s\n\nSchema:\n%s", - toString(root.getError()).c_str(), os.str().c_str(), m_schema.data()); -} - -std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) { - std::ostringstream schema_builder; - schema_builder << "{\n \"trace\": "; - schema_builder << plugin_schema.data() << ","; - schema_builder << R"( - "processes": [ - { - "pid": integer, - "triple": string, // llvm-triple - "threads": [ - { - "tid": integer, - "traceFile": string - } - ], - "modules": [ - { - "systemPath": string, // original path of the module at runtime - "file"?: string, // copy of the file if not available at "systemPath" - "loadAddress": string, // string address in hex or decimal form - "uuid"?: string, - } - ] - } - ] - // Notes: - // All paths are either absolute or relative to the session file. -} -)"; - return schema_builder.str(); -} - -ThreadPostMortemTraceSP -TraceSessionFileParser::ParseThread(ProcessSP &process_sp, - const JSONThread &thread) { - lldb::tid_t tid = static_cast(thread.tid); - - FileSpec trace_file(thread.trace_file); - NormalizePath(trace_file); - - ThreadPostMortemTraceSP thread_sp = - std::make_shared(*process_sp, tid, trace_file); - process_sp->GetThreadList().AddThread(thread_sp); - return thread_sp; -} - -Expected -TraceSessionFileParser::ParseProcess(const JSONProcess &process) { - TargetSP target_sp; - Status error = m_debugger.GetTargetList().CreateTarget( - m_debugger, /*user_exe_path*/ StringRef(), process.triple, - eLoadDependentsNo, - /*platform_options*/ nullptr, target_sp); - - if (!target_sp) - return error.ToError(); - - ParsedProcess parsed_process; - parsed_process.target_sp = target_sp; - - ProcessSP process_sp = target_sp->CreateProcess( - /*listener*/ nullptr, "trace", - /*crash_file*/ nullptr, - /*can_connect*/ false); - - process_sp->SetID(static_cast(process.pid)); - - for (const JSONThread &thread : process.threads) - parsed_process.threads.push_back(ParseThread(process_sp, thread)); - - for (const JSONModule &module : process.modules) - if (Error err = ParseModule(target_sp, module)) - return std::move(err); - - if (!process.threads.empty()) - process_sp->GetThreadList().SetSelectedThreadByIndexID(0); - - // We invoke DidAttach to create a correct stopped state for the process and - // its threads. - ArchSpec process_arch; - process_sp->DidAttach(process_arch); - - return parsed_process; -} - -Expected> -TraceSessionFileParser::ParseCommonSessionFile( - const JSONTraceSessionBase &session) { - std::vector parsed_processes; - - auto onError = [&]() { - // Delete all targets that were created so far in case of failures - for (ParsedProcess &parsed_process : parsed_processes) - m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp); - }; - - for (const JSONProcess &process : session.processes) { - if (Expected parsed_process = ParseProcess(process)) - parsed_processes.push_back(std::move(*parsed_process)); - else { - onError(); - return parsed_process.takeError(); - } - } - return parsed_processes; -} - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONAddress &address, - Path path) { - Optional s = value.getAsString(); - if (s.hasValue() && !s->getAsInteger(0, address.value)) - return true; - - path.report("expected numeric string"); - return false; -} - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONModule &module, - Path path) { - ObjectMapper o(value, path); - return o && o.map("systemPath", module.system_path) && - o.map("file", module.file) && - o.map("loadAddress", module.load_address) && - o.map("uuid", module.uuid); -} - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONThread &thread, - Path path) { - ObjectMapper o(value, path); - return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file); -} - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONProcess &process, - Path path) { - ObjectMapper o(value, path); - return o && o.map("pid", process.pid) && o.map("triple", process.triple) && - o.map("threads", process.threads) && o.map("modules", process.modules); -} - -bool fromJSON(const Value &value, - TraceSessionFileParser::JSONTracePluginSettings &plugin_settings, - Path path) { - ObjectMapper o(value, path); - return o && o.map("type", plugin_settings.type); -} - -bool fromJSON(const Value &value, - TraceSessionFileParser::JSONTraceSessionBase &session, - Path path) { - ObjectMapper o(value, path); - return o && o.map("processes", session.processes); -} - -} // namespace json -} // namespace llvm diff --git a/gnu/llvm/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h b/gnu/llvm/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h deleted file mode 100644 index 6abaffcecd3..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h +++ /dev/null @@ -1,179 +0,0 @@ -//===-- TraceSessionFileParser.h --------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_TARGET_TRACESESSIONPARSER_H -#define LLDB_TARGET_TRACESESSIONPARSER_H - -#include "llvm/Support/JSON.h" - -#include "ThreadPostMortemTrace.h" - -namespace lldb_private { - -/// \class TraceSessionFileParser TraceSessionFileParser.h -/// -/// Base class for parsing the common information of JSON trace session files. -/// Contains the basic C++ structs that represent the JSON data, which include -/// \a JSONTraceSession as the root object. -/// -/// See \a Trace::FindPlugin for more information regarding these JSON files. -class TraceSessionFileParser { -public: - /// C++ structs representing the JSON trace session. - /// \{ - struct JSONAddress { - lldb::addr_t value; - }; - - struct JSONModule { - std::string system_path; - llvm::Optional file; - JSONAddress load_address; - llvm::Optional uuid; - }; - - struct JSONThread { - int64_t tid; - std::string trace_file; - }; - - struct JSONProcess { - int64_t pid; - std::string triple; - std::vector threads; - std::vector modules; - }; - - struct JSONTracePluginSettings { - std::string type; - }; - - struct JSONTraceSessionBase { - std::vector processes; - }; - - /// The trace plug-in implementation should provide its own TPluginSettings, - /// which corresponds to the "trace" section of the schema. - template - struct JSONTraceSession : JSONTraceSessionBase { - TPluginSettings trace; - }; - /// \} - - /// Helper struct holding the objects created when parsing a process - struct ParsedProcess { - lldb::TargetSP target_sp; - std::vector threads; - }; - - TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir, - llvm::StringRef schema) - : m_debugger(debugger), m_session_file_dir(session_file_dir), - m_schema(schema) {} - - /// Build the full schema for a Trace plug-in. - /// - /// \param[in] plugin_schema - /// The subschema that corresponds to the "trace" section of the schema. - /// - /// \return - /// The full schema containing the common attributes and the plug-in - /// specific attributes. - static std::string BuildSchema(llvm::StringRef plugin_schema); - - /// Parse the fields common to all trace session schemas. - /// - /// \param[in] session - /// The session json objects already deserialized. - /// - /// \return - /// A list of \a ParsedProcess containing all threads and targets created - /// during the parsing, or an error in case of failures. In case of - /// errors, no side effects are produced. - llvm::Expected> - ParseCommonSessionFile(const JSONTraceSessionBase &session); - -protected: - /// Resolve non-absolute paths relative to the session file folder. It - /// modifies the given file_spec. - void NormalizePath(lldb_private::FileSpec &file_spec); - - lldb::ThreadPostMortemTraceSP ParseThread(lldb::ProcessSP &process_sp, - const JSONThread &thread); - - llvm::Expected ParseProcess(const JSONProcess &process); - - llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module); - - /// Create a user-friendly error message upon a JSON-parsing failure using the - /// \a json::ObjectMapper functionality. - /// - /// \param[in] root - /// The \a llvm::json::Path::Root used to parse the JSON \a value. - /// - /// \param[in] value - /// The json value that failed to parse. - /// - /// \return - /// An \a llvm::Error containing the user-friendly error message. - llvm::Error CreateJSONError(llvm::json::Path::Root &root, - const llvm::json::Value &value); - - Debugger &m_debugger; - std::string m_session_file_dir; - llvm::StringRef m_schema; -}; -} // namespace lldb_private - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONAddress &address, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONModule &module, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONThread &thread, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONProcess &process, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONTracePluginSettings - &plugin_settings, - Path path); - -bool fromJSON( - const Value &value, - lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session, - Path path); - -template -bool fromJSON( - const Value &value, - lldb_private::TraceSessionFileParser::JSONTraceSession - &session, - Path path) { - ObjectMapper o(value, path); - return o && o.map("trace", session.trace) && - fromJSON(value, - (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &) - session, - path); -} - -} // namespace json -} // namespace llvm - -#endif // LLDB_TARGET_TRACESESSIONPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp b/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp deleted file mode 100644 index 3827881454c..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp +++ /dev/null @@ -1,279 +0,0 @@ -//===-- IntelPTDecoder.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 "IntelPTDecoder.h" - -#include "llvm/Support/MemoryBuffer.h" - -#include "../common/ThreadPostMortemTrace.h" -#include "DecodedThread.h" -#include "TraceIntelPT.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/Section.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/StringExtractor.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::trace_intel_pt; -using namespace llvm; - -/// Move the decoder forward to the next synchronization point (i.e. next PSB -/// packet). -/// -/// Once the decoder is at that sync. point, it can start decoding instructions. -/// -/// \return -/// A negative number with the libipt error if we couldn't synchronize. -/// Otherwise, a positive number with the synchronization status will be -/// returned. -static int FindNextSynchronizationPoint(pt_insn_decoder &decoder) { - // Try to sync the decoder. If it fails, then get - // the decoder_offset and try to sync again from - // the next synchronization point. If the - // new_decoder_offset is same as decoder_offset - // then we can't move to the next synchronization - // point. Otherwise, keep resyncing until either - // end of trace stream (eos) is reached or - // pt_insn_sync_forward() passes. - int errcode = pt_insn_sync_forward(&decoder); - - if (errcode != -pte_eos && errcode < 0) { - uint64_t decoder_offset = 0; - int errcode_off = pt_insn_get_offset(&decoder, &decoder_offset); - if (errcode_off >= 0) { // we could get the offset - while (true) { - errcode = pt_insn_sync_forward(&decoder); - if (errcode >= 0 || errcode == -pte_eos) - break; - - uint64_t new_decoder_offset = 0; - errcode_off = pt_insn_get_offset(&decoder, &new_decoder_offset); - if (errcode_off < 0) - break; // We can't further synchronize. - else if (new_decoder_offset <= decoder_offset) { - // We tried resyncing the decoder and - // decoder didn't make any progress because - // the offset didn't change. We will not - // make any progress further. Hence, - // stopping in this situation. - break; - } - // We'll try again starting from a new offset. - decoder_offset = new_decoder_offset; - } - } - } - - return errcode; -} - -/// Before querying instructions, we need to query the events associated that -/// instruction e.g. timing events like ptev_tick, or paging events like -/// ptev_paging. -/// -/// \return -/// 0 if there were no errors processing the events, or a negative libipt -/// error code in case of errors. -static int ProcessPTEvents(pt_insn_decoder &decoder, int errcode) { - while (errcode & pts_event_pending) { - pt_event event; - errcode = pt_insn_event(&decoder, &event, sizeof(event)); - if (errcode < 0) - return errcode; - } - return 0; -} - -/// Decode all the instructions from a configured decoder. -/// The decoding flow is based on -/// https://github.com/intel/libipt/blob/master/doc/howto_libipt.md#the-instruction-flow-decode-loop -/// but with some relaxation to allow for gaps in the trace. -/// -/// Error codes returned by libipt while decoding are: -/// - negative: actual errors -/// - positive or zero: not an error, but a list of bits signaling the status of -/// the decoder -/// -/// \param[in] decoder -/// A configured libipt \a pt_insn_decoder. -/// -/// \return -/// The decoded instructions. -static std::vector -DecodeInstructions(pt_insn_decoder &decoder) { - std::vector instructions; - - while (true) { - int errcode = FindNextSynchronizationPoint(decoder); - if (errcode == -pte_eos) - break; - - if (errcode < 0) { - instructions.emplace_back(make_error(errcode)); - break; - } - - // We have synchronized, so we can start decoding - // instructions and events. - while (true) { - errcode = ProcessPTEvents(decoder, errcode); - if (errcode < 0) { - instructions.emplace_back(make_error(errcode)); - break; - } - pt_insn insn; - - errcode = pt_insn_next(&decoder, &insn, sizeof(insn)); - if (errcode == -pte_eos) - break; - - if (errcode < 0) { - instructions.emplace_back(make_error(errcode, insn.ip)); - break; - } - - uint64_t time; - int time_error = pt_insn_time(&decoder, &time, nullptr, nullptr); - if (time_error == -pte_invalid) { - // This happens if we invoke the pt_insn_time method incorrectly, - // but the instruction is good though. - instructions.emplace_back( - make_error(time_error, insn.ip)); - instructions.emplace_back(insn); - break; - } - if (time_error == -pte_no_time) { - // We simply don't have time information, i.e. None of TSC, MTC or CYC - // was enabled. - instructions.emplace_back(insn); - } else { - instructions.emplace_back(insn, time); - } - } - } - - return instructions; -} - -/// Callback used by libipt for reading the process memory. -/// -/// More information can be found in -/// https://github.com/intel/libipt/blob/master/doc/man/pt_image_set_callback.3.md -static int ReadProcessMemory(uint8_t *buffer, size_t size, - const pt_asid * /* unused */, uint64_t pc, - void *context) { - Process *process = static_cast(context); - - Status error; - int bytes_read = process->ReadMemory(pc, buffer, size, error); - if (error.Fail()) - return -pte_nomap; - return bytes_read; -} - -static Expected> -DecodeInMemoryTrace(Process &process, TraceIntelPT &trace_intel_pt, - MutableArrayRef buffer) { - Expected cpu_info = trace_intel_pt.GetCPUInfo(); - if (!cpu_info) - return cpu_info.takeError(); - - pt_config config; - pt_config_init(&config); - config.cpu = *cpu_info; - - if (int errcode = pt_cpu_errata(&config.errata, &config.cpu)) - return make_error(errcode); - - config.begin = buffer.data(); - config.end = buffer.data() + buffer.size(); - - pt_insn_decoder *decoder = pt_insn_alloc_decoder(&config); - if (!decoder) - return make_error(-pte_nomem); - - pt_image *image = pt_insn_get_image(decoder); - - int errcode = pt_image_set_callback(image, ReadProcessMemory, &process); - assert(errcode == 0); - (void)errcode; - - std::vector instructions = DecodeInstructions(*decoder); - - pt_insn_free_decoder(decoder); - return instructions; -} - -static Expected> -DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt, - const FileSpec &trace_file, size_t &raw_trace_size) { - ErrorOr> trace_or_error = - MemoryBuffer::getFile(trace_file.GetPath()); - if (std::error_code err = trace_or_error.getError()) - return errorCodeToError(err); - - MemoryBuffer &trace = **trace_or_error; - MutableArrayRef trace_data( - // The libipt library does not modify the trace buffer, hence the - // following cast is safe. - reinterpret_cast(const_cast(trace.getBufferStart())), - trace.getBufferSize()); - raw_trace_size = trace_data.size(); - return DecodeInMemoryTrace(process, trace_intel_pt, trace_data); -} - -static Expected> -DecodeLiveThread(Thread &thread, TraceIntelPT &trace, size_t &raw_trace_size) { - Expected> buffer = - trace.GetLiveThreadBuffer(thread.GetID()); - if (!buffer) - return buffer.takeError(); - raw_trace_size = buffer->size(); - if (Expected cpu_info = trace.GetCPUInfo()) - return DecodeInMemoryTrace(*thread.GetProcess(), trace, - MutableArrayRef(*buffer)); - else - return cpu_info.takeError(); -} - -DecodedThreadSP ThreadDecoder::Decode() { - if (!m_decoded_thread.hasValue()) - m_decoded_thread = DoDecode(); - return *m_decoded_thread; -} - -PostMortemThreadDecoder::PostMortemThreadDecoder( - const lldb::ThreadPostMortemTraceSP &trace_thread, TraceIntelPT &trace) - : m_trace_thread(trace_thread), m_trace(trace) {} - -DecodedThreadSP PostMortemThreadDecoder::DoDecode() { - size_t raw_trace_size = 0; - if (Expected> instructions = - DecodeTraceFile(*m_trace_thread->GetProcess(), m_trace, - m_trace_thread->GetTraceFile(), raw_trace_size)) - return std::make_shared(m_trace_thread->shared_from_this(), - std::move(*instructions), - raw_trace_size); - else - return std::make_shared(m_trace_thread->shared_from_this(), - instructions.takeError()); -} - -LiveThreadDecoder::LiveThreadDecoder(Thread &thread, TraceIntelPT &trace) - : m_thread_sp(thread.shared_from_this()), m_trace(trace) {} - -DecodedThreadSP LiveThreadDecoder::DoDecode() { - size_t raw_trace_size = 0; - if (Expected> instructions = - DecodeLiveThread(*m_thread_sp, m_trace, raw_trace_size)) - return std::make_shared( - m_thread_sp, std::move(*instructions), raw_trace_size); - else - return std::make_shared(m_thread_sp, - instructions.takeError()); -} diff --git a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h b/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h deleted file mode 100644 index e969db579e5..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h +++ /dev/null @@ -1,87 +0,0 @@ -//===-- IntelPTDecoder.h --======--------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H -#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H - -#include "intel-pt.h" - -#include "DecodedThread.h" -#include "forward-declarations.h" -#include "lldb/Target/Process.h" -#include "lldb/Utility/FileSpec.h" - -namespace lldb_private { -namespace trace_intel_pt { - -/// Base class that handles the decoding of a thread and caches the result. -class ThreadDecoder { -public: - virtual ~ThreadDecoder() = default; - - ThreadDecoder() = default; - - /// Decode the thread and store the result internally, to avoid - /// recomputations. - /// - /// \return - /// A \a DecodedThread instance. - DecodedThreadSP Decode(); - - ThreadDecoder(const ThreadDecoder &other) = delete; - ThreadDecoder &operator=(const ThreadDecoder &other) = delete; - -protected: - /// Decode the thread. - /// - /// \return - /// A \a DecodedThread instance. - virtual DecodedThreadSP DoDecode() = 0; - - llvm::Optional m_decoded_thread; -}; - -/// Decoder implementation for \a lldb_private::ThreadPostMortemTrace, which are -/// non-live processes that come trace session files. -class PostMortemThreadDecoder : public ThreadDecoder { -public: - /// \param[in] trace_thread - /// The thread whose trace file will be decoded. - /// - /// \param[in] trace - /// The main Trace object who owns this decoder and its data. - PostMortemThreadDecoder(const lldb::ThreadPostMortemTraceSP &trace_thread, - TraceIntelPT &trace); - -private: - DecodedThreadSP DoDecode() override; - - lldb::ThreadPostMortemTraceSP m_trace_thread; - TraceIntelPT &m_trace; -}; - -class LiveThreadDecoder : public ThreadDecoder { -public: - /// \param[in] thread - /// The thread whose traces will be decoded. - /// - /// \param[in] trace - /// The main Trace object who owns this decoder and its data. - LiveThreadDecoder(Thread &thread, TraceIntelPT &trace); - -private: - DecodedThreadSP DoDecode() override; - - lldb::ThreadSP m_thread_sp; - TraceIntelPT &m_trace; -}; - -} // namespace trace_intel_pt -} // namespace lldb_private - -#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H diff --git a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp deleted file mode 100644 index 5af7c269d0c..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//===-- TraceIntelPTSessionFileParser.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 "TraceIntelPTSessionFileParser.h" - -#include "../common/ThreadPostMortemTrace.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/ThreadList.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::trace_intel_pt; -using namespace llvm; - -StringRef TraceIntelPTSessionFileParser::GetSchema() { - static std::string schema; - if (schema.empty()) { - schema = TraceSessionFileParser::BuildSchema(R"({ - "type": "intel-pt", - "cpuInfo": { - "vendor": "intel" | "unknown", - "family": integer, - "model": integer, - "stepping": integer - } - })"); - } - return schema; -} - -pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU( - const JSONTraceIntelPTCPUInfo &cpu_info) { - return {cpu_info.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown, - static_cast(cpu_info.family), - static_cast(cpu_info.model), - static_cast(cpu_info.stepping)}; -} - -TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance( - const pt_cpu &cpu_info, std::vector &parsed_processes) { - std::vector threads; - for (const ParsedProcess &parsed_process : parsed_processes) - threads.insert(threads.end(), parsed_process.threads.begin(), - parsed_process.threads.end()); - - TraceSP trace_instance(new TraceIntelPT(cpu_info, threads)); - for (const ParsedProcess &parsed_process : parsed_processes) - parsed_process.target_sp->SetTrace(trace_instance); - - return trace_instance; -} - -Expected TraceIntelPTSessionFileParser::Parse() { - json::Path::Root root("traceSession"); - TraceSessionFileParser::JSONTraceSession session; - if (!json::fromJSON(m_trace_session_file, session, root)) - return CreateJSONError(root, m_trace_session_file); - - if (Expected> parsed_processes = - ParseCommonSessionFile(session)) - return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo), - *parsed_processes); - else - return parsed_processes.takeError(); -} - -namespace llvm { -namespace json { - -bool fromJSON( - const Value &value, - TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings, - Path path) { - ObjectMapper o(value, path); - return o && o.map("cpuInfo", plugin_settings.cpuInfo) && - fromJSON( - value, - (TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings, - path); -} - -bool fromJSON(const json::Value &value, - TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info, - Path path) { - ObjectMapper o(value, path); - return o && o.map("vendor", cpu_info.vendor) && - o.map("family", cpu_info.family) && o.map("model", cpu_info.model) && - o.map("stepping", cpu_info.stepping); -} - -Value toJSON( - const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info) { - return Value(Object{{"family", cpu_info.family}, - {"model", cpu_info.model}, - {"stepping", cpu_info.stepping}, - {"vendor", cpu_info.vendor}}); -} - -} // namespace json -} // namespace llvm diff --git a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h deleted file mode 100644 index b2667a88222..00000000000 --- a/gnu/llvm/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h +++ /dev/null @@ -1,88 +0,0 @@ -//===-- TraceIntelPTSessionFileParser.h -----------------------*- C++ //-*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H -#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H - -#include "TraceIntelPT.h" - -#include "../common/TraceSessionFileParser.h" - -namespace lldb_private { -namespace trace_intel_pt { - -class TraceIntelPT; - -class TraceIntelPTSessionFileParser : public TraceSessionFileParser { -public: - struct JSONTraceIntelPTCPUInfo { - int64_t family; - int64_t model; - int64_t stepping; - std::string vendor; - }; - - struct JSONTraceIntelPTSettings - : TraceSessionFileParser::JSONTracePluginSettings { - JSONTraceIntelPTCPUInfo cpuInfo; - }; - - /// See \a TraceSessionFileParser::TraceSessionFileParser for the description - /// of these fields. - TraceIntelPTSessionFileParser(Debugger &debugger, - const llvm::json::Value &trace_session_file, - llvm::StringRef session_file_dir) - : TraceSessionFileParser(debugger, session_file_dir, GetSchema()), - m_trace_session_file(trace_session_file) {} - - /// \return - /// The JSON schema for the session data. - static llvm::StringRef GetSchema(); - - /// Parse the structured data trace session and create the corresponding \a - /// Target objects. In case of an error, no targets are created. - /// - /// \return - /// A \a lldb::TraceSP instance with the trace session data. In case of - /// errors, return a null pointer. - llvm::Expected Parse(); - - lldb::TraceSP - CreateTraceIntelPTInstance(const pt_cpu &cpu_info, - std::vector &parsed_processes); - -private: - static pt_cpu ParsePTCPU(const JSONTraceIntelPTCPUInfo &cpu_info); - - const llvm::json::Value &m_trace_session_file; -}; - -} // namespace trace_intel_pt -} // namespace lldb_private - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, - lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: - JSONTraceIntelPTSettings &plugin_settings, - Path path); - -bool fromJSON(const llvm::json::Value &value, - lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: - JSONTraceIntelPTCPUInfo &packet, - llvm::json::Path path); - -llvm::json::Value -toJSON(const lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: - JSONTraceIntelPTCPUInfo &packet); - -} // namespace json -} // namespace llvm - -#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp index 8e68f75020b..888dd156660 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp @@ -24,11 +24,12 @@ x86AssemblyInspectionEngine::x86AssemblyInspectionEngine(const ArchSpec &arch) : m_cur_insn(nullptr), m_machine_ip_regnum(LLDB_INVALID_REGNUM), m_machine_sp_regnum(LLDB_INVALID_REGNUM), m_machine_fp_regnum(LLDB_INVALID_REGNUM), + m_machine_alt_fp_regnum(LLDB_INVALID_REGNUM), m_lldb_ip_regnum(LLDB_INVALID_REGNUM), m_lldb_sp_regnum(LLDB_INVALID_REGNUM), m_lldb_fp_regnum(LLDB_INVALID_REGNUM), - - m_reg_map(), m_arch(arch), m_cpu(k_cpu_unspecified), m_wordsize(-1), + m_lldb_alt_fp_regnum(LLDB_INVALID_REGNUM), m_reg_map(), m_arch(arch), + m_cpu(k_cpu_unspecified), m_wordsize(-1), m_register_map_initialized(false), m_disasm_context() { m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), nullptr, @@ -681,10 +682,6 @@ bool x86AssemblyInspectionEngine::jmp_to_reg_p() { // The second byte is a ModR/M /4 byte, strip off the registers uint8_t second_byte_sans_reg = *(m_cur_insn + 1) & ~7; - // Don't handle 0x24 disp32, because the target address is - // knowable statically - pc_rel_branch_or_jump_p() will - // return the target address. - // [reg] if (second_byte_sans_reg == 0x20) return true; @@ -701,17 +698,6 @@ bool x86AssemblyInspectionEngine::jmp_to_reg_p() { if (second_byte_sans_reg == 0xe0) return true; - // disp32 - // jumps to an address stored in memory, the value can't be cached - // in an unwind plan. - if (second_byte_sans_reg == 0x24) - return true; - - // use SIB byte - // ff 24 fe jmpq *(%rsi,%rdi,8) - if (second_byte_sans_reg == 0x24) - return true; - return false; } @@ -977,9 +963,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( // path jumps over the mid-function epilogue UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI - int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the + int prologue_completed_sp_bytes_offset_from_cfa = 0; // The sp value before the // epilogue started executed - bool prologue_completed_is_aligned; + bool prologue_completed_is_aligned = false; std::vector prologue_completed_saved_registers; while (current_func_text_offset < size) { diff --git a/gnu/llvm/lldb/source/Target/TraceInstructionDumper.cpp b/gnu/llvm/lldb/source/Target/TraceInstructionDumper.cpp deleted file mode 100644 index dc1e86481c3..00000000000 --- a/gnu/llvm/lldb/source/Target/TraceInstructionDumper.cpp +++ /dev/null @@ -1,292 +0,0 @@ -//===-- TraceInstructionDumper.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 "lldb/Target/TraceInstructionDumper.h" - -#include "lldb/Core/Module.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/SectionLoadList.h" - -using namespace lldb; -using namespace lldb_private; -using namespace llvm; - -TraceInstructionDumper::TraceInstructionDumper(lldb::TraceCursorUP &&cursor_up, - int initial_index, bool raw, - bool show_tsc) - : m_cursor_up(std::move(cursor_up)), m_index(initial_index), m_raw(raw), - m_show_tsc(show_tsc) {} - -/// \return -/// Return \b true if the cursor could move one step. -bool TraceInstructionDumper::TryMoveOneStep() { - if (!m_cursor_up->Next()) { - SetNoMoreData(); - return false; - } - m_index += m_cursor_up->IsForwards() ? 1 : -1; - return true; -} - -/// \return -/// The number of characters that would be needed to print the given -/// integer. -static int GetNumberOfChars(int num) { - if (num == 0) - return 1; - return (num < 0 ? 1 : 0) + static_cast(log10(abs(num))) + 1; -} - -/// Helper struct that holds symbol, disassembly and address information of an -/// instruction. -struct InstructionSymbolInfo { - SymbolContext sc; - Address address; - lldb::addr_t load_address; - lldb::DisassemblerSP disassembler; - lldb::InstructionSP instruction; - lldb_private::ExecutionContext exe_ctx; -}; - -// This custom LineEntry validator is neded because some line_entries have -// 0 as line, which is meaningless. Notice that LineEntry::IsValid only -// checks that line is not LLDB_INVALID_LINE_NUMBER, i.e. UINT32_MAX. -static bool IsLineEntryValid(const LineEntry &line_entry) { - return line_entry.IsValid() && line_entry.line > 0; -} - -/// \return -/// \b true if the provided line entries match line, column and source file. -/// This function assumes that the line entries are valid. -static bool FileLineAndColumnMatches(const LineEntry &a, const LineEntry &b) { - if (a.line != b.line) - return false; - if (a.column != b.column) - return false; - return a.file == b.file; -} - -/// Compare the symbol contexts of the provided \a InstructionSymbolInfo -/// objects. -/// -/// \return -/// \a true if both instructions belong to the same scope level analized -/// in the following order: -/// - module -/// - symbol -/// - function -/// - line -static bool -IsSameInstructionSymbolContext(const InstructionSymbolInfo &prev_insn, - const InstructionSymbolInfo &insn) { - // module checks - if (insn.sc.module_sp != prev_insn.sc.module_sp) - return false; - - // symbol checks - if (insn.sc.symbol != prev_insn.sc.symbol) - return false; - - // function checks - if (!insn.sc.function && !prev_insn.sc.function) - return true; - else if (insn.sc.function != prev_insn.sc.function) - return false; - - // line entry checks - const bool curr_line_valid = IsLineEntryValid(insn.sc.line_entry); - const bool prev_line_valid = IsLineEntryValid(prev_insn.sc.line_entry); - if (curr_line_valid && prev_line_valid) - return FileLineAndColumnMatches(insn.sc.line_entry, - prev_insn.sc.line_entry); - return curr_line_valid == prev_line_valid; -} - -/// Dump the symbol context of the given instruction address if it's different -/// from the symbol context of the previous instruction in the trace. -/// -/// \param[in] prev_sc -/// The symbol context of the previous instruction in the trace. -/// -/// \param[in] address -/// The address whose symbol information will be dumped. -/// -/// \return -/// The symbol context of the current address, which might differ from the -/// previous one. -static void -DumpInstructionSymbolContext(Stream &s, - Optional prev_insn, - InstructionSymbolInfo &insn) { - if (prev_insn && IsSameInstructionSymbolContext(*prev_insn, insn)) - return; - - s.Printf(" "); - - if (!insn.sc.module_sp) - s.Printf("(none)"); - else if (!insn.sc.function && !insn.sc.symbol) - s.Printf("%s`(none)", - insn.sc.module_sp->GetFileSpec().GetFilename().AsCString()); - else - insn.sc.DumpStopContext(&s, insn.exe_ctx.GetTargetPtr(), insn.address, - /*show_fullpath=*/false, - /*show_module=*/true, /*show_inlined_frames=*/false, - /*show_function_arguments=*/true, - /*show_function_name=*/true); - s.Printf("\n"); -} - -static void DumpInstructionDisassembly(Stream &s, InstructionSymbolInfo &insn) { - if (!insn.instruction) - return; - s.Printf(" "); - insn.instruction->Dump(&s, /*show_address=*/false, /*show_bytes=*/false, - /*max_opcode_byte_size=*/0, &insn.exe_ctx, &insn.sc, - /*prev_sym_ctx=*/nullptr, - /*disassembly_addr_format=*/nullptr, - /*max_address_text_size=*/0); -} - -void TraceInstructionDumper::SetNoMoreData() { m_no_more_data = true; } - -bool TraceInstructionDumper::HasMoreData() { return !m_no_more_data; } - -void TraceInstructionDumper::DumpInstructions(Stream &s, size_t count) { - ThreadSP thread_sp = m_cursor_up->GetExecutionContextRef().GetThreadSP(); - if (!thread_sp) { - s.Printf("invalid thread"); - return; - } - - s.Printf("thread #%u: tid = %" PRIu64 "\n", thread_sp->GetIndexID(), - thread_sp->GetID()); - - int digits_count = GetNumberOfChars( - m_cursor_up->IsForwards() ? m_index + count - 1 : m_index - count + 1); - bool was_prev_instruction_an_error = false; - - auto printMissingInstructionsMessage = [&]() { - s.Printf(" ...missing instructions\n"); - }; - - auto printInstructionIndex = [&]() { - s.Printf(" [%*d] ", digits_count, m_index); - - if (m_show_tsc) { - s.Printf("[tsc="); - - if (Optional timestamp = m_cursor_up->GetTimestampCounter()) - s.Printf("0x%016" PRIx64, *timestamp); - else - s.Printf("unavailable"); - - s.Printf("] "); - } - }; - - InstructionSymbolInfo prev_insn_info; - - Target &target = thread_sp->GetProcess()->GetTarget(); - ExecutionContext exe_ctx; - target.CalculateExecutionContext(exe_ctx); - const ArchSpec &arch = target.GetArchitecture(); - - // Find the symbol context for the given address reusing the previous - // instruction's symbol context when possible. - auto calculateSymbolContext = [&](const Address &address) { - AddressRange range; - if (prev_insn_info.sc.GetAddressRange(eSymbolContextEverything, 0, - /*inline_block_range*/ false, - range) && - range.Contains(address)) - return prev_insn_info.sc; - - SymbolContext sc; - address.CalculateSymbolContext(&sc, eSymbolContextEverything); - return sc; - }; - - // Find the disassembler for the given address reusing the previous - // instruction's disassembler when possible. - auto calculateDisass = [&](const Address &address, const SymbolContext &sc) { - if (prev_insn_info.disassembler) { - if (InstructionSP instruction = - prev_insn_info.disassembler->GetInstructionList() - .GetInstructionAtAddress(address)) - return std::make_tuple(prev_insn_info.disassembler, instruction); - } - - if (sc.function) { - if (DisassemblerSP disassembler = - sc.function->GetInstructions(exe_ctx, nullptr)) { - if (InstructionSP instruction = - disassembler->GetInstructionList().GetInstructionAtAddress( - address)) - return std::make_tuple(disassembler, instruction); - } - } - // We fallback to a single instruction disassembler - AddressRange range(address, arch.GetMaximumOpcodeByteSize()); - DisassemblerSP disassembler = - Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr, - /*flavor*/ nullptr, target, range); - return std::make_tuple(disassembler, - disassembler ? disassembler->GetInstructionList() - .GetInstructionAtAddress(address) - : InstructionSP()); - }; - - for (size_t i = 0; i < count; i++) { - if (!HasMoreData()) { - s.Printf(" no more data\n"); - break; - } - - if (Error err = m_cursor_up->GetError()) { - if (!m_cursor_up->IsForwards() && !was_prev_instruction_an_error) - printMissingInstructionsMessage(); - - was_prev_instruction_an_error = true; - - printInstructionIndex(); - s << toString(std::move(err)); - } else { - if (m_cursor_up->IsForwards() && was_prev_instruction_an_error) - printMissingInstructionsMessage(); - - was_prev_instruction_an_error = false; - - InstructionSymbolInfo insn_info; - - if (!m_raw) { - insn_info.load_address = m_cursor_up->GetLoadAddress(); - insn_info.exe_ctx = exe_ctx; - insn_info.address.SetLoadAddress(insn_info.load_address, &target); - insn_info.sc = calculateSymbolContext(insn_info.address); - std::tie(insn_info.disassembler, insn_info.instruction) = - calculateDisass(insn_info.address, insn_info.sc); - - DumpInstructionSymbolContext(s, prev_insn_info, insn_info); - } - - printInstructionIndex(); - s.Printf("0x%016" PRIx64, m_cursor_up->GetLoadAddress()); - - if (!m_raw) - DumpInstructionDisassembly(s, insn_info); - - prev_insn_info = insn_info; - } - - s.Printf("\n"); - TryMoveOneStep(); - } -} diff --git a/gnu/llvm/lldb/source/Target/UnixSignals.cpp b/gnu/llvm/lldb/source/Target/UnixSignals.cpp index 003d60debc0..652e2bbb07d 100644 --- a/gnu/llvm/lldb/source/Target/UnixSignals.cpp +++ b/gnu/llvm/lldb/source/Target/UnixSignals.cpp @@ -13,17 +13,20 @@ #include "Plugins/Process/Utility/NetBSDSignals.h" #include "Plugins/Process/Utility/OpenBSDSignals.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/ArchSpec.h" +#include using namespace lldb_private; +using namespace llvm; UnixSignals::Signal::Signal(const char *name, bool default_suppress, bool default_stop, bool default_notify, const char *description, const char *alias) : m_name(name), m_alias(alias), m_description(), m_suppress(default_suppress), m_stop(default_stop), - m_notify(default_notify) { + m_notify(default_notify), + m_default_suppress(default_suppress), m_default_stop(default_stop), + m_default_notify(default_notify) { if (description) m_description.assign(description); } @@ -158,9 +161,8 @@ int32_t UnixSignals::GetSignalNumberFromName(const char *name) const { return pos->first; } - const int32_t signo = - StringConvert::ToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0); - if (signo != LLDB_INVALID_SIGNAL_NUMBER) + int32_t signo; + if (llvm::to_integer(name, signo)) return signo; return LLDB_INVALID_SIGNAL_NUMBER; } @@ -286,9 +288,9 @@ int32_t UnixSignals::GetSignalAtIndex(int32_t index) const { uint64_t UnixSignals::GetVersion() const { return m_version; } std::vector -UnixSignals::GetFilteredSignals(llvm::Optional should_suppress, - llvm::Optional should_stop, - llvm::Optional should_notify) { +UnixSignals::GetFilteredSignals(std::optional should_suppress, + std::optional should_stop, + std::optional should_notify) { std::vector result; for (int32_t signo = GetFirstSignalNumber(); signo != LLDB_INVALID_SIGNAL_NUMBER; @@ -301,14 +303,13 @@ UnixSignals::GetFilteredSignals(llvm::Optional should_suppress, // If any of filtering conditions are not met, we move on to the next // signal. - if (should_suppress.hasValue() && - signal_suppress != should_suppress.getValue()) + if (should_suppress && signal_suppress != *should_suppress) continue; - if (should_stop.hasValue() && signal_stop != should_stop.getValue()) + if (should_stop && signal_stop != *should_stop) continue; - if (should_notify.hasValue() && signal_notify != should_notify.getValue()) + if (should_notify && signal_notify != *should_notify) continue; result.push_back(signo); @@ -316,3 +317,40 @@ UnixSignals::GetFilteredSignals(llvm::Optional should_suppress, return result; } + +void UnixSignals::IncrementSignalHitCount(int signo) { + collection::iterator pos = m_signals.find(signo); + if (pos != m_signals.end()) + pos->second.m_hit_count += 1; +} + +json::Value UnixSignals::GetHitCountStatistics() const { + json::Array json_signals; + for (const auto &pair: m_signals) { + if (pair.second.m_hit_count > 0) + json_signals.emplace_back(json::Object{ + { pair.second.m_name.GetCString(), pair.second.m_hit_count } + }); + } + return std::move(json_signals); +} + +void UnixSignals::Signal::Reset(bool reset_stop, bool reset_notify, + bool reset_suppress) { + if (reset_stop) + m_stop = m_default_stop; + if (reset_notify) + m_notify = m_default_notify; + if (reset_suppress) + m_suppress = m_default_suppress; +} + +bool UnixSignals::ResetSignal(int32_t signo, bool reset_stop, + bool reset_notify, bool reset_suppress) { + auto elem = m_signals.find(signo); + if (elem == m_signals.end()) + return false; + (*elem).second.Reset(reset_stop, reset_notify, reset_suppress); + return true; +} + diff --git a/gnu/llvm/lldb/source/Utility/ArchSpec.cpp b/gnu/llvm/lldb/source/Utility/ArchSpec.cpp index f2d8f857e9b..6d9fb786dd8 100644 --- a/gnu/llvm/lldb/source/Utility/ArchSpec.cpp +++ b/gnu/llvm/lldb/source/Utility/ArchSpec.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StringList.h" @@ -15,6 +16,7 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/Compiler.h" using namespace lldb; @@ -221,6 +223,11 @@ static const CoreDefinition g_core_definitions[] = { {eByteOrderLittle, 8, 2, 4, llvm::Triple::riscv64, ArchSpec::eCore_riscv64, "riscv64"}, + {eByteOrderLittle, 4, 4, 4, llvm::Triple::loongarch32, + ArchSpec::eCore_loongarch32, "loongarch32"}, + {eByteOrderLittle, 8, 4, 4, llvm::Triple::loongarch64, + ArchSpec::eCore_loongarch64, "loongarch64"}, + {eByteOrderLittle, 4, 4, 4, llvm::Triple::UnknownArch, ArchSpec::eCore_uknownMach32, "unknown-mach-32"}, {eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch, @@ -256,13 +263,13 @@ struct ArchDefinition { }; void ArchSpec::ListSupportedArchNames(StringList &list) { - for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) - list.AppendString(g_core_definitions[i].name); + for (const auto &def : g_core_definitions) + list.AppendString(def.name); } void ArchSpec::AutoComplete(CompletionRequest &request) { - for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) - request.TryCompleteCurrentArg(g_core_definitions[i].name); + for (const auto &def : g_core_definitions) + request.TryCompleteCurrentArg(def.name); } #define CPU_ANY (UINT32_MAX) @@ -341,9 +348,9 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = { {ArchSpec::eCore_uknownMach64, llvm::MachO::CPU_ARCH_ABI64, 0, 0xFF000000u, 0x00000000u}}; // clang-format on -static const ArchDefinition g_macho_arch_def = { - eArchTypeMachO, llvm::array_lengthof(g_macho_arch_entries), - g_macho_arch_entries, "mach-o"}; +static const ArchDefinition g_macho_arch_def = {eArchTypeMachO, + std::size(g_macho_arch_entries), + g_macho_arch_entries, "mach-o"}; //===----------------------------------------------------------------------===// // A table that gets searched linearly for matches. This table is used to @@ -359,10 +366,10 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel MCU // FIXME: is this correct? {ArchSpec::eCore_ppc_generic, llvm::ELF::EM_PPC, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC - {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le - {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64 + {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, + ArchSpec::eCore_ppc64le_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le + {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, + ArchSpec::eCore_ppc64_generic, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64 {ArchSpec::eCore_arm_generic, llvm::ELF::EM_ARM, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM {ArchSpec::eCore_arm_aarch64, llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, @@ -401,17 +408,23 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC - {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, - 0xFFFFFFFFu, 0xFFFFFFFFu}, // AVR + {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // AVR {ArchSpec::eCore_riscv32, llvm::ELF::EM_RISCV, ArchSpec::eRISCVSubType_riscv32, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv32 {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV, ArchSpec::eRISCVSubType_riscv64, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv64 + {ArchSpec::eCore_loongarch32, llvm::ELF::EM_LOONGARCH, + ArchSpec::eLoongArchSubType_loongarch32, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // loongarch32 + {ArchSpec::eCore_loongarch64, llvm::ELF::EM_LOONGARCH, + ArchSpec::eLoongArchSubType_loongarch64, 0xFFFFFFFFu, + 0xFFFFFFFFu}, // loongarch64 }; static const ArchDefinition g_elf_arch_def = { eArchTypeELF, - llvm::array_lengthof(g_elf_arch_entries), + std::size(g_elf_arch_entries), g_elf_arch_entries, "elf", }; @@ -437,7 +450,7 @@ static const ArchDefinitionEntry g_coff_arch_entries[] = { static const ArchDefinition g_coff_arch_def = { eArchTypeCOFF, - llvm::array_lengthof(g_coff_arch_entries), + std::size(g_coff_arch_entries), g_coff_arch_entries, "pe-coff", }; @@ -447,16 +460,12 @@ static const ArchDefinition g_coff_arch_def = { static const ArchDefinition *g_arch_definitions[] = { &g_macho_arch_def, &g_elf_arch_def, &g_coff_arch_def}; -static const size_t k_num_arch_definitions = - llvm::array_lengthof(g_arch_definitions); - //===----------------------------------------------------------------------===// // Static helper functions. // Get the architecture definition for a given object type. static const ArchDefinition *FindArchDefinition(ArchitectureType arch_type) { - for (unsigned int i = 0; i < k_num_arch_definitions; ++i) { - const ArchDefinition *def = g_arch_definitions[i]; + for (const ArchDefinition *def : g_arch_definitions) { if (def->type == arch_type) return def; } @@ -465,15 +474,15 @@ static const ArchDefinition *FindArchDefinition(ArchitectureType arch_type) { // Get an architecture definition by name. static const CoreDefinition *FindCoreDefinition(llvm::StringRef name) { - for (unsigned int i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { - if (name.equals_insensitive(g_core_definitions[i].name)) - return &g_core_definitions[i]; + for (const auto &def : g_core_definitions) { + if (name.equals_insensitive(def.name)) + return &def; } return nullptr; } static inline const CoreDefinition *FindCoreDefinition(ArchSpec::Core core) { - if (core < llvm::array_lengthof(g_core_definitions)) + if (core < std::size(g_core_definitions)) return &g_core_definitions[core]; return nullptr; } @@ -584,7 +593,6 @@ void ArchSpec::SetFlags(const std::string &elf_abi) { std::string ArchSpec::GetClangTargetCPU() const { std::string cpu; - if (IsMIPS()) { switch (m_core) { case ArchSpec::eCore_mips32: @@ -631,6 +639,9 @@ std::string ArchSpec::GetClangTargetCPU() const { break; } } + + if (GetTriple().isARM()) + cpu = llvm::ARM::getARMCPUForArch(GetTriple(), "").str(); return cpu; } @@ -904,7 +915,7 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, m_triple.setArch(core_def->machine); } } else { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_PLATFORM)); + Log *log(GetLog(LLDBLog::Target | LLDBLog::Process | LLDBLog::Platform)); LLDB_LOGF(log, "Unable to find a core definition for cpu 0x%" PRIx32 " sub %" PRId32, @@ -929,14 +940,6 @@ uint32_t ArchSpec::GetMaximumOpcodeByteSize() const { return 0; } -bool ArchSpec::IsExactMatch(const ArchSpec &rhs) const { - return IsEqualTo(rhs, true); -} - -bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const { - return IsEqualTo(rhs, false); -} - static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs) { if (lhs == rhs) @@ -968,11 +971,11 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, return false; } -bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { +bool ArchSpec::IsMatch(const ArchSpec &rhs, MatchType match) const { // explicitly ignoring m_distribution_id in this method. if (GetByteOrder() != rhs.GetByteOrder() || - !cores_match(GetCore(), rhs.GetCore(), true, exact_match)) + !cores_match(GetCore(), rhs.GetCore(), true, match == ExactMatch)) return false; const llvm::Triple &lhs_triple = GetTriple(); @@ -980,7 +983,16 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor(); const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor(); - if (lhs_triple_vendor != rhs_triple_vendor) { + + const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS(); + const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS(); + + bool both_windows = lhs_triple.isOSWindows() && rhs_triple.isOSWindows(); + + // On Windows, the vendor field doesn't have any practical effect, but + // it is often set to either "pc" or "w64". + if ((lhs_triple_vendor != rhs_triple_vendor) && + (match == ExactMatch || !both_windows)) { const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified(); const bool lhs_vendor_specified = TripleVendorWasSpecified(); // Both architectures had the vendor specified, so if they aren't equal @@ -994,14 +1006,12 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { return false; } - const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS(); - const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS(); const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment(); const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment(); - if (!exact_match) { + if (match == CompatibleMatch) { // x86_64-apple-ios-macabi, x86_64-apple-macosx are compatible, no match. if ((lhs_triple_os == llvm::Triple::IOS && lhs_triple_env == llvm::Triple::MacABI && @@ -1028,11 +1038,15 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { return false; // If the pair of os+env is both unspecified, match any other os+env combo. - if (!exact_match && ((!lhs_os_specified && !lhs_triple.hasEnvironment()) || - (!rhs_os_specified && !rhs_triple.hasEnvironment()))) + if (match == CompatibleMatch && + ((!lhs_os_specified && !lhs_triple.hasEnvironment()) || + (!rhs_os_specified && !rhs_triple.hasEnvironment()))) return true; } + if (match == CompatibleMatch && both_windows) + return true; // The Windows environments (MSVC vs GNU) are compatible + return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env); } @@ -1081,7 +1095,7 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, case ArchSpec::eCore_arm_generic: if (enforce_exact_match) break; - LLVM_FALLTHROUGH; + [[fallthrough]]; case ArchSpec::kCore_arm_any: if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last) return true; @@ -1405,23 +1419,18 @@ bool lldb_private::operator==(const ArchSpec &lhs, const ArchSpec &rhs) { } bool ArchSpec::IsFullySpecifiedTriple() const { - const auto &user_specified_triple = GetTriple(); - - bool user_triple_fully_specified = false; - - if ((user_specified_triple.getOS() != llvm::Triple::UnknownOS) || - TripleOSWasSpecified()) { - if ((user_specified_triple.getVendor() != llvm::Triple::UnknownVendor) || - TripleVendorWasSpecified()) { - const unsigned unspecified = 0; - if (!user_specified_triple.isOSDarwin() || - user_specified_triple.getOSMajorVersion() != unspecified) { - user_triple_fully_specified = true; - } - } - } + if (!TripleOSWasSpecified()) + return false; + + if (!TripleVendorWasSpecified()) + return false; - return user_triple_fully_specified; + const unsigned unspecified = 0; + const llvm::Triple &triple = GetTriple(); + if (triple.isOSDarwin() && triple.getOSMajorVersion() == unspecified) + return false; + + return true; } void ArchSpec::PiecewiseTripleCompare( @@ -1482,15 +1491,3 @@ void ArchSpec::DumpTriple(llvm::raw_ostream &s) const { if (!environ_str.empty()) s << "-" << environ_str; } - -void llvm::yaml::ScalarTraits::output(const ArchSpec &Val, void *, - raw_ostream &Out) { - Val.DumpTriple(Out); -} - -llvm::StringRef -llvm::yaml::ScalarTraits::input(llvm::StringRef Scalar, void *, - ArchSpec &Val) { - Val = ArchSpec(Scalar); - return {}; -} diff --git a/gnu/llvm/lldb/source/Utility/Logging.cpp b/gnu/llvm/lldb/source/Utility/Logging.cpp deleted file mode 100644 index 4648bec502c..00000000000 --- a/gnu/llvm/lldb/source/Utility/Logging.cpp +++ /dev/null @@ -1,64 +0,0 @@ -//===-- Logging.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 "lldb/Utility/Logging.h" -#include "lldb/Utility/Log.h" - -#include "llvm/ADT/ArrayRef.h" - -#include - -using namespace lldb_private; - -static constexpr Log::Category g_categories[] = { - {{"api"}, {"log API calls and return values"}, LIBLLDB_LOG_API}, - {{"ast"}, {"log AST"}, LIBLLDB_LOG_AST}, - {{"break"}, {"log breakpoints"}, LIBLLDB_LOG_BREAKPOINTS}, - {{"commands"}, {"log command argument parsing"}, LIBLLDB_LOG_COMMANDS}, - {{"comm"}, {"log communication activities"}, LIBLLDB_LOG_COMMUNICATION}, - {{"conn"}, {"log connection details"}, LIBLLDB_LOG_CONNECTION}, - {{"demangle"}, {"log mangled names to catch demangler crashes"}, LIBLLDB_LOG_DEMANGLE}, - {{"dyld"}, {"log shared library related activities"}, LIBLLDB_LOG_DYNAMIC_LOADER}, - {{"event"}, {"log broadcaster, listener and event queue activities"}, LIBLLDB_LOG_EVENTS}, - {{"expr"}, {"log expressions"}, LIBLLDB_LOG_EXPRESSIONS}, - {{"formatters"}, {"log data formatters related activities"}, LIBLLDB_LOG_DATAFORMATTERS}, - {{"host"}, {"log host activities"}, LIBLLDB_LOG_HOST}, - {{"jit"}, {"log JIT events in the target"}, LIBLLDB_LOG_JIT_LOADER}, - {{"language"}, {"log language runtime events"}, LIBLLDB_LOG_LANGUAGE}, - {{"mmap"}, {"log mmap related activities"}, LIBLLDB_LOG_MMAP}, - {{"module"}, {"log module activities such as when modules are created, destroyed, replaced, and more"}, LIBLLDB_LOG_MODULES}, - {{"object"}, {"log object construction/destruction for important objects"}, LIBLLDB_LOG_OBJECT}, - {{"os"}, {"log OperatingSystem plugin related activities"}, LIBLLDB_LOG_OS}, - {{"platform"}, {"log platform events and activities"}, LIBLLDB_LOG_PLATFORM}, - {{"process"}, {"log process events and activities"}, LIBLLDB_LOG_PROCESS}, - {{"script"}, {"log events about the script interpreter"}, LIBLLDB_LOG_SCRIPT}, - {{"state"}, {"log private and public process state changes"}, LIBLLDB_LOG_STATE}, - {{"step"}, {"log step related activities"}, LIBLLDB_LOG_STEP}, - {{"symbol"}, {"log symbol related issues and warnings"}, LIBLLDB_LOG_SYMBOLS}, - {{"system-runtime"}, {"log system runtime events"}, LIBLLDB_LOG_SYSTEM_RUNTIME}, - {{"target"}, {"log target events and activities"}, LIBLLDB_LOG_TARGET}, - {{"temp"}, {"log internal temporary debug messages"}, LIBLLDB_LOG_TEMPORARY}, - {{"thread"}, {"log thread events and activities"}, LIBLLDB_LOG_THREAD}, - {{"types"}, {"log type system related activities"}, LIBLLDB_LOG_TYPES}, - {{"unwind"}, {"log stack unwind activities"}, LIBLLDB_LOG_UNWIND}, - {{"watch"}, {"log watchpoint related activities"}, LIBLLDB_LOG_WATCHPOINTS}, -}; - -static Log::Channel g_log_channel(g_categories, LIBLLDB_LOG_DEFAULT); - -void lldb_private::InitializeLldbChannel() { - Log::Register("lldb", g_log_channel); -} - -Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) { - return g_log_channel.GetLogIfAll(mask); -} - -Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) { - return g_log_channel.GetLogIfAny(mask); -} diff --git a/gnu/llvm/lldb/source/Utility/Reproducer.cpp b/gnu/llvm/lldb/source/Utility/Reproducer.cpp deleted file mode 100644 index b63863c535f..00000000000 --- a/gnu/llvm/lldb/source/Utility/Reproducer.cpp +++ /dev/null @@ -1,402 +0,0 @@ -//===-- Reproducer.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 "lldb/Utility/Reproducer.h" -#include "lldb/Utility/LLDBAssert.h" -#include "lldb/Utility/ReproducerProvider.h" -#include "lldb/Utility/Timer.h" - -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Threading.h" -#include "llvm/Support/raw_ostream.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace llvm; -using namespace llvm::yaml; - -Reproducer &Reproducer::Instance() { return *InstanceImpl(); } - -llvm::Error Reproducer::Initialize(ReproducerMode mode, - llvm::Optional root) { - lldbassert(!InstanceImpl() && "Already initialized."); - InstanceImpl().emplace(); - - switch (mode) { - case ReproducerMode::Capture: { - if (!root) { - SmallString<128> repro_dir; - auto ec = sys::fs::createUniqueDirectory("reproducer", repro_dir); - if (ec) - return make_error( - "unable to create unique reproducer directory", ec); - root.emplace(repro_dir); - } else { - auto ec = sys::fs::create_directory(root->GetPath()); - if (ec) - return make_error("unable to create reproducer directory", - ec); - } - return Instance().SetCapture(root); - } break; - case ReproducerMode::Replay: - return Instance().SetReplay(root, /*passive*/ false); - case ReproducerMode::PassiveReplay: - return Instance().SetReplay(root, /*passive*/ true); - case ReproducerMode::Off: - break; - }; - - return Error::success(); -} - -void Reproducer::Initialize() { - llvm::cantFail(Initialize(repro::ReproducerMode::Off, llvm::None)); -} - -bool Reproducer::Initialized() { return InstanceImpl().operator bool(); } - -void Reproducer::Terminate() { - lldbassert(InstanceImpl() && "Already terminated."); - InstanceImpl().reset(); -} - -Optional &Reproducer::InstanceImpl() { - static Optional g_reproducer; - return g_reproducer; -} - -const Generator *Reproducer::GetGenerator() const { - std::lock_guard guard(m_mutex); - if (m_generator) - return &(*m_generator); - return nullptr; -} - -const Loader *Reproducer::GetLoader() const { - std::lock_guard guard(m_mutex); - if (m_loader) - return &(*m_loader); - return nullptr; -} - -Generator *Reproducer::GetGenerator() { - std::lock_guard guard(m_mutex); - if (m_generator) - return &(*m_generator); - return nullptr; -} - -Loader *Reproducer::GetLoader() { - std::lock_guard guard(m_mutex); - if (m_loader) - return &(*m_loader); - return nullptr; -} - -llvm::Error Reproducer::SetCapture(llvm::Optional root) { - std::lock_guard guard(m_mutex); - - if (root && m_loader) - return make_error( - "cannot generate a reproducer when replay one", - inconvertibleErrorCode()); - - if (!root) { - m_generator.reset(); - return Error::success(); - } - - m_generator.emplace(*root); - return Error::success(); -} - -llvm::Error Reproducer::SetReplay(llvm::Optional root, bool passive) { - std::lock_guard guard(m_mutex); - - if (root && m_generator) - return make_error( - "cannot replay a reproducer when generating one", - inconvertibleErrorCode()); - - if (!root) { - m_loader.reset(); - return Error::success(); - } - - m_loader.emplace(*root, passive); - if (auto e = m_loader->LoadIndex()) - return e; - - return Error::success(); -} - -FileSpec Reproducer::GetReproducerPath() const { - if (auto g = GetGenerator()) - return g->GetRoot(); - if (auto l = GetLoader()) - return l->GetRoot(); - return {}; -} - -static FileSpec MakeAbsolute(const FileSpec &file_spec) { - SmallString<128> path; - file_spec.GetPath(path, false); - llvm::sys::fs::make_absolute(path); - return FileSpec(path, file_spec.GetPathStyle()); -} - -Generator::Generator(FileSpec root) : m_root(MakeAbsolute(std::move(root))) { - GetOrCreate(); - GetOrCreate(); -} - -Generator::~Generator() { - if (!m_done) { - if (m_auto_generate) { - Keep(); - llvm::cantFail(Finalize(GetRoot())); - } else { - Discard(); - } - } -} - -ProviderBase *Generator::Register(std::unique_ptr provider) { - std::lock_guard lock(m_providers_mutex); - std::pair> key_value( - provider->DynamicClassID(), std::move(provider)); - auto e = m_providers.insert(std::move(key_value)); - return e.first->getSecond().get(); -} - -void Generator::Keep() { - LLDB_SCOPED_TIMER(); - assert(!m_done); - m_done = true; - - for (auto &provider : m_providers) - provider.second->Keep(); - - AddProvidersToIndex(); -} - -void Generator::Discard() { - LLDB_SCOPED_TIMER(); - assert(!m_done); - m_done = true; - - for (auto &provider : m_providers) - provider.second->Discard(); - - llvm::sys::fs::remove_directories(m_root.GetPath()); -} - -void Generator::SetAutoGenerate(bool b) { m_auto_generate = b; } - -bool Generator::IsAutoGenerate() const { return m_auto_generate; } - -const FileSpec &Generator::GetRoot() const { return m_root; } - -void Generator::AddProvidersToIndex() { - FileSpec index = m_root; - index.AppendPathComponent("index.yaml"); - - std::error_code EC; - auto strm = std::make_unique(index.GetPath(), EC, - sys::fs::OpenFlags::OF_None); - yaml::Output yout(*strm); - - std::vector files; - files.reserve(m_providers.size()); - for (auto &provider : m_providers) { - files.emplace_back(provider.second->GetFile()); - } - - yout << files; -} - -Loader::Loader(FileSpec root, bool passive) - : m_root(MakeAbsolute(std::move(root))), m_loaded(false), - m_passive_replay(passive) {} - -llvm::Error Loader::LoadIndex() { - if (m_loaded) - return llvm::Error::success(); - - FileSpec index = m_root.CopyByAppendingPathComponent("index.yaml"); - - auto error_or_file = MemoryBuffer::getFile(index.GetPath()); - if (auto err = error_or_file.getError()) - return make_error("unable to load reproducer index", err); - - yaml::Input yin((*error_or_file)->getBuffer()); - yin >> m_files; - if (auto err = yin.error()) - return make_error("unable to read reproducer index", err); - - // Sort files to speed up search. - llvm::sort(m_files); - - // Remember that we've loaded the index. - m_loaded = true; - - return llvm::Error::success(); -} - -bool Loader::HasFile(StringRef file) { - assert(m_loaded); - auto it = std::lower_bound(m_files.begin(), m_files.end(), file.str()); - return (it != m_files.end()) && (*it == file); -} - -void Verifier::Verify( - llvm::function_ref error_callback, - llvm::function_ref warning_callback, - llvm::function_ref note_callack) const { - if (!m_loader) { - error_callback("invalid loader"); - return; - } - - FileSpec vfs_mapping = m_loader->GetFile(); - ErrorOr> buffer = - vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath()); - if (!buffer) { - error_callback("unable to read files: " + buffer.getError().message()); - return; - } - - IntrusiveRefCntPtr vfs = vfs::getVFSFromYAML( - std::move(buffer.get()), nullptr, vfs_mapping.GetPath()); - if (!vfs) { - error_callback("unable to initialize the virtual file system"); - return; - } - - auto &redirecting_vfs = static_cast(*vfs); - redirecting_vfs.setFallthrough(false); - - { - llvm::Expected working_dir = - GetDirectoryFrom(m_loader); - if (working_dir) { - if (!vfs->exists(*working_dir)) - warning_callback("working directory '" + *working_dir + "' not in VFS"); - vfs->setCurrentWorkingDirectory(*working_dir); - } else { - warning_callback("no working directory in reproducer: " + - toString(working_dir.takeError())); - } - } - - { - llvm::Expected home_dir = - GetDirectoryFrom(m_loader); - if (home_dir) { - if (!vfs->exists(*home_dir)) - warning_callback("home directory '" + *home_dir + "' not in VFS"); - } else { - warning_callback("no home directory in reproducer: " + - toString(home_dir.takeError())); - } - } - - { - Expected symbol_files = - m_loader->LoadBuffer(); - if (symbol_files) { - std::vector entries; - llvm::yaml::Input yin(*symbol_files); - yin >> entries; - for (const auto &entry : entries) { - if (!entry.module_path.empty() && !vfs->exists(entry.module_path)) { - warning_callback("'" + entry.module_path + "': module path for " + - entry.uuid + " not in VFS"); - } - if (!entry.symbol_path.empty() && !vfs->exists(entry.symbol_path)) { - warning_callback("'" + entry.symbol_path + "': symbol path for " + - entry.uuid + " not in VFS"); - } - } - } else { - llvm::consumeError(symbol_files.takeError()); - } - } - - // Missing files in the VFS are notes rather than warnings. Because the VFS - // is a snapshot, temporary files could have been removed between when they - // were recorded and when the reproducer was generated. - std::vector roots = redirecting_vfs.getRoots(); - for (llvm::StringRef root : roots) { - std::error_code ec; - vfs::recursive_directory_iterator iter(*vfs, root, ec); - vfs::recursive_directory_iterator end; - for (; iter != end && !ec; iter.increment(ec)) { - ErrorOr status = vfs->status(iter->path()); - if (!status) - note_callack("'" + iter->path().str() + - "': " + status.getError().message()); - } - } -} - -static llvm::Error addPaths(StringRef path, - function_ref callback) { - auto buffer = llvm::MemoryBuffer::getFile(path); - if (!buffer) - return errorCodeToError(buffer.getError()); - - SmallVector paths; - (*buffer)->getBuffer().split(paths, '\0'); - for (StringRef p : paths) { - if (!p.empty() && llvm::sys::fs::exists(p)) - callback(p); - } - - return errorCodeToError(llvm::sys::fs::remove(path)); -} - -llvm::Error repro::Finalize(Loader *loader) { - if (!loader) - return make_error("invalid loader", - llvm::inconvertibleErrorCode()); - - FileSpec reproducer_root = loader->GetRoot(); - std::string files_path = - reproducer_root.CopyByAppendingPathComponent("files.txt").GetPath(); - std::string dirs_path = - reproducer_root.CopyByAppendingPathComponent("dirs.txt").GetPath(); - - FileCollector collector( - reproducer_root.CopyByAppendingPathComponent("root").GetPath(), - reproducer_root.GetPath()); - - if (Error e = - addPaths(files_path, [&](StringRef p) { collector.addFile(p); })) - return e; - - if (Error e = - addPaths(dirs_path, [&](StringRef p) { collector.addDirectory(p); })) - return e; - - FileSpec mapping = - reproducer_root.CopyByAppendingPathComponent(FileProvider::Info::file); - if (auto ec = collector.copyFiles(/*stop_on_error=*/false)) - return errorCodeToError(ec); - collector.writeMapping(mapping.GetPath()); - - return llvm::Error::success(); -} - -llvm::Error repro::Finalize(const FileSpec &root) { - Loader loader(root); - if (Error e = loader.LoadIndex()) - return e; - return Finalize(&loader); -} diff --git a/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp b/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp deleted file mode 100644 index e5bd2ba4b62..00000000000 --- a/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp +++ /dev/null @@ -1,253 +0,0 @@ -//===-- ReproducerInstrumentation.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 "lldb/Utility/ReproducerInstrumentation.h" -#include "lldb/Utility/Reproducer.h" -#include -#include -#include -#include - -using namespace lldb_private; -using namespace lldb_private::repro; - -void *IndexToObject::GetObjectForIndexImpl(unsigned idx) { - return m_mapping.lookup(idx); -} - -void IndexToObject::AddObjectForIndexImpl(unsigned idx, void *object) { - assert(idx != 0 && "Cannot add object for sentinel"); - m_mapping[idx] = object; -} - -std::vector IndexToObject::GetAllObjects() const { - std::vector> pairs; - for (auto &e : m_mapping) { - pairs.emplace_back(e.first, e.second); - } - - // Sort based on index. - std::sort(pairs.begin(), pairs.end(), - [](auto &lhs, auto &rhs) { return lhs.first < rhs.first; }); - - std::vector objects; - objects.reserve(pairs.size()); - for (auto &p : pairs) { - objects.push_back(p.second); - } - - return objects; -} - -template <> const uint8_t *Deserializer::Deserialize() { - return Deserialize(); -} - -template <> void *Deserializer::Deserialize() { - return const_cast(Deserialize()); -} - -template <> const void *Deserializer::Deserialize() { - return nullptr; -} - -template <> char *Deserializer::Deserialize() { - return const_cast(Deserialize()); -} - -template <> const char *Deserializer::Deserialize() { - const size_t size = Deserialize(); - if (size == std::numeric_limits::max()) - return nullptr; - assert(HasData(size + 1)); - const char *str = m_buffer.data(); - m_buffer = m_buffer.drop_front(size + 1); -#ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> \"" - << str << "\"\n"; -#endif - return str; -} - -template <> const char **Deserializer::Deserialize() { - const size_t size = Deserialize(); - if (size == 0) - return nullptr; - const char **r = - reinterpret_cast(calloc(size + 1, sizeof(char *))); - for (size_t i = 0; i < size; ++i) - r[i] = Deserialize(); - return r; -} - -void Deserializer::CheckSequence(unsigned sequence) { - if (m_expected_sequence && *m_expected_sequence != sequence) - llvm::report_fatal_error( - "The result does not match the preceding " - "function. This is probably the result of concurrent " - "use of the SB API during capture, which is currently not " - "supported."); - m_expected_sequence.reset(); -} - -bool Registry::Replay(const FileSpec &file) { - auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); - if (auto err = error_or_file.getError()) - return false; - - return Replay((*error_or_file)->getBuffer()); -} - -bool Registry::Replay(llvm::StringRef buffer) { - Deserializer deserializer(buffer); - return Replay(deserializer); -} - -bool Registry::Replay(Deserializer &deserializer) { -#ifndef LLDB_REPRO_INSTR_TRACE - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); -#endif - - // Disable buffering stdout so that we approximate the way things get flushed - // during an interactive session. - setvbuf(stdout, nullptr, _IONBF, 0); - - while (deserializer.HasData(1)) { - unsigned sequence = deserializer.Deserialize(); - unsigned id = deserializer.Deserialize(); - -#ifndef LLDB_REPRO_INSTR_TRACE - LLDB_LOG(log, "Replaying {0}: {1}", id, GetSignature(id)); -#else - llvm::errs() << "Replaying " << id << ": " << GetSignature(id) << "\n"; -#endif - - deserializer.SetExpectedSequence(sequence); - GetReplayer(id)->operator()(deserializer); - } - - // Add a small artificial delay to ensure that all asynchronous events have - // completed before we exit. - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - return true; -} - -void Registry::DoRegister(uintptr_t RunID, std::unique_ptr replayer, - SignatureStr signature) { - const unsigned id = m_replayers.size() + 1; - assert(m_replayers.find(RunID) == m_replayers.end()); - m_replayers[RunID] = std::make_pair(std::move(replayer), id); - m_ids[id] = - std::make_pair(m_replayers[RunID].first.get(), std::move(signature)); -} - -unsigned Registry::GetID(uintptr_t addr) { - unsigned id = m_replayers[addr].second; - assert(id != 0 && "Forgot to add function to registry?"); - return id; -} - -std::string Registry::GetSignature(unsigned id) { - assert(m_ids.count(id) != 0 && "ID not in registry"); - return m_ids[id].second.ToString(); -} - -void Registry::CheckID(unsigned expected, unsigned actual) { - if (expected != actual) { - llvm::errs() << "Reproducer expected signature " << expected << ": '" - << GetSignature(expected) << "'\n"; - llvm::errs() << "Reproducer actual signature " << actual << ": '" - << GetSignature(actual) << "'\n"; - llvm::report_fatal_error( - "Detected reproducer replay divergence. Refusing to continue."); - } - -#ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Replaying " << actual << ": " << GetSignature(actual) - << "\n"; -#endif -} - -Replayer *Registry::GetReplayer(unsigned id) { - assert(m_ids.count(id) != 0 && "ID not in registry"); - return m_ids[id].first; -} - -std::string Registry::SignatureStr::ToString() const { - return (result + (result.empty() ? "" : " ") + scope + "::" + name + args) - .str(); -} - -unsigned ObjectToIndex::GetIndexForObjectImpl(const void *object) { - unsigned index = m_mapping.size() + 1; - auto it = m_mapping.find(object); - if (it == m_mapping.end()) - m_mapping[object] = index; - return m_mapping[object]; -} - -Recorder::Recorder() - : m_pretty_func(), m_pretty_args(), - - m_sequence(std::numeric_limits::max()) { - if (!g_global_boundary) { - g_global_boundary = true; - m_local_boundary = true; - m_sequence = GetNextSequenceNumber(); - } -} - -Recorder::Recorder(llvm::StringRef pretty_func, std::string &&pretty_args) - : m_serializer(nullptr), m_pretty_func(pretty_func), - m_pretty_args(pretty_args), m_local_boundary(false), - m_result_recorded(true), - m_sequence(std::numeric_limits::max()) { - if (!g_global_boundary) { - g_global_boundary = true; - m_local_boundary = true; - m_sequence = GetNextSequenceNumber(); - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "{0} ({1})", - m_pretty_func, m_pretty_args); - } -} - -Recorder::~Recorder() { - assert(m_result_recorded && "Did you forget LLDB_RECORD_RESULT?"); - UpdateBoundary(); -} - -unsigned Recorder::GetSequenceNumber() const { - assert(m_sequence != std::numeric_limits::max()); - return m_sequence; -} - -void InstrumentationData::Initialize(Serializer &serializer, - Registry ®istry) { - InstanceImpl().emplace(serializer, registry); -} - -void InstrumentationData::Initialize(Deserializer &deserializer, - Registry ®istry) { - InstanceImpl().emplace(deserializer, registry); -} - -InstrumentationData &InstrumentationData::Instance() { - if (!InstanceImpl()) - InstanceImpl().emplace(); - return *InstanceImpl(); -} - -llvm::Optional &InstrumentationData::InstanceImpl() { - static llvm::Optional g_instrumentation_data; - return g_instrumentation_data; -} - -thread_local bool lldb_private::repro::Recorder::g_global_boundary = false; -std::atomic lldb_private::repro::Recorder::g_sequence; -std::mutex lldb_private::repro::Recorder::g_mutex; diff --git a/gnu/llvm/lldb/source/Utility/ReproducerProvider.cpp b/gnu/llvm/lldb/source/Utility/ReproducerProvider.cpp deleted file mode 100644 index 5145819b717..00000000000 --- a/gnu/llvm/lldb/source/Utility/ReproducerProvider.cpp +++ /dev/null @@ -1,221 +0,0 @@ -//===-- Reproducer.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 "lldb/Utility/ReproducerProvider.h" -#include "lldb/Utility/ProcessInfo.h" -#include "llvm/ADT/ScopeExit.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/WithColor.h" -#include "llvm/Support/raw_ostream.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace llvm; -using namespace llvm::yaml; - -llvm::Expected> -DataRecorder::Create(const FileSpec &filename) { - std::error_code ec; - auto recorder = std::make_unique(std::move(filename), ec); - if (ec) - return llvm::errorCodeToError(ec); - return std::move(recorder); -} - -llvm::Expected> -YamlRecorder::Create(const FileSpec &filename) { - std::error_code ec; - auto recorder = std::make_unique(std::move(filename), ec); - if (ec) - return llvm::errorCodeToError(ec); - return std::move(recorder); -} - -void VersionProvider::Keep() { - FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); - std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); - if (ec) - return; - os << m_version << "\n"; -} - -FlushingFileCollector::FlushingFileCollector(llvm::StringRef files_path, - llvm::StringRef dirs_path, - std::error_code &ec) { - auto clear = llvm::make_scope_exit([this]() { - m_files_os.reset(); - m_dirs_os.reset(); - }); - m_files_os.emplace(files_path, ec, llvm::sys::fs::OF_Append); - if (ec) - return; - m_dirs_os.emplace(dirs_path, ec, llvm::sys::fs::OF_Append); - if (ec) - return; - clear.release(); -} - -void FlushingFileCollector::addFileImpl(StringRef file) { - if (m_files_os) { - *m_files_os << file << '\0'; - m_files_os->flush(); - } -} - -llvm::vfs::directory_iterator -FlushingFileCollector::addDirectoryImpl(const Twine &dir, - IntrusiveRefCntPtr vfs, - std::error_code &dir_ec) { - if (m_dirs_os) { - *m_dirs_os << dir << '\0'; - m_dirs_os->flush(); - } - return vfs->dir_begin(dir, dir_ec); -} - -void FileProvider::RecordInterestingDirectory(const llvm::Twine &dir) { - if (m_collector) - m_collector->addFile(dir); -} - -void FileProvider::RecordInterestingDirectoryRecursive(const llvm::Twine &dir) { - if (m_collector) - m_collector->addDirectory(dir); -} - -llvm::Expected> -ProcessInfoRecorder::Create(const FileSpec &filename) { - std::error_code ec; - auto recorder = - std::make_unique(std::move(filename), ec); - if (ec) - return llvm::errorCodeToError(ec); - return std::move(recorder); -} - -void ProcessInfoProvider::Keep() { - std::vector files; - for (auto &recorder : m_process_info_recorders) { - recorder->Stop(); - files.push_back(recorder->GetFilename().GetPath()); - } - - FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); - std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); - if (ec) - return; - llvm::yaml::Output yout(os); - yout << files; -} - -void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); } - -ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() { - std::size_t i = m_process_info_recorders.size() + 1; - std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") + - llvm::Twine(i) + llvm::Twine(".yaml")) - .str(); - auto recorder_or_error = ProcessInfoRecorder::Create( - GetRoot().CopyByAppendingPathComponent(filename)); - if (!recorder_or_error) { - llvm::consumeError(recorder_or_error.takeError()); - return nullptr; - } - - m_process_info_recorders.push_back(std::move(*recorder_or_error)); - return m_process_info_recorders.back().get(); -} - -void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) { - if (!m_record) - return; - llvm::yaml::Output yout(m_os); - yout << const_cast(process_infos); - m_os.flush(); -} - -void SymbolFileProvider::AddSymbolFile(const UUID *uuid, - const FileSpec &module_file, - const FileSpec &symbol_file) { - if (!uuid || (!module_file && !symbol_file)) - return; - m_symbol_files.emplace_back(uuid->GetAsString(), module_file.GetPath(), - symbol_file.GetPath()); -} - -void SymbolFileProvider::Keep() { - FileSpec file = this->GetRoot().CopyByAppendingPathComponent(Info::file); - std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_TextWithCRLF); - if (ec) - return; - - // Remove duplicates. - llvm::sort(m_symbol_files.begin(), m_symbol_files.end()); - m_symbol_files.erase( - std::unique(m_symbol_files.begin(), m_symbol_files.end()), - m_symbol_files.end()); - - llvm::yaml::Output yout(os); - yout << m_symbol_files; -} - -SymbolFileLoader::SymbolFileLoader(Loader *loader) { - if (!loader) - return; - - FileSpec file = loader->GetFile(); - if (!file) - return; - - auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); - if (auto err = error_or_file.getError()) - return; - - llvm::yaml::Input yin((*error_or_file)->getBuffer()); - yin >> m_symbol_files; -} - -std::pair -SymbolFileLoader::GetPaths(const UUID *uuid) const { - if (!uuid) - return {}; - - auto it = std::lower_bound(m_symbol_files.begin(), m_symbol_files.end(), - SymbolFileProvider::Entry(uuid->GetAsString())); - if (it == m_symbol_files.end()) - return {}; - return std::make_pair(FileSpec(it->module_path), - FileSpec(it->symbol_path)); -} - -void ProviderBase::anchor() {} -char CommandProvider::ID = 0; -char FileProvider::ID = 0; -char ProviderBase::ID = 0; -char VersionProvider::ID = 0; -char WorkingDirectoryProvider::ID = 0; -char HomeDirectoryProvider::ID = 0; -char ProcessInfoProvider::ID = 0; -char SymbolFileProvider::ID = 0; -const char *CommandProvider::Info::file = "command-interpreter.yaml"; -const char *CommandProvider::Info::name = "command-interpreter"; -const char *FileProvider::Info::file = "files.yaml"; -const char *FileProvider::Info::name = "files"; -const char *VersionProvider::Info::file = "version.txt"; -const char *VersionProvider::Info::name = "version"; -const char *WorkingDirectoryProvider::Info::file = "cwd.txt"; -const char *WorkingDirectoryProvider::Info::name = "cwd"; -const char *HomeDirectoryProvider::Info::file = "home.txt"; -const char *HomeDirectoryProvider::Info::name = "home"; -const char *ProcessInfoProvider::Info::file = "process-info.yaml"; -const char *ProcessInfoProvider::Info::name = "process-info"; -const char *SymbolFileProvider::Info::file = "symbol-files.yaml"; -const char *SymbolFileProvider::Info::name = "symbol-files"; diff --git a/gnu/llvm/lldb/source/Utility/StreamCallback.cpp b/gnu/llvm/lldb/source/Utility/StreamCallback.cpp deleted file mode 100644 index c10f678d7a2..00000000000 --- a/gnu/llvm/lldb/source/Utility/StreamCallback.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===-- StreamCallback.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 "lldb/Utility/StreamCallback.h" - -#include - -using namespace lldb_private; - -StreamCallback::StreamCallback(lldb::LogOutputCallback callback, void *baton) - : llvm::raw_ostream(true), m_callback(callback), m_baton(baton) {} - -void StreamCallback::write_impl(const char *Ptr, size_t Size) { - m_callback(std::string(Ptr, Size).c_str(), m_baton); -} - -uint64_t StreamCallback::current_pos() const { return 0; } diff --git a/gnu/llvm/lldb/source/lldb.cpp b/gnu/llvm/lldb/source/lldb.cpp deleted file mode 100644 index 371902f6c1b..00000000000 --- a/gnu/llvm/lldb/source/lldb.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===-- lldb.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 "VCSVersion.inc" -#include "lldb/lldb-private.h" -#include "clang/Basic/Version.h" - -using namespace lldb; -using namespace lldb_private; - -// LLDB_VERSION_STRING is set through a define so unlike the other defines -// expanded with CMake, it lacks the double quotes. -#define QUOTE(str) #str -#define EXPAND_AND_QUOTE(str) QUOTE(str) - -static const char *GetLLDBVersion() { -#ifdef LLDB_VERSION_STRING - return EXPAND_AND_QUOTE(LLDB_VERSION_STRING); -#else - return "lldb version " CLANG_VERSION_STRING; -#endif -} - -static const char *GetLLDBRevision() { -#ifdef LLDB_REVISION - return LLDB_REVISION; -#else - return NULL; -#endif -} - -static const char *GetLLDBRepository() { -#ifdef LLDB_REPOSITORY - return LLDB_REPOSITORY; -#else - return NULL; -#endif -} - -const char *lldb_private::GetVersion() { - static std::string g_version_str; - if (g_version_str.empty()) { - const char *lldb_version = GetLLDBVersion(); - const char *lldb_repo = GetLLDBRepository(); - const char *lldb_rev = GetLLDBRevision(); - g_version_str += lldb_version; - if (lldb_repo || lldb_rev) { - g_version_str += " ("; - if (lldb_repo) - g_version_str += lldb_repo; - if (lldb_repo && lldb_rev) - g_version_str += " "; - if (lldb_rev) { - g_version_str += "revision "; - g_version_str += lldb_rev; - } - g_version_str += ")"; - } - - std::string clang_rev(clang::getClangRevision()); - if (clang_rev.length() > 0) { - g_version_str += "\n clang revision "; - g_version_str += clang_rev; - } - std::string llvm_rev(clang::getLLVMRevision()); - if (llvm_rev.length() > 0) { - g_version_str += "\n llvm revision "; - g_version_str += llvm_rev; - } - } - return g_version_str.c_str(); -} diff --git a/gnu/llvm/lldb/third_party/Python/module/six/LICENSE b/gnu/llvm/lldb/third_party/Python/module/six/LICENSE deleted file mode 100644 index e558f9d494a..00000000000 --- a/gnu/llvm/lldb/third_party/Python/module/six/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright (c) 2010-2015 Benjamin Peterson - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/gnu/llvm/lldb/third_party/Python/module/six/six.py b/gnu/llvm/lldb/third_party/Python/module/six/six.py deleted file mode 100644 index 0df2e259237..00000000000 --- a/gnu/llvm/lldb/third_party/Python/module/six/six.py +++ /dev/null @@ -1,887 +0,0 @@ -"""Utilities for writing code that runs on Python 2 and 3""" - -# Copyright (c) 2010-2015 Benjamin Peterson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from __future__ import absolute_import - -import functools -import itertools -import operator -import sys -import types - -__author__ = "Benjamin Peterson " -__version__ = "1.10.0" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = str, - integer_types = int, - class_types = type, - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = basestring, - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - result = self._resolve() - setattr(obj, self.name, result) # Invokes __set__. - try: - # This is a bit ugly, but it avoids running this again by - # removing this descriptor. - delattr(obj.__class__, self.name) - except AttributeError: - pass - return result - - -class MovedModule(_LazyDescr): - - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - _module = self._resolve() - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - -class _SixMetaPathImporter(object): - - """ - A meta path importer to import six.moves and its submodules. - - This class implements a PEP302 finder and loader. It should be compatible - with Python 2.5 and all existing versions of Python3 - """ - - def __init__(self, six_module_name): - self.name = six_module_name - self.known_modules = {} - - def _add_module(self, mod, *fullnames): - for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod - - def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] - - def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None - - def __get_module(self, fullname): - try: - return self.known_modules[fullname] - except KeyError: - raise ImportError("This loader does not know module " + fullname) - - def load_module(self, fullname): - try: - # in case of a reload - return sys.modules[fullname] - except KeyError: - pass - mod = self.__get_module(fullname) - if isinstance(mod, MovedModule): - mod = mod._resolve() - else: - mod.__loader__ = self - sys.modules[fullname] = mod - return mod - - def is_package(self, fullname): - """ - Return true, if the named module is a package. - - We need this method to get correct spec objects with - Python 3.4 (see PEP451) - """ - return hasattr(self.__get_module(fullname), "__path__") - - def get_code(self, fullname): - """Return None - - Required, if is_package is implemented""" - self.__get_module(fullname) # eventually raises ImportError - return None - get_source = get_code # same as get_code - -_importer = _SixMetaPathImporter(__name__) - - -class _MovedItems(_LazyModule): - - """Lazy loading of moved objects""" - __path__ = [] # mark as package - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("intern", "__builtin__", "sys"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), - MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), - MovedAttribute("UserList", "UserList", "collections"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), -] -# Add windows specific modules. -if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] - -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = _MovedItems(__name__ + ".moves") -_importer._add_module(moves, "moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), - MovedAttribute("splittag", "urllib", "urllib.parse"), - MovedAttribute("splituser", "urllib", "urllib.parse"), - MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), - MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), - MovedAttribute("uses_params", "urlparse", "urllib.parse"), - MovedAttribute("uses_query", "urlparse", "urllib.parse"), - MovedAttribute("uses_relative", "urlparse", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_parse( - __name__ + - ".moves.urllib_parse"), - "moves.urllib_parse", - "moves.urllib.parse") - - -class Module_six_moves_urllib_error(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_error( - __name__ + - ".moves.urllib.error"), - "moves.urllib_error", - "moves.urllib.error") - - -class Module_six_moves_urllib_request(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_request( - __name__ + - ".moves.urllib.request"), - "moves.urllib_request", - "moves.urllib.request") - - -class Module_six_moves_urllib_response(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_response( - __name__ + - ".moves.urllib.response"), - "moves.urllib_response", - "moves.urllib.response") - - -class Module_six_moves_urllib_robotparser(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_robotparser( - __name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", - "moves.urllib.robotparser") - - -class Module_six_moves_urllib(types.ModuleType): - - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" - __path__ = [] # mark as package - parse = _importer._get_module("moves.urllib_parse") - error = _importer._get_module("moves.urllib_error") - request = _importer._get_module("moves.urllib_request") - response = _importer._get_module("moves.urllib_response") - robotparser = _importer._get_module("moves.urllib_robotparser") - - def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] - -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") - - -def add_move(move): - """Add an item to six.moves.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from six.moves.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - -try: - advance_iterator = next -except NameError: - def advance_iterator(it): - return it.next() -next = advance_iterator - - -try: - callable = callable -except NameError: - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - def create_unbound_method(func, cls): - return func - - Iterator = object -else: - def get_unbound_function(unbound): - return unbound.im_func - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - def create_unbound_method(func, cls): - return types.MethodType(func, None, cls) - - class Iterator(object): - - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -if PY3: - def iterkeys(d, **kw): - return iter(d.keys(**kw)) - - def itervalues(d, **kw): - return iter(d.values(**kw)) - - def iteritems(d, **kw): - return iter(d.items(**kw)) - - def iterlists(d, **kw): - return iter(d.lists(**kw)) - - viewkeys = operator.methodcaller("keys") - - viewvalues = operator.methodcaller("values") - - viewitems = operator.methodcaller("items") -else: - def iterkeys(d, **kw): - return d.iterkeys(**kw) - - def itervalues(d, **kw): - return d.itervalues(**kw) - - def iteritems(d, **kw): - return d.iteritems(**kw) - - def iterlists(d, **kw): - return d.iterlists(**kw) - - viewkeys = operator.methodcaller("viewkeys") - - viewvalues = operator.methodcaller("viewvalues") - - viewitems = operator.methodcaller("viewitems") - -_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") -_add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") - - -if PY3: - def b(s): - return s.encode("latin-1") - - def u(s): - return s - unichr = chr - import struct - int2byte = struct.Struct(">B").pack - del struct - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - StringIO = io.StringIO - BytesIO = io.BytesIO - _assertCountEqual = "assertCountEqual" - if sys.version_info[1] <= 1: - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - else: - _assertRaisesRegex = "assertRaisesRegex" - _assertRegex = "assertRegex" -else: - def b(s): - return s - # Workaround for standalone backslash - - def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") - unichr = unichr - int2byte = chr - - def byte2int(bs): - return ord(bs[0]) - - def indexbytes(buf, i): - return ord(buf[i]) - iterbytes = functools.partial(itertools.imap, ord) - import StringIO - StringIO = BytesIO = StringIO.StringIO - _assertCountEqual = "assertItemsEqual" - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -def assertCountEqual(self, *args, **kwargs): - return getattr(self, _assertCountEqual)(*args, **kwargs) - - -def assertRaisesRegex(self, *args, **kwargs): - return getattr(self, _assertRaisesRegex)(*args, **kwargs) - - -def assertRegex(self, *args, **kwargs): - return getattr(self, _assertRegex)(*args, **kwargs) - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - def reraise(tp, value, tb=None): - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - -else: - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("""exec _code_ in _globs_, _locs_""") - - exec_("""def reraise(tp, value, tb=None): - raise tp, value, tb -""") - - -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - if from_value is None: - raise value - raise value from from_value -""") -elif sys.version_info[:2] > (3, 2): - exec_("""def raise_from(value, from_value): - raise value from from_value -""") -else: - def raise_from(value, from_value): - raise value - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) -if sys.version_info[:2] < (3, 3): - _print = print_ - - def print_(*args, **kwargs): - fp = kwargs.get("file", sys.stdout) - flush = kwargs.pop("flush", False) - _print(*args, **kwargs) - if flush and fp is not None: - fp.flush() - -_add_doc(reraise, """Reraise an exception.""") - -if sys.version_info[0:2] < (3, 4): - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper -else: - wraps = functools.wraps - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - class metaclass(meta): - - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if PY2: - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass - - -# Complete the moves implementation. -# This code is at the end of this module to speed up module loading. -# Turn this module into a package. -__path__ = [] # required for PEP 302 and PEP 451 -__package__ = __name__ # see PEP 366 @ReservedAssignment -if globals().get("__spec__") is not None: - __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable -# Remove other six meta path importers, since they cause problems. This can -# happen if six is removed from sys.modules and then reloaded. (Setuptools does -# this for some reason.) -if sys.meta_path: - for i, importer in enumerate(sys.meta_path): - # Here's some real nastiness: Another "instance" of the six module might - # be floating around. Therefore, we can't use isinstance() to check for - # the six meta path importer, since the other six instance will have - # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): - del sys.meta_path[i] - break - del i, importer -# Finally, add the importer to the meta path import hook. -sys.meta_path.append(_importer) diff --git a/gnu/llvm/lldb/tools/CMakeLists.txt b/gnu/llvm/lldb/tools/CMakeLists.txt index 57aba7db2ed..fedf580a307 100644 --- a/gnu/llvm/lldb/tools/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(intel-features) # i.e. if a target requires it as dependency. The typical # example is `check-lldb`. So, we pass EXCLUDE_FROM_ALL here. add_subdirectory(lldb-test EXCLUDE_FROM_ALL) +add_subdirectory(lldb-fuzzer EXCLUDE_FROM_ALL) #add_lldb_tool_subdirectory(lldb-instr) add_lldb_tool_subdirectory(lldb-vscode) diff --git a/gnu/llvm/lldb/tools/argdumper/argdumper.exports b/gnu/llvm/lldb/tools/argdumper/argdumper.exports deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/gnu/llvm/lldb/tools/driver/Driver.cpp b/gnu/llvm/lldb/tools/driver/Driver.cpp index a6a4a2a1b80..d463267aeef 100644 --- a/gnu/llvm/lldb/tools/driver/Driver.cpp +++ b/gnu/llvm/lldb/tools/driver/Driver.cpp @@ -15,15 +15,14 @@ #include "lldb/API/SBFile.h" #include "lldb/API/SBHostOS.h" #include "lldb/API/SBLanguageRuntime.h" -#include "lldb/API/SBReproducer.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" +#include "lldb/API/SBStructuredData.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Format.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" -#include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" @@ -43,14 +42,6 @@ #include #include -// Includes for pipe() -#if defined(_WIN32) -#include -#include -#else -#include -#endif - #if !defined(__APPLE__) #include "llvm/Support/DataTypes.h" #endif @@ -68,11 +59,14 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#define PREFIX(NAME, VALUE) \ + static constexpr StringLiteral NAME##_init[] = VALUE; \ + static constexpr ArrayRef NAME(NAME##_init, \ + std::size(NAME##_init) - 1); #include "Options.inc" #undef PREFIX -const opt::OptTable::Info InfoTable[] = { +static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ { \ @@ -84,9 +78,9 @@ const opt::OptTable::Info InfoTable[] = { #undef OPTION }; -class LLDBOptTable : public opt::OptTable { +class LLDBOptTable : public opt::GenericOptTable { public: - LLDBOptTable() : OptTable(InfoTable) {} + LLDBOptTable() : opt::GenericOptTable(InfoTable) {} }; } // namespace @@ -94,6 +88,8 @@ static void reset_stdin_termios(); static bool g_old_stdin_termios_is_valid = false; static struct termios g_old_stdin_termios; +static bool disable_color(const raw_ostream &OS) { return false; } + static Driver *g_driver = nullptr; // In the Driver::MainLoop, we change the terminal settings. This function is @@ -194,6 +190,12 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { m_debugger.SkipLLDBInitFiles(false); m_debugger.SkipAppInitFiles(false); + if (args.hasArg(OPT_no_use_colors)) { + m_debugger.SetUseColor(false); + WithColor::setAutoDetectFunction(disable_color); + m_option_data.m_debug_mode = true; + } + if (args.hasArg(OPT_version)) { m_option_data.m_print_version = true; } @@ -201,6 +203,9 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { if (args.hasArg(OPT_python_path)) { m_option_data.m_print_python_path = true; } + if (args.hasArg(OPT_print_script_interpreter_info)) { + m_option_data.m_print_script_interpreter_info = true; + } if (args.hasArg(OPT_batch)) { m_option_data.m_batch = true; @@ -232,11 +237,6 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { m_debugger.GetInstanceName()); } - if (args.hasArg(OPT_no_use_colors)) { - m_debugger.SetUseColor(false); - m_option_data.m_debug_mode = true; - } - if (auto *arg = args.getLastArg(OPT_file)) { auto arg_value = arg->getValue(); SBFileSpec file(arg_value); @@ -301,6 +301,7 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { arg_value); return error; } + m_debugger.SetREPLLanguage(m_option_data.m_repl_lang); } if (args.hasArg(OPT_repl)) { @@ -398,61 +399,23 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { return error; } - return error; -} - -static inline int OpenPipe(int fds[2], std::size_t size) { -#ifdef _WIN32 - return _pipe(fds, size, O_BINARY); -#else - (void)size; - return pipe(fds); -#endif -} - -static ::FILE *PrepareCommandsForSourcing(const char *commands_data, - size_t commands_size) { - enum PIPES { READ, WRITE }; // Indexes for the read and write fds - int fds[2] = {-1, -1}; - - if (OpenPipe(fds, commands_size) != 0) { - WithColor::error() - << "can't create pipe file descriptors for LLDB commands\n"; - return nullptr; - } - - ssize_t nrwr = write(fds[WRITE], commands_data, commands_size); - if (size_t(nrwr) != commands_size) { - WithColor::error() - << format( - "write(%i, %p, %" PRIu64 - ") failed (errno = %i) when trying to open LLDB commands pipe", - fds[WRITE], static_cast(commands_data), - static_cast(commands_size), errno) - << '\n'; - llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]); - llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); - return nullptr; - } - - // Close the write end of the pipe, so that the command interpreter will exit - // when it consumes all the data. - llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); - - // Open the read file descriptor as a FILE * that we can return as an input - // handle. - ::FILE *commands_file = fdopen(fds[READ], "rb"); - if (commands_file == nullptr) { - WithColor::error() << format("fdopen(%i, \"rb\") failed (errno = %i) " - "when trying to open LLDB commands pipe", - fds[READ], errno) - << '\n'; - llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]); - return nullptr; + if (m_option_data.m_print_script_interpreter_info) { + SBStructuredData info = + m_debugger.GetScriptInterpreterInfo(m_debugger.GetScriptLanguage()); + if (!info) { + error.SetErrorString("no script interpreter."); + } else { + SBStream stream; + error = info.GetAsJSON(stream); + if (error.Success()) { + llvm::outs() << stream.GetData() << '\n'; + } + } + exiting = true; + return error; } - // 'commands_file' now owns the read descriptor. - return commands_file; + return error; } std::string EscapeString(std::string arg) { @@ -494,9 +457,14 @@ int Driver::MainLoop() { SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); - // Before we handle any options from the command line, we parse the - // REPL init file or the default file in the user's home directory. + // Process lldbinit files before handling any options from the command line. SBCommandReturnObject result; + sb_interpreter.SourceInitFileInGlobalDirectory(result); + if (m_option_data.m_debug_mode) { + result.PutError(m_debugger.GetErrorFile()); + result.PutOutput(m_debugger.GetOutputFile()); + } + sb_interpreter.SourceInitFileInHomeDirectory(result, m_option_data.m_repl); if (m_option_data.m_debug_mode) { result.PutError(m_debugger.GetErrorFile()); @@ -584,21 +552,15 @@ int Driver::MainLoop() { // Check if we have any data in the commands stream, and if so, save it to a // temp file // so we can then run the command interpreter using the file contents. - const char *commands_data = commands_stream.GetData(); - const size_t commands_size = commands_stream.GetSize(); - bool go_interactive = true; - if ((commands_data != nullptr) && (commands_size != 0u)) { - FILE *commands_file = - PrepareCommandsForSourcing(commands_data, commands_size); - - if (commands_file == nullptr) { - // We should have already printed an error in PrepareCommandsForSourcing. + if ((commands_stream.GetData() != nullptr) && + (commands_stream.GetSize() != 0u)) { + SBError error = m_debugger.SetInputString(commands_stream.GetData()); + if (error.Fail()) { + WithColor::error() << error.GetCString() << '\n'; return 1; } - m_debugger.SetInputFileHandle(commands_file, true); - // Set the debugger into Sync mode when running the command file. Otherwise // command files that run the target won't run in a sensible way. bool old_async = m_debugger.GetAsync(); @@ -609,6 +571,7 @@ int Driver::MainLoop() { options.SetSpawnThread(false); options.SetStopOnError(true); options.SetStopOnCrash(m_option_data.m_batch); + options.SetEchoCommands(!m_option_data.m_source_quietly); SBCommandInterpreterRunResult results = m_debugger.RunCommandInterpreter(options); @@ -630,12 +593,9 @@ int Driver::MainLoop() { SBStream crash_commands_stream; WriteCommandsForSourcing(eCommandPlacementAfterCrash, crash_commands_stream); - const char *crash_commands_data = crash_commands_stream.GetData(); - const size_t crash_commands_size = crash_commands_stream.GetSize(); - commands_file = - PrepareCommandsForSourcing(crash_commands_data, crash_commands_size); - if (commands_file != nullptr) { - m_debugger.SetInputFileHandle(commands_file, true); + SBError error = + m_debugger.SetInputString(crash_commands_stream.GetData()); + if (error.Success()) { SBCommandInterpreterRunResult local_results = m_debugger.RunCommandInterpreter(options); if (local_results.GetResult() == @@ -713,31 +673,30 @@ void sigint_handler(int signo) { _exit(signo); } -void sigtstp_handler(int signo) { +#ifndef _WIN32 +static void sigtstp_handler(int signo) { if (g_driver != nullptr) g_driver->GetDebugger().SaveInputTerminalState(); + // Unblock the signal and remove our handler. + sigset_t set; + sigemptyset(&set); + sigaddset(&set, signo); + pthread_sigmask(SIG_UNBLOCK, &set, nullptr); signal(signo, SIG_DFL); - kill(getpid(), signo); + + // Now re-raise the signal. We will immediately suspend... + raise(signo); + // ... and resume after a SIGCONT. + + // Now undo the modifications. + pthread_sigmask(SIG_BLOCK, &set, nullptr); signal(signo, sigtstp_handler); -} -void sigcont_handler(int signo) { if (g_driver != nullptr) g_driver->GetDebugger().RestoreInputTerminalState(); - - signal(signo, SIG_DFL); - kill(getpid(), signo); - signal(signo, sigcont_handler); -} - -void reproducer_handler(void *finalize_cmd) { - if (SBReproducer::Generate()) { - int result = std::system(static_cast(finalize_cmd)); - (void)result; - fflush(stdout); - } } +#endif static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) { std::string usage_str = tool_name.str() + " [options]"; @@ -785,88 +744,6 @@ EXAMPLES: llvm::outs() << examples << '\n'; } -static llvm::Optional InitializeReproducer(llvm::StringRef argv0, - opt::InputArgList &input_args) { - if (auto *finalize_path = input_args.getLastArg(OPT_reproducer_finalize)) { - if (const char *error = SBReproducer::Finalize(finalize_path->getValue())) { - WithColor::error() << "reproducer finalization failed: " << error << '\n'; - return 1; - } - - llvm::outs() << "********************\n"; - llvm::outs() << "Crash reproducer for "; - llvm::outs() << lldb::SBDebugger::GetVersionString() << '\n'; - llvm::outs() << '\n'; - llvm::outs() << "Reproducer written to '" << SBReproducer::GetPath() - << "'\n"; - llvm::outs() << '\n'; - llvm::outs() << "Before attaching the reproducer to a bug report:\n"; - llvm::outs() << " - Look at the directory to ensure you're willing to " - "share its content.\n"; - llvm::outs() - << " - Make sure the reproducer works by replaying the reproducer.\n"; - llvm::outs() << '\n'; - llvm::outs() << "Replay the reproducer with the following command:\n"; - llvm::outs() << argv0 << " -replay " << finalize_path->getValue() << "\n"; - llvm::outs() << "********************\n"; - return 0; - } - - if (auto *replay_path = input_args.getLastArg(OPT_replay)) { - SBReplayOptions replay_options; - replay_options.SetCheckVersion(!input_args.hasArg(OPT_no_version_check)); - replay_options.SetVerify(!input_args.hasArg(OPT_no_verification)); - if (const char *error = - SBReproducer::Replay(replay_path->getValue(), replay_options)) { - WithColor::error() << "reproducer replay failed: " << error << '\n'; - return 1; - } - return 0; - } - - bool capture = input_args.hasArg(OPT_capture); - bool generate_on_exit = input_args.hasArg(OPT_generate_on_exit); - auto *capture_path = input_args.getLastArg(OPT_capture_path); - - if (generate_on_exit && !capture) { - WithColor::warning() - << "-reproducer-generate-on-exit specified without -capture\n"; - } - - if (capture || capture_path) { - if (capture_path) { - if (!capture) - WithColor::warning() << "-capture-path specified without -capture\n"; - if (const char *error = SBReproducer::Capture(capture_path->getValue())) { - WithColor::error() << "reproducer capture failed: " << error << '\n'; - return 1; - } - } else { - const char *error = SBReproducer::Capture(); - if (error) { - WithColor::error() << "reproducer capture failed: " << error << '\n'; - return 1; - } - } - if (generate_on_exit) - SBReproducer::SetAutoGenerate(true); - - // Register the reproducer signal handler. - if (!input_args.hasArg(OPT_no_generate_on_signal)) { - if (const char *reproducer_path = SBReproducer::GetPath()) { - static std::string *finalize_cmd = new std::string(argv0); - finalize_cmd->append(" --reproducer-finalize '"); - finalize_cmd->append(reproducer_path); - finalize_cmd->append("'"); - llvm::sys::AddSignalHandler(reproducer_handler, - const_cast(finalize_cmd->c_str())); - } - } - } - - return llvm::None; -} - int main(int argc, char const *argv[]) { // Editline uses for example iswprint which is dependent on LC_CTYPE. std::setlocale(LC_ALL, ""); @@ -880,7 +757,7 @@ int main(int argc, char const *argv[]) { LLDBOptTable T; unsigned MissingArgIndex; unsigned MissingArgCount; - ArrayRef arg_arr = makeArrayRef(argv + 1, argc - 1); + ArrayRef arg_arr = ArrayRef(argv + 1, argc - 1); opt::InputArgList input_args = T.ParseArgs(arg_arr, MissingArgIndex, MissingArgCount); llvm::StringRef argv0 = llvm::sys::path::filename(argv[0]); @@ -908,24 +785,23 @@ int main(int argc, char const *argv[]) { return 1; } - if (auto exit_code = InitializeReproducer(argv[0], input_args)) { - return *exit_code; - } - SBError error = SBDebugger::InitializeWithErrorHandling(); if (error.Fail()) { WithColor::error() << "initialization failed: " << error.GetCString() << '\n'; return 1; } + + // Setup LLDB signal handlers once the debugger has been initialized. + SBDebugger::PrintDiagnosticsOnError(); + SBHostOS::ThreadCreated(""); signal(SIGINT, sigint_handler); -#if !defined(_MSC_VER) +#if !defined(_WIN32) signal(SIGPIPE, SIG_IGN); signal(SIGWINCH, sigwinch_handler); signal(SIGTSTP, sigtstp_handler); - signal(SIGCONT, sigcont_handler); #endif int exit_code = 0; diff --git a/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt b/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt index 98c0a331f0f..facbd8e1784 100644 --- a/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt @@ -50,13 +50,15 @@ add_lldb_tool(lldb-server SystemInitializerLLGS.cpp LINK_LIBS - lldbBase lldbHost lldbInitialization + lldbVersion ${LLDB_PLUGINS} lldbPluginInstructionARM + lldbPluginInstructionLoongArch lldbPluginInstructionMIPS lldbPluginInstructionMIPS64 + lldbPluginInstructionRISCV ${LLDB_SYSTEM_LIBS} LINK_COMPONENTS diff --git a/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp b/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp index 8bda93af8b1..549e5505a49 100644 --- a/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -17,7 +17,6 @@ #include #endif -#include "Acceptor.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" @@ -26,9 +25,9 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/StringRef.h" #include "llvm/Option/ArgList.h" @@ -100,7 +99,7 @@ static int g_sighup_received_count = 0; static void sighup_handler(MainLoopBase &mainloop) { ++g_sighup_received_count; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count); @@ -169,15 +168,14 @@ void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, } } -Status writeSocketIdToPipe(Pipe &port_pipe, const std::string &socket_id) { +Status writeSocketIdToPipe(Pipe &port_pipe, llvm::StringRef socket_id) { size_t bytes_written = 0; // Write the port number as a C string with the NULL terminator. - return port_pipe.Write(socket_id.c_str(), socket_id.size() + 1, - bytes_written); + return port_pipe.Write(socket_id.data(), socket_id.size() + 1, bytes_written); } Status writeSocketIdToPipe(const char *const named_pipe_path, - const std::string &socket_id) { + llvm::StringRef socket_id) { Pipe port_name_pipe; // Wait for 10 seconds for pipe to be opened. auto error = port_name_pipe.OpenAsWriterWithTimeout(named_pipe_path, false, @@ -188,7 +186,7 @@ Status writeSocketIdToPipe(const char *const named_pipe_path, } Status writeSocketIdToPipe(lldb::pipe_t unnamed_pipe, - const std::string &socket_id) { + llvm::StringRef socket_id) { Pipe port_pipe{LLDB_INVALID_PIPE, unnamed_pipe}; return writeSocketIdToPipe(port_pipe, socket_id); } @@ -202,129 +200,76 @@ void ConnectToRemote(MainLoop &mainloop, Status error; std::unique_ptr connection_up; + std::string url; + if (connection_fd != -1) { - // Build the connection string. - char connection_url[512]; - snprintf(connection_url, sizeof(connection_url), "fd://%d", connection_fd); + url = llvm::formatv("fd://{0}", connection_fd).str(); // Create the connection. #if LLDB_ENABLE_POSIX && !defined _WIN32 ::fcntl(connection_fd, F_SETFD, FD_CLOEXEC); #endif - connection_up.reset(new ConnectionFileDescriptor); - auto connection_result = connection_up->Connect(connection_url, &error); - if (connection_result != eConnectionStatusSuccess) { - fprintf(stderr, "error: failed to connect to client at '%s' " - "(connection status: %d)\n", - connection_url, static_cast(connection_result)); - exit(-1); - } - if (error.Fail()) { - fprintf(stderr, "error: failed to connect to client at '%s': %s\n", - connection_url, error.AsCString()); - exit(-1); - } } else if (!host_and_port.empty()) { - // Parse out host and port. - std::string final_host_and_port; - std::string connection_host; - std::string connection_port; - uint32_t connection_portno = 0; - - // If host_and_port starts with ':', default the host to be "localhost" and - // expect the remainder to be the port. - if (host_and_port[0] == ':') - final_host_and_port.append("localhost"); - final_host_and_port.append(host_and_port.str()); - - // Note: use rfind, because the host/port may look like "[::1]:12345". - const std::string::size_type colon_pos = final_host_and_port.rfind(':'); - if (colon_pos != std::string::npos) { - connection_host = final_host_and_port.substr(0, colon_pos); - connection_port = final_host_and_port.substr(colon_pos + 1); - connection_portno = StringConvert::ToUInt32(connection_port.c_str(), 0); + llvm::Expected url_exp = + LLGSArgToURL(host_and_port, reverse_connect); + if (!url_exp) { + llvm::errs() << llvm::formatv("error: invalid host:port or URL '{0}': " + "{1}\n", + host_and_port, + llvm::toString(url_exp.takeError())); + exit(-1); } + url = std::move(url_exp.get()); + } - if (reverse_connect) { - // llgs will connect to the gdb-remote client. - - // Ensure we have a port number for the connection. - if (connection_portno == 0) { - fprintf(stderr, "error: port number must be specified on when using " - "reverse connect\n"); - exit(1); - } - - // Build the connection string. - char connection_url[512]; - snprintf(connection_url, sizeof(connection_url), "connect://%s", - final_host_and_port.c_str()); - - // Create the connection. - connection_up.reset(new ConnectionFileDescriptor); - auto connection_result = connection_up->Connect(connection_url, &error); - if (connection_result != eConnectionStatusSuccess) { - fprintf(stderr, "error: failed to connect to client at '%s' " - "(connection status: %d)\n", - connection_url, static_cast(connection_result)); - exit(-1); - } - if (error.Fail()) { - fprintf(stderr, "error: failed to connect to client at '%s': %s\n", - connection_url, error.AsCString()); - exit(-1); - } - } else { - std::unique_ptr acceptor_up( - Acceptor::Create(final_host_and_port, false, error)); - if (error.Fail()) { - fprintf(stderr, "failed to create acceptor: %s\n", error.AsCString()); - exit(1); - } - error = acceptor_up->Listen(1); - if (error.Fail()) { - fprintf(stderr, "failed to listen: %s\n", error.AsCString()); - exit(1); - } - const std::string socket_id = acceptor_up->GetLocalSocketId(); - if (!socket_id.empty()) { - // If we have a named pipe to write the socket id back to, do that now. - if (named_pipe_path && named_pipe_path[0]) { - error = writeSocketIdToPipe(named_pipe_path, socket_id); - if (error.Fail()) - fprintf(stderr, "failed to write to the named pipe \'%s\': %s\n", - named_pipe_path, error.AsCString()); - } - // If we have an unnamed pipe to write the socket id back to, do that - // now. - else if (unnamed_pipe != LLDB_INVALID_PIPE) { - error = writeSocketIdToPipe(unnamed_pipe, socket_id); - if (error.Fail()) - fprintf(stderr, "failed to write to the unnamed pipe: %s\n", - error.AsCString()); - } - } else { - fprintf(stderr, - "unable to get the socket id for the listening connection\n"); - } + if (!url.empty()) { + // Create the connection or server. + std::unique_ptr conn_fd_up{ + new ConnectionFileDescriptor}; + auto connection_result = conn_fd_up->Connect( + url, + [named_pipe_path, unnamed_pipe](llvm::StringRef socket_id) { + // If we have a named pipe to write the socket id back to, do that + // now. + if (named_pipe_path && named_pipe_path[0]) { + Status error = writeSocketIdToPipe(named_pipe_path, socket_id); + if (error.Fail()) + llvm::errs() << llvm::formatv( + "failed to write to the named peipe '{0}': {1}\n", + named_pipe_path, error.AsCString()); + } + // If we have an unnamed pipe to write the socket id back to, do + // that now. + else if (unnamed_pipe != LLDB_INVALID_PIPE) { + Status error = writeSocketIdToPipe(unnamed_pipe, socket_id); + if (error.Fail()) + llvm::errs() << llvm::formatv( + "failed to write to the unnamed pipe: {0}\n", error); + } + }, + &error); - Connection *conn = nullptr; - error = acceptor_up->Accept(false, conn); - if (error.Fail()) { - printf("failed to accept new connection: %s\n", error.AsCString()); - exit(1); - } - connection_up.reset(conn); + if (error.Fail()) { + llvm::errs() << llvm::formatv( + "error: failed to connect to client at '{0}': {1}\n", url, error); + exit(-1); + } + if (connection_result != eConnectionStatusSuccess) { + llvm::errs() << llvm::formatv( + "error: failed to connect to client at '{0}' " + "(connection status: {1})\n", + url, static_cast(connection_result)); + exit(-1); } + connection_up = std::move(conn_fd_up); } error = gdb_server.InitializeConnection(std::move(connection_up)); if (error.Fail()) { - fprintf(stderr, "Failed to initialize connection: %s\n", - error.AsCString()); + llvm::errs() << llvm::formatv("failed to initialize connection\n", error); exit(-1); } - printf("Connection established.\n"); + llvm::outs() << "Connection established.\n"; } namespace { @@ -337,11 +282,14 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#define PREFIX(NAME, VALUE) \ + constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ + constexpr llvm::ArrayRef NAME( \ + NAME##_init, std::size(NAME##_init) - 1); #include "LLGSOptions.inc" #undef PREFIX -const opt::OptTable::Info InfoTable[] = { +static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ { \ @@ -353,9 +301,9 @@ const opt::OptTable::Info InfoTable[] = { #undef OPTION }; -class LLGSOptTable : public opt::OptTable { +class LLGSOptTable : public opt::GenericOptTable { public: - LLGSOptTable() : OptTable(InfoTable) {} + LLGSOptTable() : opt::GenericOptTable(InfoTable) {} void PrintHelp(llvm::StringRef Name) { std::string Usage = diff --git a/gnu/llvm/lldb/tools/lldb-server/lldb-server.exports b/gnu/llvm/lldb/tools/lldb-server/lldb-server.exports deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/gnu/llvm/lldb/unittests/API/CMakeLists.txt b/gnu/llvm/lldb/unittests/API/CMakeLists.txt deleted file mode 100644 index 7bdc1e3e87c..00000000000 --- a/gnu/llvm/lldb/unittests/API/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_lldb_unittest(APITests - SBCommandInterpreterTest.cpp - SBStructuredDataTest.cpp - - LINK_LIBS - liblldb - ) - -if(Python3_RPATH) - set_property(TARGET APITests APPEND PROPERTY BUILD_RPATH "${Python3_RPATH}") -endif() diff --git a/gnu/llvm/lldb/unittests/API/SBCommandInterpreterTest.cpp b/gnu/llvm/lldb/unittests/API/SBCommandInterpreterTest.cpp deleted file mode 100644 index d117c08c0bf..00000000000 --- a/gnu/llvm/lldb/unittests/API/SBCommandInterpreterTest.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===-- SBCommandInterpreterTest.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 "gtest/gtest.h" - -#include "lldb/API/SBCommandInterpreter.h" -#include "lldb/API/SBCommandReturnObject.h" -#include "lldb/API/SBDebugger.h" - -#include -#include - -using namespace lldb; - -class SBCommandInterpreterTest : public testing::Test { -protected: - void SetUp() override { - SBDebugger::Initialize(); - m_dbg = SBDebugger::Create(/*source_init_files=*/false); - m_interp = m_dbg.GetCommandInterpreter(); - } - - SBDebugger m_dbg; - SBCommandInterpreter m_interp; -}; - -class DummyCommand : public SBCommandPluginInterface { -public: - DummyCommand(const char *message) : m_message(message) {} - - bool DoExecute(SBDebugger dbg, char **command, - SBCommandReturnObject &result) { - result.PutCString(m_message.c_str()); - result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); - } - -private: - std::string m_message; -}; - -TEST_F(SBCommandInterpreterTest, SingleWordCommand) { - // We first test a command without autorepeat - DummyCommand dummy("It worked"); - m_interp.AddCommand("dummy", &dummy, /*help=*/nullptr); - { - SBCommandReturnObject result; - m_interp.HandleCommand("dummy", result, /*add_to_history=*/true); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked\n"); - } - { - SBCommandReturnObject result; - m_interp.HandleCommand("", result); - EXPECT_FALSE(result.Succeeded()); - EXPECT_STREQ(result.GetError(), "error: No auto repeat.\n"); - } - - // Now we test a command with autorepeat - m_interp.AddCommand("dummy_with_autorepeat", &dummy, /*help=*/nullptr, - /*syntax=*/nullptr, /*auto_repeat_command=*/nullptr); - { - SBCommandReturnObject result; - m_interp.HandleCommand("dummy_with_autorepeat", result, - /*add_to_history=*/true); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked\n"); - } - { - SBCommandReturnObject result; - m_interp.HandleCommand("", result); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked\n"); - } -} - -TEST_F(SBCommandInterpreterTest, MultiWordCommand) { - auto command = m_interp.AddMultiwordCommand("multicommand", /*help=*/nullptr); - // We first test a subcommand without autorepeat - DummyCommand subcommand("It worked again"); - command.AddCommand("subcommand", &subcommand, /*help=*/nullptr); - { - SBCommandReturnObject result; - m_interp.HandleCommand("multicommand subcommand", result, - /*add_to_history=*/true); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked again\n"); - } - { - SBCommandReturnObject result; - m_interp.HandleCommand("", result); - EXPECT_FALSE(result.Succeeded()); - EXPECT_STREQ(result.GetError(), "error: No auto repeat.\n"); - } - - // We first test a subcommand with autorepeat - command.AddCommand("subcommand_with_autorepeat", &subcommand, - /*help=*/nullptr, /*syntax=*/nullptr, - /*auto_repeat_command=*/nullptr); - { - SBCommandReturnObject result; - m_interp.HandleCommand("multicommand subcommand_with_autorepeat", result, - /*add_to_history=*/true); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked again\n"); - } - { - SBCommandReturnObject result; - m_interp.HandleCommand("", result); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked again\n"); - } - - DummyCommand subcommand2("It worked again 2"); - // We now test a subcommand with autorepeat of the command name - command.AddCommand( - "subcommand_with_custom_autorepeat", &subcommand2, /*help=*/nullptr, - /*syntax=*/nullptr, - /*auto_repeat_command=*/"multicommand subcommand_with_autorepeat"); - { - SBCommandReturnObject result; - m_interp.HandleCommand("multicommand subcommand_with_custom_autorepeat", - result, /*add_to_history=*/true); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked again 2\n"); - } - { - SBCommandReturnObject result; - m_interp.HandleCommand("", result); - EXPECT_TRUE(result.Succeeded()); - EXPECT_STREQ(result.GetOutput(), "It worked again\n"); - } -} diff --git a/gnu/llvm/lldb/unittests/API/SBStructuredDataTest.cpp b/gnu/llvm/lldb/unittests/API/SBStructuredDataTest.cpp deleted file mode 100644 index a3a33aad9a1..00000000000 --- a/gnu/llvm/lldb/unittests/API/SBStructuredDataTest.cpp +++ /dev/null @@ -1,35 +0,0 @@ -//===-- SBStructuredDataTest.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 "gtest/gtest.h" - -#include "lldb/API/SBStringList.h" -#include "lldb/API/SBStructuredData.h" - -#include -#include - -using namespace lldb; - -class SBStructuredDataTest : public testing::Test {}; - -TEST_F(SBStructuredDataTest, NullImpl) { - SBStructuredData data(nullptr); - EXPECT_EQ(data.GetType(), eStructuredDataTypeInvalid); - EXPECT_EQ(data.GetSize(), 0ul); - SBStringList keys; - EXPECT_FALSE(data.GetKeys(keys)); - EXPECT_EQ(data.GetValueForKey("key").GetType(), eStructuredDataTypeInvalid); - EXPECT_EQ(data.GetItemAtIndex(0).GetType(), eStructuredDataTypeInvalid); - EXPECT_EQ(data.GetIntegerValue(UINT64_MAX), UINT64_MAX); - EXPECT_EQ(data.GetFloatValue(DBL_MAX), DBL_MAX); - EXPECT_TRUE(data.GetBooleanValue(true)); - EXPECT_FALSE(data.GetBooleanValue(false)); - char dst[1]; - EXPECT_EQ(data.GetStringValue(dst, sizeof(dst)), 0ul); -} diff --git a/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp b/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp deleted file mode 100644 index 7d1695e6e3c..00000000000 --- a/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===-- BreakpointIDTest.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 "gtest/gtest.h" - -#include "lldb/Breakpoint/BreakpointID.h" -#include "lldb/Utility/Status.h" - -#include "llvm/ADT/StringRef.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(BreakpointIDTest, StringIsBreakpointName) { - Status E; - EXPECT_FALSE(BreakpointID::StringIsBreakpointName("1breakpoint", E)); - EXPECT_FALSE(BreakpointID::StringIsBreakpointName("-", E)); - EXPECT_FALSE(BreakpointID::StringIsBreakpointName("", E)); - EXPECT_FALSE(BreakpointID::StringIsBreakpointName("3.4", E)); - - EXPECT_TRUE(BreakpointID::StringIsBreakpointName("_", E)); - EXPECT_TRUE(BreakpointID::StringIsBreakpointName("a123", E)); - EXPECT_TRUE(BreakpointID::StringIsBreakpointName("test", E)); -} diff --git a/gnu/llvm/lldb/unittests/Breakpoint/CMakeLists.txt b/gnu/llvm/lldb/unittests/Breakpoint/CMakeLists.txt deleted file mode 100644 index 3164af237a7..00000000000 --- a/gnu/llvm/lldb/unittests/Breakpoint/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_lldb_unittest(LLDBBreakpointTests - BreakpointIDTest.cpp - - LINK_LIBS - lldbBreakpoint - lldbCore - LINK_COMPONENTS - Support - ) diff --git a/gnu/llvm/lldb/unittests/CMakeLists.txt b/gnu/llvm/lldb/unittests/CMakeLists.txt deleted file mode 100644 index e7b0f1c17d6..00000000000 --- a/gnu/llvm/lldb/unittests/CMakeLists.txt +++ /dev/null @@ -1,100 +0,0 @@ -add_custom_target(LLDBUnitTests) -set_target_properties(LLDBUnitTests PROPERTIES FOLDER "lldb tests") - -add_dependencies(lldb-unit-test-deps LLDBUnitTests) - -include_directories(${LLDB_SOURCE_ROOT}) -include_directories(${LLDB_PROJECT_ROOT}/unittests) - -if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG) - add_compile_options("-Wno-suggest-override") -endif() - -set(LLDB_GTEST_COMMON_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/gtest_common.h) -if (MSVC) - list(APPEND LLVM_COMPILE_FLAGS /FI ${LLDB_GTEST_COMMON_INCLUDE}) -else () - list(APPEND LLVM_COMPILE_FLAGS -include ${LLDB_GTEST_COMMON_INCLUDE}) -endif () - -if (LLDB_BUILT_STANDALONE) - # Build the gtest library needed for unittests, if we have LLVM sources - # handy. - if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/unittest AND NOT TARGET gtest) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/unittest utils/unittest) - endif() - # LLVMTestingSupport library is needed for Process/gdb-remote. - if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support - AND NOT TARGET LLVMTestingSupport) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Testing/Support - lib/Testing/Support) - endif() -endif() - -function(add_lldb_unittest test_name) - cmake_parse_arguments(ARG - "" - "" - "LINK_LIBS;LINK_COMPONENTS" - ${ARGN}) - - if (NOT ${test_name} MATCHES "Tests$") - message(FATAL_ERROR "Unit test name must end with 'Tests' for lit to find it.") - endif() - - list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) - - add_unittest(LLDBUnitTests - ${test_name} - ${ARG_UNPARSED_ARGUMENTS} - ) - - add_custom_command( - TARGET ${test_name} - POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/Inputs) - - target_link_libraries(${test_name} PRIVATE ${ARG_LINK_LIBS}) -endfunction() - -function(add_unittest_inputs test_name inputs) - foreach (INPUT ${inputs}) - add_custom_command( - TARGET ${test_name} - POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Inputs/${INPUT} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/Inputs - COMMENT "Copying ${INPUT} to binary directory.") - endforeach() -endfunction() - -add_subdirectory(TestingSupport) -if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - # FIXME: APITests.exe is not a valid googletest binary. - add_subdirectory(API) -endif() -add_subdirectory(Breakpoint) -add_subdirectory(Core) -add_subdirectory(DataFormatter) -add_subdirectory(Disassembler) -add_subdirectory(Editline) -add_subdirectory(Expression) -add_subdirectory(Host) -add_subdirectory(Interpreter) -add_subdirectory(Instruction) -add_subdirectory(Language) -add_subdirectory(ObjectFile) -add_subdirectory(Platform) -add_subdirectory(Process) -add_subdirectory(ScriptInterpreter) -add_subdirectory(Signals) -add_subdirectory(Symbol) -add_subdirectory(SymbolFile) -add_subdirectory(Target) -add_subdirectory(tools) -add_subdirectory(UnwindAssembly) -add_subdirectory(Utility) -add_subdirectory(Thread) - -if(LLDB_CAN_USE_DEBUGSERVER AND LLDB_TOOL_DEBUGSERVER_BUILD AND NOT LLDB_USE_SYSTEM_DEBUGSERVER) - add_subdirectory(debugserver) -endif() diff --git a/gnu/llvm/lldb/unittests/Core/CMakeLists.txt b/gnu/llvm/lldb/unittests/Core/CMakeLists.txt deleted file mode 100644 index dfe017b3c9c..00000000000 --- a/gnu/llvm/lldb/unittests/Core/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -add_lldb_unittest(LLDBCoreTests - CommunicationTest.cpp - DumpDataExtractorTest.cpp - FormatEntityTest.cpp - MangledTest.cpp - ModuleSpecTest.cpp - RichManglingContextTest.cpp - SourceLocationSpecTest.cpp - SourceManagerTest.cpp - StreamCallbackTest.cpp - UniqueCStringMapTest.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbSymbol - lldbPluginObjectFileELF - lldbPluginObjectFileMachO - lldbPluginObjectFilePECOFF - lldbPluginSymbolFileSymtab - lldbUtilityHelpers - LLVMTestingSupport - LINK_COMPONENTS - Support - ) diff --git a/gnu/llvm/lldb/unittests/Core/CommunicationTest.cpp b/gnu/llvm/lldb/unittests/Core/CommunicationTest.cpp deleted file mode 100644 index 3ddc78d4a5a..00000000000 --- a/gnu/llvm/lldb/unittests/Core/CommunicationTest.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===-- CommunicationTest.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 "lldb/Core/Communication.h" -#include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/Pipe.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -#ifndef _WIN32 -TEST(CommunicationTest, SynchronizeWhileClosing) { - // Set up a communication object reading from a pipe. - Pipe pipe; - ASSERT_THAT_ERROR(pipe.CreateNew(/*child_process_inherit=*/false).ToError(), - llvm::Succeeded()); - - Communication comm("test"); - comm.SetConnection(std::make_unique( - pipe.ReleaseReadFileDescriptor(), /*owns_fd=*/true)); - comm.SetCloseOnEOF(true); - ASSERT_TRUE(comm.StartReadThread()); - - // Ensure that we can safely synchronize with the read thread while it is - // closing the read end (in response to us closing the write end). - pipe.CloseWriteFileDescriptor(); - comm.SynchronizeWithReadThread(); - - ASSERT_TRUE(comm.StopReadThread()); -} -#endif diff --git a/gnu/llvm/lldb/unittests/Core/DumpDataExtractorTest.cpp b/gnu/llvm/lldb/unittests/Core/DumpDataExtractorTest.cpp deleted file mode 100644 index f76014aa938..00000000000 --- a/gnu/llvm/lldb/unittests/Core/DumpDataExtractorTest.cpp +++ /dev/null @@ -1,387 +0,0 @@ -//===-- DataDumpExtractorTest.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 "lldb/Core/DumpDataExtractor.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Endian.h" -#include "lldb/Utility/StreamString.h" -#include "gtest/gtest.h" -#include -#include - -using namespace lldb; -using namespace lldb_private; - -static void TestDumpWithAddress(uint64_t base_addr, size_t item_count, - llvm::StringRef expected) { - std::vector data{0x11, 0x22}; - StreamString result; - DataBufferHeap dumpbuffer(&data[0], data.size()); - DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), - endian::InlHostByteOrder(), /*addr_size=*/4); - - DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatHex, - /*item_byte_size=*/1, item_count, - /*num_per_line=*/1, base_addr, 0, 0); - ASSERT_EQ(expected, result.GetString()); -} - -TEST(DumpDataExtractorTest, BaseAddress) { - TestDumpWithAddress(0x12341234, 1, "0x12341234: 0x11"); - TestDumpWithAddress(LLDB_INVALID_ADDRESS, 1, "0x11"); - TestDumpWithAddress(0x12341234, 2, "0x12341234: 0x11\n0x12341235: 0x22"); - TestDumpWithAddress(LLDB_INVALID_ADDRESS, 2, "0x11\n0x22"); -} - -static void TestDumpWithOffset(offset_t start_offset, - llvm::StringRef expected) { - std::vector data{0x11, 0x22, 0x33}; - StreamString result; - DataBufferHeap dumpbuffer(&data[0], data.size()); - DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), - endian::InlHostByteOrder(), /*addr_size=*/4); - - DumpDataExtractor(extractor, &result, start_offset, lldb::Format::eFormatHex, - /*item_byte_size=*/1, /*item_count=*/data.size(), - /*num_per_line=*/data.size(), /*base_addr=*/0, 0, 0); - ASSERT_EQ(expected, result.GetString()); -} - -TEST(DumpDataExtractorTest, StartOffset) { - TestDumpWithOffset(0, "0x00000000: 0x11 0x22 0x33"); - // The offset applies to the DataExtractor, not the address used when - // formatting. - TestDumpWithOffset(1, "0x00000000: 0x22 0x33"); - // If the offset is outside the DataExtractor's range we do nothing. - TestDumpWithOffset(3, ""); -} - -TEST(DumpDataExtractorTest, NullStream) { - // We don't do any work if there is no output stream. - uint8_t c = 0x11; - StreamString result; - DataBufferHeap dumpbuffer(&c, 0); - DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), - endian::InlHostByteOrder(), /*addr_size=*/4); - - DumpDataExtractor(extractor, nullptr, 0, lldb::Format::eFormatHex, - /*item_byte_size=*/1, /*item_count=*/1, - /*num_per_line=*/1, /*base_addr=*/0, 0, 0); - ASSERT_EQ("", result.GetString()); -} - -static void TestDumpImpl(const void *data, size_t data_size, - size_t item_byte_size, size_t item_count, - size_t num_per_line, uint64_t base_addr, - lldb::Format format, llvm::StringRef expected) { - StreamString result; - DataBufferHeap dumpbuffer(data, data_size); - DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), - endian::InlHostByteOrder(), - /*addr_size=*/4); - DumpDataExtractor(extractor, &result, 0, format, item_byte_size, item_count, - num_per_line, base_addr, 0, 0); - ASSERT_EQ(expected, result.GetString()); -} - -template -static void TestDump(T data, lldb::Format format, llvm::StringRef expected) { - TestDumpImpl(&data, sizeof(T), sizeof(T), 1, 1, LLDB_INVALID_ADDRESS, format, - expected); -} - -static void TestDump(llvm::StringRef str, lldb::Format format, - llvm::StringRef expected) { - TestDumpImpl(str.bytes_begin(), - // +1 to include the NULL char as the last byte - str.size() + 1, str.size() + 1, 1, 1, LLDB_INVALID_ADDRESS, - format, expected); -} - -template -static void TestDump(const std::vector data, lldb::Format format, - llvm::StringRef expected) { - size_t sz_bytes = data.size() * sizeof(T); - TestDumpImpl(&data[0], sz_bytes, sz_bytes, data.size(), 1, - LLDB_INVALID_ADDRESS, format, expected); -} - -TEST(DumpDataExtractorTest, Formats) { - TestDump(1, lldb::eFormatDefault, "0x01"); - TestDump(1, lldb::eFormatBoolean, "true"); - TestDump(0xAA, lldb::eFormatBinary, "0b10101010"); - TestDump(1, lldb::eFormatBytes, "01"); - TestDump(1, lldb::eFormatBytesWithASCII, "01 ."); - TestDump('?', lldb::eFormatChar, "'?'"); - TestDump('\x1A', lldb::eFormatCharPrintable, "."); - TestDump('#', lldb::eFormatCharPrintable, "#"); - TestDump(std::complex(1.2, 3.4), lldb::eFormatComplex, "1.2 + 3.4i"); - TestDump(std::complex(4.5, 6.7), lldb::eFormatComplex, "4.5 + 6.7i"); - - // long double is not tested here because for some platforms we treat it as 10 - // bytes when the compiler allocates 16 bytes of space for it. (see - // DataExtractor::GetLongDouble) Meaning that when we extract the second one, - // it gets the wrong value (it's 6 bytes off). You could manually construct a - // set of bytes to match the 10 byte format but then if the test runs on a - // machine where we don't use 10 it'll break. - - TestDump(llvm::StringRef("aardvark"), lldb::Format::eFormatCString, - "\"aardvark\""); - TestDump(99, lldb::Format::eFormatDecimal, "99"); - // Just prints as a signed integer. - TestDump(-1, lldb::Format::eFormatEnum, "-1"); - TestDump(0xcafef00d, lldb::Format::eFormatHex, "0xcafef00d"); - TestDump(0xcafef00d, lldb::Format::eFormatHexUppercase, "0xCAFEF00D"); - TestDump(0.456, lldb::Format::eFormatFloat, "0.456"); - TestDump(9, lldb::Format::eFormatOctal, "011"); - // Chars packed into an integer. - TestDump(0x4C4C4442, lldb::Format::eFormatOSType, "'LLDB'"); - // Unicode8 doesn't have a specific formatter. - TestDump(0x34, lldb::Format::eFormatUnicode8, "0x34"); - TestDump(0x1122, lldb::Format::eFormatUnicode16, "U+1122"); - TestDump(0x12345678, lldb::Format::eFormatUnicode32, - "U+0x12345678"); - TestDump(654321, lldb::Format::eFormatUnsigned, "654321"); - // This pointer is printed based on the size of uint64_t, so the test is the - // same for 32/64 bit host. - TestDump(0x4444555566667777, lldb::Format::eFormatPointer, - "0x4444555566667777"); - - TestDump(std::vector{'A', '\x01', 'C'}, - lldb::Format::eFormatVectorOfChar, "{A\\x01C}"); - TestDump(std::vector{0, -1, std::numeric_limits::max()}, - lldb::Format::eFormatVectorOfSInt8, "{0 -1 127}"); - TestDump(std::vector{12, 0xFF, 34}, - lldb::Format::eFormatVectorOfUInt8, "{0x0c 0xff 0x22}"); - TestDump(std::vector{-1, 1234, std::numeric_limits::max()}, - lldb::Format::eFormatVectorOfSInt16, "{-1 1234 32767}"); - TestDump(std::vector{0xffff, 0xabcd, 0x1234}, - lldb::Format::eFormatVectorOfUInt16, "{0xffff 0xabcd 0x1234}"); - TestDump(std::vector{0, -1, std::numeric_limits::max()}, - lldb::Format::eFormatVectorOfSInt32, "{0 -1 2147483647}"); - TestDump(std::vector{0, 0xffffffff, 0x1234abcd}, - lldb::Format::eFormatVectorOfUInt32, - "{0x00000000 0xffffffff 0x1234abcd}"); - TestDump(std::vector{0, -1, std::numeric_limits::max()}, - lldb::Format::eFormatVectorOfSInt64, "{0 -1 9223372036854775807}"); - TestDump(std::vector{0, 0xaaaabbbbccccdddd}, - lldb::Format::eFormatVectorOfUInt64, - "{0x0000000000000000 0xaaaabbbbccccdddd}"); - - // See half2float for format details. - // Test zeroes. - TestDump(std::vector{0x0000, 0x8000}, - lldb::Format::eFormatVectorOfFloat16, "{0 -0}"); - // Some subnormal numbers. - TestDump(std::vector{0x0001, 0x8001}, - lldb::Format::eFormatVectorOfFloat16, "{5.96046e-08 -5.96046e-08}"); - // A full mantisse and empty expontent. - TestDump(std::vector{0x83ff, 0x03ff}, - lldb::Format::eFormatVectorOfFloat16, "{-6.09756e-05 6.09756e-05}"); - // Some normal numbers. - TestDump(std::vector{0b0100001001001000}, - lldb::Format::eFormatVectorOfFloat16, -#ifdef _WIN32 - // FIXME: This should print the same on all platforms. - "{3.14063}"); -#else - "{3.14062}"); -#endif - // Largest and smallest normal number. - TestDump(std::vector{0x0400, 0x7bff}, - lldb::Format::eFormatVectorOfFloat16, "{6.10352e-05 65504}"); - TestDump(std::vector{0xabcd, 0x1234}, - lldb::Format::eFormatVectorOfFloat16, "{-0.0609436 0.000757217}"); - - // quiet/signaling NaNs. - TestDump(std::vector{0xffff, 0xffc0, 0x7fff, 0x7fc0}, - lldb::Format::eFormatVectorOfFloat16, "{-nan -nan nan nan}"); - // +/-Inf. - TestDump(std::vector{0xfc00, 0x7c00}, - lldb::Format::eFormatVectorOfFloat16, "{-inf inf}"); - - TestDump(std::vector{std::numeric_limits::min(), - std::numeric_limits::max()}, - lldb::Format::eFormatVectorOfFloat32, "{1.17549e-38 3.40282e+38}"); - TestDump(std::vector{std::numeric_limits::quiet_NaN(), - std::numeric_limits::signaling_NaN(), - -std::numeric_limits::quiet_NaN(), - -std::numeric_limits::signaling_NaN()}, - lldb::Format::eFormatVectorOfFloat32, "{nan nan -nan -nan}"); - TestDump(std::vector{std::numeric_limits::min(), - std::numeric_limits::max()}, - lldb::Format::eFormatVectorOfFloat64, - "{2.2250738585072e-308 1.79769313486232e+308}"); - TestDump( - std::vector{ - std::numeric_limits::quiet_NaN(), - std::numeric_limits::signaling_NaN(), - -std::numeric_limits::quiet_NaN(), - -std::numeric_limits::signaling_NaN(), - }, - lldb::Format::eFormatVectorOfFloat64, "{nan nan -nan -nan}"); - - // Not sure we can rely on having uint128_t everywhere so emulate with - // uint64_t. - TestDump( - std::vector{0x1, 0x1111222233334444, 0xaaaabbbbccccdddd, 0x0}, - lldb::Format::eFormatVectorOfUInt128, - "{0x11112222333344440000000000000001 " - "0x0000000000000000aaaabbbbccccdddd}"); - - TestDump(std::vector{2, 4}, lldb::Format::eFormatComplexInteger, - "2 + 4i"); - - // Without an execution context this just prints the pointer on its own. - TestDump(0x11223344, lldb::Format::eFormatAddressInfo, - "0x11223344"); - - // Input not written in hex form because that requires C++17. - TestDump(10, lldb::Format::eFormatHexFloat, "0x1.4p3"); - TestDump(10, lldb::Format::eFormatHexFloat, "0x1.4p3"); - // long double not supported, see ItemByteSizeErrors. - - // Can't disassemble without an execution context. - TestDump(0xcafef00d, lldb::Format::eFormatInstruction, - "invalid target"); - - // Has no special handling, intended for use elsewhere. - TestDump(99, lldb::Format::eFormatVoid, "0x00000063"); -} - -TEST(DumpDataExtractorTest, FormatCharArray) { - // Unlike the other formats, charArray isn't 1 array of N chars. - // It must be passed as N chars of 1 byte each. - // (eFormatVectorOfChar does this swap for you) - std::vector data{'A', '\x01', '#'}; - StreamString result; - DataBufferHeap dumpbuffer(&data[0], data.size()); - DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), - endian::InlHostByteOrder(), /*addr_size=*/4); - - DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray, - /*item_byte_size=*/1, - /*item_count=*/data.size(), - /*num_per_line=*/data.size(), 0, 0, 0); - ASSERT_EQ("0x00000000: A\\x01#", result.GetString()); - - result.Clear(); - DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray, 1, - data.size(), 1, 0, 0, 0); - // ASSERT macro thinks the split strings are multiple arguments so make a var. - const char *expected = "0x00000000: A\n" - "0x00000001: \\x01\n" - "0x00000002: #"; - ASSERT_EQ(expected, result.GetString()); -} - -template -void TestDumpMultiLine(std::vector data, lldb::Format format, - size_t num_per_line, llvm::StringRef expected) { - size_t sz_bytes = data.size() * sizeof(T); - TestDumpImpl(&data[0], sz_bytes, data.size(), sz_bytes, num_per_line, - 0x80000000, format, expected); -} - -template -void TestDumpMultiLine(const T *data, size_t num_items, lldb::Format format, - size_t num_per_line, llvm::StringRef expected) { - TestDumpImpl(data, sizeof(T) * num_items, sizeof(T), num_items, num_per_line, - 0x80000000, format, expected); -} - -TEST(DumpDataExtractorTest, MultiLine) { - // A vector counts as 1 item regardless of size. - TestDumpMultiLine(std::vector{0x11}, - lldb::Format::eFormatVectorOfUInt8, 1, - "0x80000000: {0x11}"); - TestDumpMultiLine(std::vector{0x11, 0x22}, - lldb::Format::eFormatVectorOfUInt8, 1, - "0x80000000: {0x11 0x22}"); - - // If you have multiple vectors then that's multiple items. - // Here we say that these 2 bytes are actually 2 1 byte vectors. - const std::vector vector_data{0x11, 0x22}; - TestDumpMultiLine(vector_data.data(), 2, lldb::Format::eFormatVectorOfUInt8, - 1, "0x80000000: {0x11}\n0x80000001: {0x22}"); - - // Single value formats can span multiple lines. - const std::vector bytes{0x11, 0x22, 0x33}; - const char *expected_bytes_3_line = "0x80000000: 0x11\n" - "0x80000001: 0x22\n" - "0x80000002: 0x33"; - TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 1, - expected_bytes_3_line); - - // Lines may not have the full number of items. - TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 4, - "0x80000000: 0x11 0x22 0x33"); - const char *expected_bytes_2_line = "0x80000000: 0x11 0x22\n" - "0x80000002: 0x33"; - TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 2, - expected_bytes_2_line); - - // The line address accounts for item sizes other than 1 byte. - const std::vector shorts{0x1111, 0x2222, 0x3333}; - const char *expected_shorts_2_line = "0x80000000: 0x1111 0x2222\n" - "0x80000004: 0x3333"; - TestDumpMultiLine(shorts.data(), shorts.size(), lldb::Format::eFormatHex, 2, - expected_shorts_2_line); - - // The ascii column is positioned using the maximum line length. - const std::vector chars{'L', 'L', 'D', 'B'}; - const char *expected_chars_2_lines = "0x80000000: 4c 4c 44 LLD\n" - "0x80000003: 42 B"; - TestDumpMultiLine(chars.data(), chars.size(), - lldb::Format::eFormatBytesWithASCII, 3, - expected_chars_2_lines); -} - -void TestDumpWithItemByteSize(size_t item_byte_size, lldb::Format format, - llvm::StringRef expected) { - // We won't be reading this data so anything will do. - uint8_t dummy = 0; - TestDumpImpl(&dummy, 1, item_byte_size, 1, 1, LLDB_INVALID_ADDRESS, format, - expected); -} - -TEST(DumpDataExtractorTest, ItemByteSizeErrors) { - TestDumpWithItemByteSize( - 16, lldb::Format::eFormatBoolean, - "error: unsupported byte size (16) for boolean format"); - TestDumpWithItemByteSize(21, lldb::Format::eFormatChar, - "error: unsupported byte size (21) for char format"); - TestDumpWithItemByteSize( - 18, lldb::Format::eFormatComplexInteger, - "error: unsupported byte size (18) for complex integer format"); - - // The code uses sizeof(long double) for these checks. This changes by host - // but we know it won't be >16. - TestDumpWithItemByteSize( - 34, lldb::Format::eFormatComplex, - "error: unsupported byte size (34) for complex float format"); - TestDumpWithItemByteSize( - 18, lldb::Format::eFormatFloat, - "error: unsupported byte size (18) for float format"); - - // We want sizes to exactly match one of float/double. - TestDumpWithItemByteSize( - 14, lldb::Format::eFormatComplex, - "error: unsupported byte size (14) for complex float format"); - TestDumpWithItemByteSize(3, lldb::Format::eFormatFloat, - "error: unsupported byte size (3) for float format"); - - // We only allow float and double size. - TestDumpWithItemByteSize( - 1, lldb::Format::eFormatHexFloat, - "error: unsupported byte size (1) for hex float format"); - TestDumpWithItemByteSize( - 17, lldb::Format::eFormatHexFloat, - "error: unsupported byte size (17) for hex float format"); -} diff --git a/gnu/llvm/lldb/unittests/Core/FormatEntityTest.cpp b/gnu/llvm/lldb/unittests/Core/FormatEntityTest.cpp deleted file mode 100644 index c22dd439957..00000000000 --- a/gnu/llvm/lldb/unittests/Core/FormatEntityTest.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//===-- FormatEntityTest.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 "lldb/Core/FormatEntity.h" -#include "lldb/Utility/Status.h" - -#include "llvm/ADT/StringRef.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -using Definition = FormatEntity::Entry::Definition; -using Entry = FormatEntity::Entry; - -TEST(FormatEntityTest, DefinitionConstructionNameAndType) { - Definition d("foo", FormatEntity::Entry::Type::Invalid); - - EXPECT_EQ(d.name, "foo"); - EXPECT_EQ(d.string, nullptr); - EXPECT_EQ(d.type, FormatEntity::Entry::Type::Invalid); - EXPECT_EQ(d.data, 0UL); - EXPECT_EQ(d.num_children, 0UL); - EXPECT_EQ(d.children, nullptr); - EXPECT_FALSE(d.keep_separator); -} - -TEST(FormatEntityTest, DefinitionConstructionNameAndString) { - Definition d("foo", "string"); - - EXPECT_EQ(d.name, "foo"); - EXPECT_EQ(d.string, "string"); - EXPECT_EQ(d.type, FormatEntity::Entry::Type::EscapeCode); - EXPECT_EQ(d.data, 0UL); - EXPECT_EQ(d.num_children, 0UL); - EXPECT_EQ(d.children, nullptr); - EXPECT_FALSE(d.keep_separator); -} - -TEST(FormatEntityTest, DefinitionConstructionNameTypeData) { - Definition d("foo", FormatEntity::Entry::Type::Invalid, 33); - - EXPECT_EQ(d.name, "foo"); - EXPECT_EQ(d.string, nullptr); - EXPECT_EQ(d.type, FormatEntity::Entry::Type::Invalid); - EXPECT_EQ(d.data, 33UL); - EXPECT_EQ(d.num_children, 0UL); - EXPECT_EQ(d.children, nullptr); - EXPECT_FALSE(d.keep_separator); -} - -TEST(FormatEntityTest, DefinitionConstructionNameTypeChildren) { - Definition d("foo", FormatEntity::Entry::Type::Invalid, 33); - Definition parent("parent", FormatEntity::Entry::Type::Invalid, 1, &d); - EXPECT_EQ(parent.name, "parent"); - EXPECT_EQ(parent.string, nullptr); - EXPECT_EQ(parent.type, FormatEntity::Entry::Type::Invalid); - EXPECT_EQ(parent.num_children, 1UL); - EXPECT_EQ(parent.children, &d); - EXPECT_FALSE(parent.keep_separator); - - EXPECT_EQ(parent.children[0].name, "foo"); - EXPECT_EQ(parent.children[0].string, nullptr); - EXPECT_EQ(parent.children[0].type, FormatEntity::Entry::Type::Invalid); - EXPECT_EQ(parent.children[0].data, 33UL); - EXPECT_EQ(parent.children[0].num_children, 0UL); - EXPECT_EQ(parent.children[0].children, nullptr); - EXPECT_FALSE(d.keep_separator); -} - -constexpr llvm::StringRef lookupStrings[] = { - "${addr.load}", - "${addr.file}", - "${ansi.fg.black}", - "${ansi.fg.red}", - "${ansi.fg.green}", - "${ansi.fg.yellow}", - "${ansi.fg.blue}", - "${ansi.fg.purple}", - "${ansi.fg.cyan}", - "${ansi.fg.white}", - "${ansi.bg.black}", - "${ansi.bg.red}", - "${ansi.bg.green}", - "${ansi.bg.yellow}", - "${ansi.bg.blue}", - "${ansi.bg.purple}", - "${ansi.bg.cyan}", - "${ansi.bg.white}", - "${file.basename}", - "${file.dirname}", - "${file.fullpath}", - "${frame.index}", - "${frame.pc}", - "${frame.fp}", - "${frame.sp}", - "${frame.flags}", - "${frame.no-debug}", - "${frame.reg.*}", - "${frame.is-artificial}", - "${function.id}", - "${function.name}", - "${function.name-without-args}", - "${function.name-with-args}", - "${function.mangled-name}", - "${function.addr-offset}", - "${function.concrete-only-addr-offset-no-padding}", - "${function.line-offset}", - "${function.pc-offset}", - "${function.initial-function}", - "${function.changed}", - "${function.is-optimized}", - "${line.file.basename}", - "${line.file.dirname}", - "${line.file.fullpath}", - "${line.number}", - "${line.column}", - "${line.start-addr}", - "${line.end-addr}", - "${module.file.basename}", - "${module.file.dirname}", - "${module.file.fullpath}", - "${process.id}", - "${process.name}", - "${process.file.basename}", - "${process.file.dirname}", - "${process.file.fullpath}", - "${script.frame}", - "${script.process}", - "${script.target}", - "${script.thread}", - "${script.var}", - "${script.svar}", - "${script.thread}", - "${svar.dummy-svar-to-test-wildcard}", - "${thread.id}", - "${thread.protocol_id}", - "${thread.index}", - "${thread.info.*}", - "${thread.queue}", - "${thread.name}", - "${thread.stop-reason}", - "${thread.stop-reason-raw}", - "${thread.return-value}", - "${thread.completed-expression}", - "${target.arch}", - "${var.dummy-var-to-test-wildcard}"}; - -TEST(FormatEntity, LookupAllEntriesInTree) { - for (const llvm::StringRef testString : lookupStrings) { - Entry e; - EXPECT_TRUE(FormatEntity::Parse(testString, e).Success()) - << "Formatting " << testString << " did not succeed"; - } -} diff --git a/gnu/llvm/lldb/unittests/Core/MangledTest.cpp b/gnu/llvm/lldb/unittests/Core/MangledTest.cpp deleted file mode 100644 index 431993fccb1..00000000000 --- a/gnu/llvm/lldb/unittests/Core/MangledTest.cpp +++ /dev/null @@ -1,266 +0,0 @@ -//===-- MangledTest.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 "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" - -#include "lldb/Core/Mangled.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/SymbolContext.h" - -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/Testing/Support/Error.h" - -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(MangledTest, ResultForValidName) { - ConstString MangledName("_ZN1a1b1cIiiiEEvm"); - Mangled TheMangled(MangledName); - ConstString TheDemangled = TheMangled.GetDemangledName(); - - ConstString ExpectedResult("void a::b::c(unsigned long)"); - EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString()); -} - -TEST(MangledTest, ResultForBlockInvocation) { - ConstString MangledName("___Z1fU13block_pointerFviE_block_invoke"); - Mangled TheMangled(MangledName); - ConstString TheDemangled = TheMangled.GetDemangledName(); - - ConstString ExpectedResult( - "invocation function for block in f(void (int) block_pointer)"); - EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString()); -} - -TEST(MangledTest, EmptyForInvalidName) { - ConstString MangledName("_ZN1a1b1cmxktpEEvm"); - Mangled TheMangled(MangledName); - ConstString TheDemangled = TheMangled.GetDemangledName(); - - EXPECT_STREQ("", TheDemangled.GetCString()); -} - -TEST(MangledTest, ResultForValidRustV0Name) { - ConstString mangled_name("_RNvC1a4main"); - Mangled the_mangled(mangled_name); - ConstString the_demangled = the_mangled.GetDemangledName(); - - ConstString expected_result("a::main"); - EXPECT_STREQ(expected_result.GetCString(), the_demangled.GetCString()); -} - -TEST(MangledTest, EmptyForInvalidRustV0Name) { - ConstString mangled_name("_RRR"); - Mangled the_mangled(mangled_name); - ConstString the_demangled = the_mangled.GetDemangledName(); - - EXPECT_STREQ("", the_demangled.GetCString()); -} - -TEST(MangledTest, NameIndexes_FindFunctionSymbols) { - SubsystemRAII - subsystems; - - auto ExpectedFile = TestFile::fromYaml(R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_X86_64 -Sections: - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - AddressAlign: 0x0000000000000010 - Size: 0x20 - - Name: .anothertext - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - Address: 0x0000000000000010 - AddressAlign: 0x0000000000000010 - Size: 0x40 - - Name: .data - Type: SHT_PROGBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x00000000000000A8 - AddressAlign: 0x0000000000000004 - Content: '01000000' -Symbols: - - Name: somedata - Type: STT_OBJECT - Section: .anothertext - Value: 0x0000000000000045 - Binding: STB_GLOBAL - - Name: main - Type: STT_FUNC - Section: .anothertext - Value: 0x0000000000000010 - Size: 0x000000000000003F - Binding: STB_GLOBAL - - Name: _Z3foov - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: puts@GLIBC_2.5 - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: puts@GLIBC_2.6 - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _Z5annotv@VERSION3 - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _ZN1AC2Ev - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _ZN1AD2Ev - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _ZN1A3barEv - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _ZGVZN4llvm4dbgsEvE7thestrm - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _ZZN4llvm4dbgsEvE7thestrm - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _ZTVN5clang4DeclE - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: -[ObjCfoo] - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: +[B ObjCbar(WithCategory)] - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL - - Name: _Z12undemangableEvx42 - Type: STT_FUNC - Section: .text - Size: 0x000000000000000D - Binding: STB_GLOBAL -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto M = std::make_shared(ExpectedFile->moduleSpec()); - - auto Count = [M](const char *Name, FunctionNameType Type) -> int { - SymbolContextList SymList; - M->FindFunctionSymbols(ConstString(Name), Type, SymList); - return SymList.GetSize(); - }; - - // Unmangled - EXPECT_EQ(1, Count("main", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("main", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("main", eFunctionNameTypeMethod)); - - // Itanium mangled - EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeBase)); - EXPECT_EQ(1, Count("foo", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("foo", eFunctionNameTypeMethod)); - - // Unmangled with linker annotation - EXPECT_EQ(1, Count("puts@GLIBC_2.5", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("puts@GLIBC_2.6", eFunctionNameTypeFull)); - EXPECT_EQ(2, Count("puts", eFunctionNameTypeFull)); - EXPECT_EQ(2, Count("puts", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("puts", eFunctionNameTypeMethod)); - - // Itanium mangled with linker annotation - EXPECT_EQ(1, Count("_Z5annotv@VERSION3", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("annot", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("annot", eFunctionNameTypeMethod)); - - // Itanium mangled ctor A::A() - EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeBase)); - EXPECT_EQ(1, Count("A", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("A", eFunctionNameTypeBase)); - - // Itanium mangled dtor A::~A() - EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeBase)); - EXPECT_EQ(1, Count("~A", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("~A", eFunctionNameTypeBase)); - - // Itanium mangled method A::bar() - EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeBase)); - EXPECT_EQ(1, Count("bar", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("bar", eFunctionNameTypeBase)); - - // Itanium mangled names that are explicitly excluded from parsing - EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase)); - EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase)); - EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("Decl", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("Decl", eFunctionNameTypeBase)); - - // ObjC mangled static - EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("ObjCfoo", eFunctionNameTypeMethod)); - - // ObjC mangled method with category - EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("ObjCbar", eFunctionNameTypeMethod)); - - // Invalid things: unable to decode but still possible to find by full name - EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeFull)); - EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("_Z12undemangableEvx42", eFunctionNameTypeMethod)); - EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeBase)); - EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeMethod)); -} diff --git a/gnu/llvm/lldb/unittests/Core/ModuleSpecTest.cpp b/gnu/llvm/lldb/unittests/Core/ModuleSpecTest.cpp deleted file mode 100644 index f9e19ed35ac..00000000000 --- a/gnu/llvm/lldb/unittests/Core/ModuleSpecTest.cpp +++ /dev/null @@ -1,166 +0,0 @@ -//===-- ModuleSpecTest.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 "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Utility/DataBuffer.h" - -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" -#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" - -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -extern const char *TestMainArgv0; - -// This test file intentionally doesn't initialize the FileSystem. -// Everything in this file should be able to run without requiring -// any interaction with the FileSystem class; by keeping it -// uninitialized, it will assert if anything tries to interact with -// it. - -TEST(ModuleSpecTest, InvalidInMemoryBuffer) { - uint8_t Invalid[] = "This is not a binary file."; - DataBufferSP InvalidBufferSP = - std::make_shared(Invalid, sizeof(Invalid)); - ModuleSpec Spec(FileSpec(), UUID(), InvalidBufferSP); - - auto InvalidModuleSP = std::make_shared(Spec); - ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr); -} - -TEST(ModuleSpecTest, InvalidInMemoryBufferValidFile) { - uint8_t Invalid[] = "This is not a binary file."; - DataBufferSP InvalidBufferSP = - std::make_shared(Invalid, sizeof(Invalid)); - ModuleSpec Spec(FileSpec(TestMainArgv0), UUID(), InvalidBufferSP); - - auto InvalidModuleSP = std::make_shared(Spec); - ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr); -} - -TEST(ModuleSpecTest, TestELFFile) { - SubsystemRAII subsystems; - - auto ExpectedFile = TestFile::fromYaml(R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 -Sections: - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - AddressAlign: 0x0000000000000010 -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto M = std::make_shared(ExpectedFile->moduleSpec()); - ObjectFile *OF = M->GetObjectFile(); - - ASSERT_EQ(llvm::isa(OF), true); -} - -TEST(ModuleSpecTest, TestCOFFFile) { - SubsystemRAII subsystems; - - auto ExpectedFile = TestFile::fromYaml(R"( ---- !COFF -OptionalHeader: - AddressOfEntryPoint: 0 - ImageBase: 16777216 - SectionAlignment: 4096 - FileAlignment: 512 - MajorOperatingSystemVersion: 6 - MinorOperatingSystemVersion: 0 - MajorImageVersion: 0 - MinorImageVersion: 0 - MajorSubsystemVersion: 6 - MinorSubsystemVersion: 0 - Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI - DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ] - SizeOfStackReserve: 1048576 - SizeOfStackCommit: 4096 - SizeOfHeapReserve: 1048576 - SizeOfHeapCommit: 4096 -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - VirtualAddress: 4096 - VirtualSize: 4096 -symbols: [] -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto M = std::make_shared(ExpectedFile->moduleSpec()); - ObjectFile *OF = M->GetObjectFile(); - - ASSERT_EQ(llvm::isa(OF), true); -} - -TEST(ModuleSpecTest, TestMachOFile) { - SubsystemRAII subsystems; - - auto ExpectedFile = TestFile::fromYaml(R"( ---- !mach-o -FileHeader: - magic: 0xFEEDFACF - cputype: 0x0100000C - cpusubtype: 0x00000000 - filetype: 0x00000001 - ncmds: 1 - sizeofcmds: 232 - flags: 0x00002000 - reserved: 0x00000000 -LoadCommands: - - cmd: LC_SEGMENT_64 - cmdsize: 232 - segname: '' - vmaddr: 0 - vmsize: 56 - fileoff: 392 - filesize: 56 - maxprot: 7 - initprot: 7 - nsects: 1 - flags: 0 - Sections: - - sectname: __text - segname: __TEXT - addr: 0x0000000000000000 - size: 24 - offset: 0x00000188 - align: 2 - reloff: 0x00000000 - nreloc: 0 - flags: 0x80000400 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto M = std::make_shared(ExpectedFile->moduleSpec()); - ObjectFile *OF = M->GetObjectFile(); - - ASSERT_EQ(llvm::isa(OF), true); -} diff --git a/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp b/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp deleted file mode 100644 index f8a0bbf9102..00000000000 --- a/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp +++ /dev/null @@ -1,139 +0,0 @@ -//===-- RichManglingContextTest.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 "lldb/Core/RichManglingContext.h" - -#include "lldb/Utility/ConstString.h" - -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(RichManglingContextTest, Basic) { - RichManglingContext RMC; - ConstString mangled("_ZN3foo3barEv"); - EXPECT_TRUE(RMC.FromItaniumName(mangled)); - - EXPECT_TRUE(RMC.IsFunction()); - EXPECT_FALSE(RMC.IsCtorOrDtor()); - - RMC.ParseFunctionDeclContextName(); - EXPECT_EQ("foo", RMC.GetBufferRef()); - - RMC.ParseFunctionBaseName(); - EXPECT_EQ("bar", RMC.GetBufferRef()); - - RMC.ParseFullName(); - EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); -} - -TEST(RichManglingContextTest, FromCxxMethodName) { - RichManglingContext ItaniumRMC; - ConstString mangled("_ZN3foo3barEv"); - EXPECT_TRUE(ItaniumRMC.FromItaniumName(mangled)); - - RichManglingContext CxxMethodRMC; - ConstString demangled("foo::bar()"); - EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(demangled)); - - EXPECT_TRUE(ItaniumRMC.IsFunction() == CxxMethodRMC.IsFunction()); - EXPECT_TRUE(ItaniumRMC.IsCtorOrDtor() == CxxMethodRMC.IsCtorOrDtor()); - - ItaniumRMC.ParseFunctionDeclContextName(); - CxxMethodRMC.ParseFunctionDeclContextName(); - EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef()); - - ItaniumRMC.ParseFunctionBaseName(); - CxxMethodRMC.ParseFunctionBaseName(); - EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef()); - - ItaniumRMC.ParseFullName(); - CxxMethodRMC.ParseFullName(); - EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef()); - - // Construct with a random name. - { - RichManglingContext CxxMethodRMC; - EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(ConstString("X"))); - - // We expect it is not a function. - EXPECT_FALSE(CxxMethodRMC.IsFunction()); - } - - // Construct with a function without a context. - { - RichManglingContext CxxMethodRMC; - EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName( - ConstString("void * operator new(unsigned __int64)"))); - - // We expect it is a function. - EXPECT_TRUE(CxxMethodRMC.IsFunction()); - - // We expect its context is empty. - CxxMethodRMC.ParseFunctionDeclContextName(); - EXPECT_TRUE(CxxMethodRMC.GetBufferRef().empty()); - } -} - -TEST(RichManglingContextTest, SwitchProvider) { - RichManglingContext RMC; - llvm::StringRef mangled = "_ZN3foo3barEv"; - llvm::StringRef demangled = "foo::bar()"; - - EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled))); - RMC.ParseFullName(); - EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); - - EXPECT_TRUE(RMC.FromCxxMethodName(ConstString(demangled))); - RMC.ParseFullName(); - EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); - - EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled))); - RMC.ParseFullName(); - EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); -} - -TEST(RichManglingContextTest, IPDRealloc) { - // The demangled name should fit into the Itanium default buffer. - const char *ShortMangled = "_ZN3foo3barEv"; - - // The demangled name for this will certainly not fit into the default buffer. - const char *LongMangled = - "_ZNK3shk6detail17CallbackPublisherIZNS_5ThrowERKNSt15__exception_" - "ptr13exception_ptrEEUlOT_E_E9SubscribeINS0_9ConcatMapINS0_" - "18CallbackSubscriberIZNS_6GetAllIiNS1_IZZNS_9ConcatMapIZNS_6ConcatIJNS1_" - "IZZNS_3MapIZZNS_7IfEmptyIS9_EEDaS7_ENKUlS6_E_clINS1_IZZNS_4TakeIiEESI_" - "S7_ENKUlS6_E_clINS1_IZZNS_6FilterIZNS_9ElementAtEmEUlS7_E_EESI_S7_" - "ENKUlS6_E_clINS1_IZZNSL_ImEESI_S7_ENKUlS6_E_clINS1_IZNS_4FromINS0_" - "22InfiniteRangeContainerIiEEEESI_S7_EUlS7_E_EEEESI_S6_EUlS7_E_EEEESI_S6_" - "EUlS7_E_EEEESI_S6_EUlS7_E_EEEESI_S6_EUlS7_E_EESI_S7_ENKUlS6_E_clIS14_" - "EESI_S6_EUlS7_E_EERNS1_IZZNSH_IS9_EESI_S7_ENKSK_IS14_EESI_S6_EUlS7_E0_" - "EEEEESI_DpOT_EUlS7_E_EESI_S7_ENKUlS6_E_clINS1_IZNS_5StartIJZNS_" - "4JustIJS19_S1C_EEESI_S1F_EUlvE_ZNS1K_IJS19_S1C_EEESI_S1F_EUlvE0_EEESI_" - "S1F_EUlS7_E_EEEESI_S6_EUlS7_E_EEEESt6vectorIS6_SaIS6_EERKT0_NS_" - "12ElementCountEbEUlS7_E_ZNSD_IiS1Q_EES1T_S1W_S1X_bEUlOS3_E_ZNSD_IiS1Q_" - "EES1T_S1W_S1X_bEUlvE_EES1G_S1O_E25ConcatMapValuesSubscriberEEEDaS7_"; - - RichManglingContext RMC; - - // Demangle the short one. - EXPECT_TRUE(RMC.FromItaniumName(ConstString(ShortMangled))); - RMC.ParseFullName(); - const char *ShortDemangled = RMC.GetBufferRef().data(); - - // Demangle the long one. - EXPECT_TRUE(RMC.FromItaniumName(ConstString(LongMangled))); - RMC.ParseFullName(); - const char *LongDemangled = RMC.GetBufferRef().data(); - - // Make sure a new buffer was allocated or the default buffer was extended. - bool AllocatedNewBuffer = (ShortDemangled != LongDemangled); - bool ExtendedExistingBuffer = (strlen(LongDemangled) > 2048); - EXPECT_TRUE(AllocatedNewBuffer || ExtendedExistingBuffer); -} diff --git a/gnu/llvm/lldb/unittests/Core/SourceLocationSpecTest.cpp b/gnu/llvm/lldb/unittests/Core/SourceLocationSpecTest.cpp deleted file mode 100644 index b79662f865f..00000000000 --- a/gnu/llvm/lldb/unittests/Core/SourceLocationSpecTest.cpp +++ /dev/null @@ -1,183 +0,0 @@ -//===-- SourceLocationSpecTest.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 "gtest/gtest.h" - -#include "lldb/Core/SourceLocationSpec.h" -#include "lldb/Utility/LLDBAssert.h" - -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private; - -TEST(SourceLocationSpecTest, OperatorBool) { - SourceLocationSpec invalid(FileSpec(), 0); - EXPECT_FALSE(invalid); - - SourceLocationSpec invalid_filespec(FileSpec(), 4); - EXPECT_FALSE(invalid_filespec); - - SourceLocationSpec invalid_line(FileSpec("/foo/bar"), 0); - EXPECT_FALSE(invalid_line); - - SourceLocationSpec valid_fs_line_no_column(FileSpec("/foo/bar"), 4); - EXPECT_TRUE(valid_fs_line_no_column); - - SourceLocationSpec invalid_fs_column(FileSpec(), 4, 0); - EXPECT_FALSE(invalid_fs_column); - - SourceLocationSpec invalid_line_column(FileSpec("/foo/bar"), 0, 19); - EXPECT_FALSE(invalid_line_column); - - SourceLocationSpec valid_fs_line_zero_column(FileSpec("/foo/bar"), 4, 0); - EXPECT_TRUE(valid_fs_line_zero_column); - - SourceLocationSpec valid_fs_line_column(FileSpec("/foo/bar"), 4, 19); - EXPECT_TRUE(valid_fs_line_column); -} - -TEST(SourceLocationSpecTest, FileLineColumnComponents) { - FileSpec fs("/foo/bar", FileSpec::Style::posix); - const uint32_t line = 19; - const uint16_t column = 4; - - SourceLocationSpec without_column(fs, line, LLDB_INVALID_COLUMN_NUMBER, false, - true); - EXPECT_TRUE(without_column); - EXPECT_EQ(fs, without_column.GetFileSpec()); - EXPECT_EQ(line, without_column.GetLine().getValueOr(0)); - EXPECT_EQ(llvm::None, without_column.GetColumn()); - EXPECT_FALSE(without_column.GetCheckInlines()); - EXPECT_TRUE(without_column.GetExactMatch()); - EXPECT_STREQ("check inlines = false, exact match = true, decl = /foo/bar:19", - without_column.GetString().c_str()); - - SourceLocationSpec with_column(fs, line, column, true, false); - EXPECT_TRUE(with_column); - EXPECT_EQ(column, *with_column.GetColumn()); - EXPECT_TRUE(with_column.GetCheckInlines()); - EXPECT_FALSE(with_column.GetExactMatch()); - EXPECT_STREQ( - "check inlines = true, exact match = false, decl = /foo/bar:19:4", - with_column.GetString().c_str()); -} - -static SourceLocationSpec Create(bool check_inlines, bool exact_match, - FileSpec fs, uint32_t line, - uint16_t column = LLDB_INVALID_COLUMN_NUMBER) { - return SourceLocationSpec(fs, line, column, check_inlines, exact_match); -} - -TEST(SourceLocationSpecTest, Equal) { - auto Equal = [](SourceLocationSpec lhs, SourceLocationSpec rhs, bool full) { - return SourceLocationSpec::Equal(lhs, rhs, full); - }; - - const FileSpec fs("/foo/bar", FileSpec::Style::posix); - const FileSpec other_fs("/foo/baz", FileSpec::Style::posix); - - // mutating FileSpec + const Inlined, ExactMatch, Line - EXPECT_TRUE( - Equal(Create(false, false, fs, 4), Create(false, false, fs, 4), true)); - EXPECT_TRUE( - Equal(Create(true, true, fs, 4), Create(true, true, fs, 4), false)); - EXPECT_FALSE(Equal(Create(false, false, fs, 4), - Create(false, false, other_fs, 4), true)); - EXPECT_FALSE( - Equal(Create(true, true, fs, 4), Create(true, true, other_fs, 4), false)); - - // Mutating FileSpec + const Inlined, ExactMatch, Line, Column - EXPECT_TRUE(Equal(Create(false, false, fs, 4, 19), - Create(false, false, fs, 4, 19), true)); - EXPECT_TRUE(Equal(Create(true, true, fs, 4, 19), - Create(true, true, fs, 4, 19), false)); - EXPECT_FALSE(Equal(Create(false, false, fs, 4, 19), - Create(false, false, other_fs, 4, 19), true)); - EXPECT_FALSE(Equal(Create(true, true, fs, 4, 19), - Create(true, true, other_fs, 4, 19), false)); - - // Asymetric match - EXPECT_FALSE( - Equal(Create(true, true, fs, 4), Create(true, true, fs, 4, 19), true)); - EXPECT_TRUE(Equal(Create(false, false, fs, 4), - Create(false, false, fs, 4, 19), false)); - - // Mutating Inlined, ExactMatch - EXPECT_FALSE( - Equal(Create(true, false, fs, 4), Create(false, true, fs, 4), true)); - EXPECT_TRUE( - Equal(Create(false, true, fs, 4), Create(true, false, fs, 4), false)); - - // Mutating Column - EXPECT_FALSE(Equal(Create(true, true, fs, 4, 96), - Create(true, true, fs, 4, 19), true)); - EXPECT_TRUE(Equal(Create(false, false, fs, 4, 96), - Create(false, false, fs, 4, 19), false)); -} - -TEST(SourceLocationSpecTest, Compare) { - auto Cmp = [](SourceLocationSpec a, SourceLocationSpec b) { - return SourceLocationSpec::Compare(a, b); - }; - - FileSpec fs("/foo/bar", FileSpec::Style::posix); - FileSpec other_fs("/foo/baz", FileSpec::Style::posix); - - // Asymetric comparaison - EXPECT_EQ(-1, Cmp(Create(true, true, fs, 4), Create(true, true, fs, 4, 19))); - EXPECT_EQ(-1, - Cmp(Create(false, false, fs, 4), Create(false, false, fs, 4, 19))); - EXPECT_EQ(1, Cmp(Create(true, true, fs, 4, 19), Create(true, true, fs, 4))); - - // Mutating FS, const Line - EXPECT_EQ( - -1, Cmp(Create(false, false, fs, 4), Create(false, false, other_fs, 4))); - EXPECT_EQ(-1, - Cmp(Create(true, true, fs, 4), Create(true, true, other_fs, 4))); - EXPECT_EQ(1, - Cmp(Create(false, true, other_fs, 4), Create(false, true, fs, 4))); - EXPECT_EQ(1, - Cmp(Create(true, false, other_fs, 4), Create(true, false, fs, 4))); - - // Const FS, mutating Line - EXPECT_EQ(-1, Cmp(Create(false, false, fs, 1), Create(false, false, fs, 4))); - EXPECT_EQ(-1, Cmp(Create(true, true, fs, 1), Create(true, true, fs, 4))); - EXPECT_EQ(0, Cmp(Create(false, true, fs, 4), Create(false, true, fs, 4))); - EXPECT_EQ(0, Cmp(Create(true, false, fs, 4), Create(true, false, fs, 4))); - EXPECT_EQ(1, Cmp(Create(false, false, fs, 4), Create(false, false, fs, 1))); - EXPECT_EQ(1, Cmp(Create(true, true, fs, 4), Create(true, true, fs, 1))); - - // Const FS, mutating Line, const Column - EXPECT_EQ(-1, - Cmp(Create(false, true, fs, 1), Create(false, true, fs, 4, 19))); - EXPECT_EQ(-1, Cmp(Create(true, true, fs, 1), Create(true, true, fs, 4, 19))); - EXPECT_EQ(1, Cmp(Create(true, false, fs, 4, 19), Create(true, false, fs, 1))); - EXPECT_EQ(1, Cmp(Create(true, false, fs, 4, 19), Create(true, false, fs, 1))); - - // Mutating FS, const Line, const Column - EXPECT_EQ(-1, Cmp(Create(false, false, fs, 4, 19), - Create(false, false, other_fs, 4, 19))); - EXPECT_EQ(-1, Cmp(Create(true, true, fs, 4, 19), - Create(true, true, other_fs, 4, 19))); - EXPECT_EQ( - 0, Cmp(Create(false, false, fs, 4, 19), Create(false, false, fs, 4, 19))); - EXPECT_EQ(0, - Cmp(Create(true, true, fs, 4, 19), Create(true, true, fs, 4, 19))); - EXPECT_EQ(1, Cmp(Create(false, true, other_fs, 4, 19), - Create(false, true, fs, 4, 19))); - EXPECT_EQ(1, Cmp(Create(true, false, other_fs, 4, 19), - Create(true, false, fs, 4, 19))); - - // Const FS, const Line, mutating Column - EXPECT_EQ(-1, Cmp(Create(false, false, fs, 4, 19), - Create(false, false, fs, 4, 96))); - EXPECT_EQ(1, - Cmp(Create(true, true, fs, 4, 96), Create(true, true, fs, 4, 19))); - EXPECT_EQ( - 1, Cmp(Create(false, true, fs, 4, 96), Create(false, true, fs, 4, 19))); -} diff --git a/gnu/llvm/lldb/unittests/Core/SourceManagerTest.cpp b/gnu/llvm/lldb/unittests/Core/SourceManagerTest.cpp deleted file mode 100644 index 9dcd048ce3f..00000000000 --- a/gnu/llvm/lldb/unittests/Core/SourceManagerTest.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===-- SourceManagerTest.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 "lldb/Core/SourceManager.h" -#include "lldb/Host/FileSystem.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -class SourceFileCache : public ::testing::Test { -public: - void SetUp() override { FileSystem::Initialize(); } - void TearDown() override { FileSystem::Terminate(); } -}; - -TEST_F(SourceFileCache, FindSourceFileFound) { - SourceManager::SourceFileCache cache; - - // Insert: foo - FileSpec foo_file_spec("foo"); - auto foo_file_sp = - std::make_shared(foo_file_spec, nullptr); - cache.AddSourceFile(foo_file_sp); - - // Query: foo, expect found. - FileSpec another_foo_file_spec("foo"); - ASSERT_EQ(cache.FindSourceFile(another_foo_file_spec), foo_file_sp); -} - -TEST_F(SourceFileCache, FindSourceFileNotFound) { - SourceManager::SourceFileCache cache; - - // Insert: foo - FileSpec foo_file_spec("foo"); - auto foo_file_sp = - std::make_shared(foo_file_spec, nullptr); - cache.AddSourceFile(foo_file_sp); - - // Query: bar, expect not found. - FileSpec bar_file_spec("bar"); - ASSERT_EQ(cache.FindSourceFile(bar_file_spec), nullptr); -} diff --git a/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp b/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp deleted file mode 100644 index d0e50b6864d..00000000000 --- a/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===-- StreamCallbackTest.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 "lldb/Utility/StreamCallback.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -static char test_baton; -static size_t callback_count = 0; -static void TestCallback(const char *data, void *baton) { - EXPECT_STREQ("Foobar", data); - EXPECT_EQ(&test_baton, baton); - ++callback_count; -} - -TEST(StreamCallbackTest, Callback) { - StreamCallback stream(TestCallback, &test_baton); - stream << "Foobar"; - EXPECT_EQ(1u, callback_count); -} diff --git a/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp b/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp deleted file mode 100644 index 25bc28538e6..00000000000 --- a/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//===-- UniqueCStringMapTest.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 "lldb/Core/UniqueCStringMap.h" -#include "gmock/gmock.h" - -using namespace lldb_private; - -namespace { -struct NoDefault { - int x; - - NoDefault(int x) : x(x) {} - NoDefault() = delete; - - friend bool operator==(NoDefault lhs, NoDefault rhs) { - return lhs.x == rhs.x; - } - - friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, - NoDefault x) { - return OS << "NoDefault{" << x.x << "}"; - } -}; -} // namespace - -TEST(UniqueCStringMap, NoDefaultConstructor) { - using MapT = UniqueCStringMap; - using EntryT = MapT::Entry; - - MapT Map; - ConstString Foo("foo"), Bar("bar"); - - Map.Append(Foo, NoDefault(42)); - EXPECT_THAT(Map.Find(Foo, NoDefault(47)), NoDefault(42)); - EXPECT_THAT(Map.Find(Bar, NoDefault(47)), NoDefault(47)); - EXPECT_THAT(Map.FindFirstValueForName(Foo), - testing::Pointee(testing::Field(&EntryT::value, NoDefault(42)))); - EXPECT_THAT(Map.FindFirstValueForName(Bar), nullptr); - - std::vector Values; - EXPECT_THAT(Map.GetValues(Foo, Values), 1); - EXPECT_THAT(Values, testing::ElementsAre(NoDefault(42))); - - Values.clear(); - EXPECT_THAT(Map.GetValues(Bar, Values), 0); - EXPECT_THAT(Values, testing::IsEmpty()); -} diff --git a/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt b/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt deleted file mode 100644 index 9d967a72bfd..00000000000 --- a/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_lldb_unittest(LLDBFormatterTests - FormatManagerTests.cpp - FormattersContainerTest.cpp - StringPrinterTests.cpp - - LINK_LIBS - lldbCore - lldbInterpreter - lldbSymbol - lldbTarget - lldbUtility - - LINK_COMPONENTS - Support - ) diff --git a/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp b/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp deleted file mode 100644 index e9dd4af610d..00000000000 --- a/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp +++ /dev/null @@ -1,36 +0,0 @@ -//===-- FormatManagerTests.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 "lldb/DataFormatters/FormatManager.h" - -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(FormatManagerTests, CompatibleLangs) { - std::vector candidates = {eLanguageTypeC_plus_plus, - eLanguageTypeObjC}; - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC), candidates); - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC89), candidates); - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC99), candidates); - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC11), candidates); - - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC_plus_plus), - candidates); - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC_plus_plus_03), - candidates); - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC_plus_plus_11), - candidates); - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeC_plus_plus_14), - candidates); - - candidates = {eLanguageTypeObjC}; - EXPECT_EQ(FormatManager::GetCandidateLanguages(eLanguageTypeObjC), - candidates); -} diff --git a/gnu/llvm/lldb/unittests/DataFormatter/FormattersContainerTest.cpp b/gnu/llvm/lldb/unittests/DataFormatter/FormattersContainerTest.cpp deleted file mode 100644 index a28212391ea..00000000000 --- a/gnu/llvm/lldb/unittests/DataFormatter/FormattersContainerTest.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//===-- FormattersContainerTests.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 "lldb/DataFormatters/FormattersContainer.h" - -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -// All the prefixes that the exact name matching will strip from the type. -static const std::vector exact_name_prefixes = { - "", // no prefix. - "class ", "struct ", "union ", "enum ", -}; - -// TypeMatcher that uses a exact type name string that needs to be matched. -TEST(TypeMatcherTests, ExactName) { - for (const std::string &prefix : exact_name_prefixes) { - SCOPED_TRACE("Prefix: " + prefix); - - TypeMatcher matcher(ConstString(prefix + "Name")); - EXPECT_TRUE(matcher.Matches(ConstString("class Name"))); - EXPECT_TRUE(matcher.Matches(ConstString("struct Name"))); - EXPECT_TRUE(matcher.Matches(ConstString("union Name"))); - EXPECT_TRUE(matcher.Matches(ConstString("enum Name"))); - EXPECT_TRUE(matcher.Matches(ConstString("Name"))); - - EXPECT_FALSE(matcher.Matches(ConstString("Name "))); - EXPECT_FALSE(matcher.Matches(ConstString("ame"))); - EXPECT_FALSE(matcher.Matches(ConstString("Nam"))); - EXPECT_FALSE(matcher.Matches(ConstString("am"))); - EXPECT_FALSE(matcher.Matches(ConstString("a"))); - EXPECT_FALSE(matcher.Matches(ConstString(" "))); - EXPECT_FALSE(matcher.Matches(ConstString("class N"))); - EXPECT_FALSE(matcher.Matches(ConstString("class "))); - EXPECT_FALSE(matcher.Matches(ConstString("class"))); - } -} - -// TypeMatcher that uses a regex to match a type name. -TEST(TypeMatcherTests, RegexName) { - TypeMatcher matcher(RegularExpression("^a[a-z]c$")); - EXPECT_TRUE(matcher.Matches(ConstString("abc"))); - EXPECT_TRUE(matcher.Matches(ConstString("azc"))); - - // FIXME: This isn't consistent with the 'exact' type name matches above. - EXPECT_FALSE(matcher.Matches(ConstString("class abc"))); - - EXPECT_FALSE(matcher.Matches(ConstString("abbc"))); - EXPECT_FALSE(matcher.Matches(ConstString(" abc"))); - EXPECT_FALSE(matcher.Matches(ConstString("abc "))); - EXPECT_FALSE(matcher.Matches(ConstString(" abc "))); - EXPECT_FALSE(matcher.Matches(ConstString("XabcX"))); - EXPECT_FALSE(matcher.Matches(ConstString("ac"))); - EXPECT_FALSE(matcher.Matches(ConstString("a[a-z]c"))); - EXPECT_FALSE(matcher.Matches(ConstString("aAc"))); - EXPECT_FALSE(matcher.Matches(ConstString("ABC"))); - EXPECT_FALSE(matcher.Matches(ConstString(""))); -} - -// TypeMatcher that only searches the type name. -TEST(TypeMatcherTests, RegexMatchPart) { - TypeMatcher matcher(RegularExpression("a[a-z]c")); - EXPECT_TRUE(matcher.Matches(ConstString("class abc"))); - EXPECT_TRUE(matcher.Matches(ConstString("abc"))); - EXPECT_TRUE(matcher.Matches(ConstString(" abc "))); - EXPECT_TRUE(matcher.Matches(ConstString("azc"))); - EXPECT_TRUE(matcher.Matches(ConstString("abc "))); - EXPECT_TRUE(matcher.Matches(ConstString(" abc "))); - EXPECT_TRUE(matcher.Matches(ConstString(" abc"))); - EXPECT_TRUE(matcher.Matches(ConstString("XabcX"))); - - EXPECT_FALSE(matcher.Matches(ConstString("abbc"))); - EXPECT_FALSE(matcher.Matches(ConstString("ac"))); - EXPECT_FALSE(matcher.Matches(ConstString("a[a-z]c"))); - EXPECT_FALSE(matcher.Matches(ConstString("aAc"))); - EXPECT_FALSE(matcher.Matches(ConstString("ABC"))); - EXPECT_FALSE(matcher.Matches(ConstString(""))); -} - -// GetMatchString for exact type name matchers. -TEST(TypeMatcherTests, GetMatchStringExactName) { - EXPECT_EQ(TypeMatcher(ConstString("aa")).GetMatchString(), "aa"); - EXPECT_EQ(TypeMatcher(ConstString("")).GetMatchString(), ""); - EXPECT_EQ(TypeMatcher(ConstString("[a]")).GetMatchString(), "[a]"); -} - -// GetMatchString for regex matchers. -TEST(TypeMatcherTests, GetMatchStringRegex) { - EXPECT_EQ(TypeMatcher(RegularExpression("aa")).GetMatchString(), "aa"); - EXPECT_EQ(TypeMatcher(RegularExpression("")).GetMatchString(), ""); - EXPECT_EQ(TypeMatcher(RegularExpression("[a]")).GetMatchString(), "[a]"); -} - -// GetMatchString for regex matchers. -TEST(TypeMatcherTests, CreatedBySameMatchString) { - TypeMatcher empty_str(ConstString("")); - TypeMatcher empty_regex(RegularExpression("")); - EXPECT_TRUE(empty_str.CreatedBySameMatchString(empty_str)); - EXPECT_TRUE(empty_str.CreatedBySameMatchString(empty_regex)); - - TypeMatcher a_str(ConstString("a")); - TypeMatcher a_regex(RegularExpression("a")); - EXPECT_TRUE(a_str.CreatedBySameMatchString(a_str)); - EXPECT_TRUE(a_str.CreatedBySameMatchString(a_regex)); - - TypeMatcher digit_str(ConstString("[0-9]")); - TypeMatcher digit_regex(RegularExpression("[0-9]")); - EXPECT_TRUE(digit_str.CreatedBySameMatchString(digit_str)); - EXPECT_TRUE(digit_str.CreatedBySameMatchString(digit_regex)); - - EXPECT_FALSE(empty_str.CreatedBySameMatchString(a_str)); - EXPECT_FALSE(empty_str.CreatedBySameMatchString(a_regex)); - EXPECT_FALSE(empty_str.CreatedBySameMatchString(digit_str)); - EXPECT_FALSE(empty_str.CreatedBySameMatchString(digit_regex)); - - EXPECT_FALSE(empty_regex.CreatedBySameMatchString(a_str)); - EXPECT_FALSE(empty_regex.CreatedBySameMatchString(a_regex)); - EXPECT_FALSE(empty_regex.CreatedBySameMatchString(digit_str)); - EXPECT_FALSE(empty_regex.CreatedBySameMatchString(digit_regex)); - - EXPECT_FALSE(a_str.CreatedBySameMatchString(empty_str)); - EXPECT_FALSE(a_str.CreatedBySameMatchString(empty_regex)); - EXPECT_FALSE(a_str.CreatedBySameMatchString(digit_str)); - EXPECT_FALSE(a_str.CreatedBySameMatchString(digit_regex)); - - EXPECT_FALSE(a_regex.CreatedBySameMatchString(empty_str)); - EXPECT_FALSE(a_regex.CreatedBySameMatchString(empty_regex)); - EXPECT_FALSE(a_regex.CreatedBySameMatchString(digit_str)); - EXPECT_FALSE(a_regex.CreatedBySameMatchString(digit_regex)); - - EXPECT_FALSE(digit_str.CreatedBySameMatchString(empty_str)); - EXPECT_FALSE(digit_str.CreatedBySameMatchString(empty_regex)); - EXPECT_FALSE(digit_str.CreatedBySameMatchString(a_str)); - EXPECT_FALSE(digit_str.CreatedBySameMatchString(a_regex)); - - EXPECT_FALSE(digit_regex.CreatedBySameMatchString(empty_str)); - EXPECT_FALSE(digit_regex.CreatedBySameMatchString(empty_regex)); - EXPECT_FALSE(digit_regex.CreatedBySameMatchString(a_str)); - EXPECT_FALSE(digit_regex.CreatedBySameMatchString(a_regex)); -} - -// Test CreatedBySameMatchString with stripped exact name prefixes. -TEST(TypeMatcherTests, CreatedBySameMatchStringExactNamePrefixes) { - for (const std::string &prefix : exact_name_prefixes) { - SCOPED_TRACE("Prefix: " + prefix); - TypeMatcher with_prefix(ConstString(prefix + "Name")); - TypeMatcher without_prefix(RegularExpression("")); - - EXPECT_TRUE(with_prefix.CreatedBySameMatchString(with_prefix)); - EXPECT_TRUE(without_prefix.CreatedBySameMatchString(without_prefix)); - } -} diff --git a/gnu/llvm/lldb/unittests/DataFormatter/StringPrinterTests.cpp b/gnu/llvm/lldb/unittests/DataFormatter/StringPrinterTests.cpp deleted file mode 100644 index 84a9372408b..00000000000 --- a/gnu/llvm/lldb/unittests/DataFormatter/StringPrinterTests.cpp +++ /dev/null @@ -1,150 +0,0 @@ -//===-- StringPrinterTests.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 "lldb/DataFormatters/StringPrinter.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Endian.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" -#include "gtest/gtest.h" -#include - -using namespace lldb; -using namespace lldb_private; -using lldb_private::formatters::StringPrinter; -using llvm::Optional; -using llvm::StringRef; - -#define QUOTE(x) std::string("\"" x "\"") - -/// Format \p input according to the specified string encoding and special char -/// escape style. -template -static Optional format(StringRef input, - StringPrinter::EscapeStyle escape_style) { - StreamString out; - StringPrinter::ReadBufferAndDumpToStreamOptions opts; - opts.SetStream(&out); - opts.SetSourceSize(input.size()); - opts.SetNeedsZeroTermination(true); - opts.SetEscapeNonPrintables(true); - opts.SetIgnoreMaxLength(false); - opts.SetEscapeStyle(escape_style); - DataExtractor extractor(input.data(), input.size(), - endian::InlHostByteOrder(), sizeof(void *)); - opts.SetData(extractor); - const bool success = StringPrinter::ReadBufferAndDumpToStream(opts); - if (!success) - return llvm::None; - return out.GetString().str(); -} - -// Test ASCII formatting for C++. This behaves exactly like UTF8 formatting for -// C++, although that's questionable (see FIXME in StringPrinter.cpp). -TEST(StringPrinterTests, CxxASCII) { - auto fmt = [](StringRef str) { - return format( - str, StringPrinter::EscapeStyle::CXX); - }; - - // Special escapes. - EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); - EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); - EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); - EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); - EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); - EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); - EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); - EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); - EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); - EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); - EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); - - // Printable characters. - EXPECT_EQ(fmt("'"), QUOTE("'")); - EXPECT_EQ(fmt("a"), QUOTE("a")); - EXPECT_EQ(fmt("Z"), QUOTE("Z")); - EXPECT_EQ(fmt("🥑"), QUOTE("🥑")); - - // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). - EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); - EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); - - EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. - EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. -} - -// Test UTF8 formatting for C++. -TEST(StringPrinterTests, CxxUTF8) { - auto fmt = [](StringRef str) { - return format( - str, StringPrinter::EscapeStyle::CXX); - }; - - // Special escapes. - EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); - EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); - EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); - EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); - EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); - EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); - EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); - EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); - EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); - EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); - EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); - - // Printable characters. - EXPECT_EQ(fmt("'"), QUOTE("'")); - EXPECT_EQ(fmt("a"), QUOTE("a")); - EXPECT_EQ(fmt("Z"), QUOTE("Z")); - EXPECT_EQ(fmt("🥑"), QUOTE("🥑")); - - // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). - EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); - EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); - - EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. - EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. -} - -// Test UTF8 formatting for Swift. -TEST(StringPrinterTests, SwiftUTF8) { - auto fmt = [](StringRef str) { - return format( - str, StringPrinter::EscapeStyle::Swift); - }; - - // Special escapes. - EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); - EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); - EXPECT_EQ(fmt("\b"), QUOTE(R"(\u{8})")); - EXPECT_EQ(fmt("\f"), QUOTE(R"(\u{c})")); - EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); - EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); - EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); - EXPECT_EQ(fmt("\v"), QUOTE(R"(\u{b})")); - EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); - EXPECT_EQ(fmt("\'"), QUOTE(R"(\')")); - EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); - - // Printable characters. - EXPECT_EQ(fmt("'"), QUOTE(R"(\')")); - EXPECT_EQ(fmt("a"), QUOTE("a")); - EXPECT_EQ(fmt("Z"), QUOTE("Z")); - EXPECT_EQ(fmt("🥑"), QUOTE("🥑")); - - // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). - EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); - EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); - - EXPECT_EQ(fmt("\376"), QUOTE(R"(\u{fe})")); // \376 is 254 in decimal. - EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\u{fe})")); // \xfe is 254 in decimal. -} diff --git a/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt b/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt deleted file mode 100644 index a0a3c264f16..00000000000 --- a/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -if("ARM" IN_LIST LLVM_TARGETS_TO_BUILD) - add_lldb_unittest(DisassemblerTests - TestArm64Disassembly.cpp - TestArmv7Disassembly.cpp - LINK_LIBS - lldbCore - lldbSymbol - lldbTarget - lldbPluginDisassemblerLLVMC - lldbPluginProcessUtility - LINK_COMPONENTS - Support - ${LLVM_TARGETS_TO_BUILD}) -endif() diff --git a/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp b/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp deleted file mode 100644 index 12975683397..00000000000 --- a/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//===-- TestArm64Disassembly.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 "gtest/gtest.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/Disassembler.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Target/ExecutionContext.h" - -#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" -#include "llvm/Support/TargetSelect.h" - -using namespace lldb; -using namespace lldb_private; - -class TestArm64Disassembly : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - - // virtual void SetUp() override { } - // virtual void TearDown() override { } - -protected: -}; - -void TestArm64Disassembly::SetUpTestCase() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllDisassemblers(); - DisassemblerLLVMC::Initialize(); -} - -void TestArm64Disassembly::TearDownTestCase() { - DisassemblerLLVMC::Terminate(); -} - -TEST_F(TestArm64Disassembly, TestArmv81Instruction) { - ArchSpec arch("arm64-apple-ios"); - - const unsigned num_of_instructions = 2; - uint8_t data[] = { - 0xff, 0x43, 0x00, 0xd1, // 0xd10043ff : sub sp, sp, #0x10 - 0x62, 0x7c, 0xa1, 0xc8, // 0xc8a17c62 : cas x1, x2, [x3] (cas defined in ARM v8.1 & newer) - }; - - DisassemblerSP disass_sp; - Address start_addr(0x100); - disass_sp = Disassembler::DisassembleBytes(arch, nullptr, nullptr, start_addr, - &data, sizeof (data), num_of_instructions, false); - - // If we failed to get a disassembler, we can assume it is because - // the llvm we linked against was not built with the ARM target, - // and we should skip these tests without marking anything as failing. - - if (disass_sp) { - const InstructionList inst_list (disass_sp->GetInstructionList()); - EXPECT_EQ (num_of_instructions, inst_list.GetSize()); - - InstructionSP inst_sp; - const char *mnemonic; - ExecutionContext exe_ctx (nullptr, nullptr, nullptr); - inst_sp = inst_list.GetInstructionAtIndex (0); - mnemonic = inst_sp->GetMnemonic(&exe_ctx); - ASSERT_STREQ ("sub", mnemonic); - - inst_sp = inst_list.GetInstructionAtIndex (1); - mnemonic = inst_sp->GetMnemonic(&exe_ctx); - ASSERT_STREQ ("cas", mnemonic); - } -} diff --git a/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp b/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp deleted file mode 100644 index 92b6d07f48e..00000000000 --- a/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp +++ /dev/null @@ -1,91 +0,0 @@ -//===-- TestArmv7Disassembly.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 "gtest/gtest.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/Disassembler.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Target/ExecutionContext.h" - -#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" -#include "llvm/Support/TargetSelect.h" - -using namespace lldb; -using namespace lldb_private; - -class TestArmv7Disassembly : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - - // virtual void SetUp() override { } - // virtual void TearDown() override { } - -protected: -}; - -void TestArmv7Disassembly::SetUpTestCase() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllDisassemblers(); - DisassemblerLLVMC::Initialize(); -} - -void TestArmv7Disassembly::TearDownTestCase() { - DisassemblerLLVMC::Terminate(); -} - -TEST_F(TestArmv7Disassembly, TestCortexFPDisass) { - ArchSpec arch("armv7em--"); - - const unsigned num_of_instructions = 3; - uint8_t data[] = { - 0x00, 0xee, 0x10, 0x2a, // 0xee002a10 : vmov s0, r2 - 0xb8, 0xee, 0xc0, 0x0b, // 0xeeb80bc0 : vcvt.f64.s32 d0, s0 - 0xb6, 0xee, 0x00, 0x0a, // 0xeeb60a00 : vmov.f32 s0, #5.000000e-01 - }; - - // these can be disassembled by hand with llvm-mc, e.g. - // - // 0x00, 0xee, 0x10, 0x2a, // 0xee002a10 : vmov s0, r2 - // - // echo 0x00 0xee 0x10 0x2a | llvm-mc -arch thumb -disassemble -mattr=+fp-armv8 - // vmov s0, r2 - - DisassemblerSP disass_sp; - Address start_addr(0x100); - disass_sp = Disassembler::DisassembleBytes(arch, nullptr, nullptr, start_addr, - &data, sizeof (data), num_of_instructions, false); - - // If we failed to get a disassembler, we can assume it is because - // the llvm we linked against was not built with the ARM target, - // and we should skip these tests without marking anything as failing. - - if (disass_sp) { - const InstructionList inst_list (disass_sp->GetInstructionList()); - EXPECT_EQ (num_of_instructions, inst_list.GetSize()); - - InstructionSP inst_sp; - const char *mnemonic; - ExecutionContext exe_ctx (nullptr, nullptr, nullptr); - inst_sp = inst_list.GetInstructionAtIndex (0); - mnemonic = inst_sp->GetMnemonic(&exe_ctx); - ASSERT_STREQ ("vmov", mnemonic); - - inst_sp = inst_list.GetInstructionAtIndex (1); - mnemonic = inst_sp->GetMnemonic(&exe_ctx); - ASSERT_STREQ ("vcvt.f64.s32", mnemonic); - - inst_sp = inst_list.GetInstructionAtIndex (2); - mnemonic = inst_sp->GetMnemonic(&exe_ctx); - ASSERT_STREQ ("vmov.f32", mnemonic); - } -} diff --git a/gnu/llvm/lldb/unittests/Editline/CMakeLists.txt b/gnu/llvm/lldb/unittests/Editline/CMakeLists.txt deleted file mode 100644 index 4b2643d15c5..00000000000 --- a/gnu/llvm/lldb/unittests/Editline/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_lldb_unittest(EditlineTests - EditlineTest.cpp - - LINK_LIBS - lldbHost - lldbUtility - LLVMTestingSupport - ) diff --git a/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp b/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp deleted file mode 100644 index 53184811450..00000000000 --- a/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp +++ /dev/null @@ -1,312 +0,0 @@ -//===-- EditlineTest.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 "lldb/Host/Config.h" - -#if LLDB_ENABLE_LIBEDIT - -#define EDITLINE_TEST_DUMP_OUTPUT 0 - -#include -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include -#include - -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/Editline.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/Pipe.h" -#include "lldb/Host/PseudoTerminal.h" -#include "lldb/Utility/Status.h" -#include "lldb/Utility/StringList.h" - -using namespace lldb_private; - -namespace { -const size_t TIMEOUT_MILLIS = 5000; -} - -class FilePointer { -public: - FilePointer() = delete; - - FilePointer(const FilePointer &) = delete; - - FilePointer(FILE *file_p) : _file_p(file_p) {} - - ~FilePointer() { - if (_file_p != nullptr) { - const int close_result = fclose(_file_p); - EXPECT_EQ(0, close_result); - } - } - - operator FILE *() { return _file_p; } - -private: - FILE *_file_p; -}; - -/** - Wraps an Editline class, providing a simple way to feed - input (as if from the keyboard) and receive output from Editline. - */ -class EditlineAdapter { -public: - EditlineAdapter(); - - void CloseInput(); - - bool IsValid() const { return _editline_sp != nullptr; } - - lldb_private::Editline &GetEditline() { return *_editline_sp; } - - bool SendLine(const std::string &line); - - bool SendLines(const std::vector &lines); - - bool GetLine(std::string &line, bool &interrupted, size_t timeout_millis); - - bool GetLines(lldb_private::StringList &lines, bool &interrupted, - size_t timeout_millis); - - void ConsumeAllOutput(); - -private: - bool IsInputComplete(lldb_private::Editline *editline, - lldb_private::StringList &lines); - - std::unique_ptr _editline_sp; - - PseudoTerminal _pty; - int _pty_master_fd; - int _pty_secondary_fd; - - std::unique_ptr _el_secondary_file; -}; - -EditlineAdapter::EditlineAdapter() - : _editline_sp(), _pty(), _pty_master_fd(-1), _pty_secondary_fd(-1), - _el_secondary_file() { - lldb_private::Status error; - - // Open the first master pty available. - EXPECT_THAT_ERROR(_pty.OpenFirstAvailablePrimary(O_RDWR), llvm::Succeeded()); - - // Grab the master fd. This is a file descriptor we will: - // (1) write to when we want to send input to editline. - // (2) read from when we want to see what editline sends back. - _pty_master_fd = _pty.GetPrimaryFileDescriptor(); - - // Open the corresponding secondary pty. - EXPECT_THAT_ERROR(_pty.OpenSecondary(O_RDWR), llvm::Succeeded()); - _pty_secondary_fd = _pty.GetSecondaryFileDescriptor(); - - _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "rw"))); - EXPECT_FALSE(nullptr == *_el_secondary_file); - if (*_el_secondary_file == nullptr) - return; - - // Create an Editline instance. - _editline_sp.reset(new lldb_private::Editline( - "gtest editor", *_el_secondary_file, *_el_secondary_file, - *_el_secondary_file, false)); - _editline_sp->SetPrompt("> "); - - // Hookup our input complete callback. - auto input_complete_cb = [this](Editline *editline, StringList &lines) { - return this->IsInputComplete(editline, lines); - }; - _editline_sp->SetIsInputCompleteCallback(input_complete_cb); -} - -void EditlineAdapter::CloseInput() { - if (_el_secondary_file != nullptr) - _el_secondary_file.reset(nullptr); -} - -bool EditlineAdapter::SendLine(const std::string &line) { - // Ensure we're valid before proceeding. - if (!IsValid()) - return false; - - // Write the line out to the pipe connected to editline's input. - ssize_t input_bytes_written = - ::write(_pty_master_fd, line.c_str(), - line.length() * sizeof(std::string::value_type)); - - const char *eoln = "\n"; - const size_t eoln_length = strlen(eoln); - input_bytes_written = - ::write(_pty_master_fd, eoln, eoln_length * sizeof(char)); - - EXPECT_NE(-1, input_bytes_written) << strerror(errno); - EXPECT_EQ(eoln_length * sizeof(char), size_t(input_bytes_written)); - return eoln_length * sizeof(char) == size_t(input_bytes_written); -} - -bool EditlineAdapter::SendLines(const std::vector &lines) { - for (auto &line : lines) { -#if EDITLINE_TEST_DUMP_OUTPUT - printf(" sending line \"%s\"\n", line.c_str()); -#endif - if (!SendLine(line)) - return false; - } - return true; -} - -// We ignore the timeout for now. -bool EditlineAdapter::GetLine(std::string &line, bool &interrupted, - size_t /* timeout_millis */) { - // Ensure we're valid before proceeding. - if (!IsValid()) - return false; - - _editline_sp->GetLine(line, interrupted); - return true; -} - -bool EditlineAdapter::GetLines(lldb_private::StringList &lines, - bool &interrupted, size_t /* timeout_millis */) { - // Ensure we're valid before proceeding. - if (!IsValid()) - return false; - - _editline_sp->GetLines(1, lines, interrupted); - return true; -} - -bool EditlineAdapter::IsInputComplete(lldb_private::Editline *editline, - lldb_private::StringList &lines) { - // We'll call ourselves complete if we've received a balanced set of braces. - int start_block_count = 0; - int brace_balance = 0; - - for (const std::string &line : lines) { - for (auto ch : line) { - if (ch == '{') { - ++start_block_count; - ++brace_balance; - } else if (ch == '}') - --brace_balance; - } - } - - return (start_block_count > 0) && (brace_balance == 0); -} - -void EditlineAdapter::ConsumeAllOutput() { - FilePointer output_file(fdopen(_pty_master_fd, "r")); - - int ch; - while ((ch = fgetc(output_file)) != EOF) { -#if EDITLINE_TEST_DUMP_OUTPUT - char display_str[] = {0, 0, 0}; - switch (ch) { - case '\t': - display_str[0] = '\\'; - display_str[1] = 't'; - break; - case '\n': - display_str[0] = '\\'; - display_str[1] = 'n'; - break; - case '\r': - display_str[0] = '\\'; - display_str[1] = 'r'; - break; - default: - display_str[0] = ch; - break; - } - printf(" 0x%02x (%03d) (%s)\n", ch, ch, display_str); -// putc(ch, stdout); -#endif - } -} - -class EditlineTestFixture : public ::testing::Test { - SubsystemRAII subsystems; - EditlineAdapter _el_adapter; - std::shared_ptr _sp_output_thread; - -public: - static void SetUpTestCase() { - // We need a TERM set properly for editline to work as expected. - setenv("TERM", "vt100", 1); - } - - void SetUp() override { - // Validate the editline adapter. - EXPECT_TRUE(_el_adapter.IsValid()); - if (!_el_adapter.IsValid()) - return; - - // Dump output. - _sp_output_thread = - std::make_shared([&] { _el_adapter.ConsumeAllOutput(); }); - } - - void TearDown() override { - _el_adapter.CloseInput(); - if (_sp_output_thread) - _sp_output_thread->join(); - } - - EditlineAdapter &GetEditlineAdapter() { return _el_adapter; } -}; - -TEST_F(EditlineTestFixture, EditlineReceivesSingleLineText) { - // Send it some text via our virtual keyboard. - const std::string input_text("Hello, world"); - EXPECT_TRUE(GetEditlineAdapter().SendLine(input_text)); - - // Verify editline sees what we put in. - std::string el_reported_line; - bool input_interrupted = false; - const bool received_line = GetEditlineAdapter().GetLine( - el_reported_line, input_interrupted, TIMEOUT_MILLIS); - - EXPECT_TRUE(received_line); - EXPECT_FALSE(input_interrupted); - EXPECT_EQ(input_text, el_reported_line); -} - -TEST_F(EditlineTestFixture, EditlineReceivesMultiLineText) { - // Send it some text via our virtual keyboard. - std::vector input_lines; - input_lines.push_back("int foo()"); - input_lines.push_back("{"); - input_lines.push_back("printf(\"Hello, world\");"); - input_lines.push_back("}"); - input_lines.push_back(""); - - EXPECT_TRUE(GetEditlineAdapter().SendLines(input_lines)); - - // Verify editline sees what we put in. - lldb_private::StringList el_reported_lines; - bool input_interrupted = false; - - EXPECT_TRUE(GetEditlineAdapter().GetLines(el_reported_lines, - input_interrupted, TIMEOUT_MILLIS)); - EXPECT_FALSE(input_interrupted); - - // Without any auto indentation support, our output should directly match our - // input. - std::vector reported_lines; - for (const std::string &line : el_reported_lines) - reported_lines.push_back(line); - - EXPECT_THAT(reported_lines, testing::ContainerEq(input_lines)); -} - -#endif diff --git a/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt b/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt deleted file mode 100644 index 185b19f84ca..00000000000 --- a/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -add_lldb_unittest(ExpressionTests - ClangParserTest.cpp - ClangExpressionDeclMapTest.cpp - DiagnosticManagerTest.cpp - DWARFExpressionTest.cpp - CppModuleConfigurationTest.cpp - - LINK_LIBS - lldbCore - lldbPluginObjectFileELF - lldbPluginPlatformLinux - lldbPluginExpressionParserClang - lldbPluginTypeSystemClang - lldbUtility - lldbUtilityHelpers - lldbSymbolHelpers - LLVMTestingSupport - ) diff --git a/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp b/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp deleted file mode 100644 index ecee35ff46e..00000000000 --- a/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp +++ /dev/null @@ -1,123 +0,0 @@ -//===-- ClangExpressionDeclMapTest.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 "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h" -#include "Plugins/ExpressionParser/Clang/ClangUtil.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/Symbol/ClangTestUtils.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/lldb-defines.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb; - -namespace { -struct FakeClangExpressionDeclMap : public ClangExpressionDeclMap { - FakeClangExpressionDeclMap(const std::shared_ptr &importer) - : ClangExpressionDeclMap(false, nullptr, lldb::TargetSP(), importer, - nullptr) { - m_scratch_context = clang_utils::createAST(); - } - std::unique_ptr m_scratch_context; - /// Adds a persistent decl that can be found by the ClangExpressionDeclMap - /// via GetPersistentDecl. - void AddPersistentDeclForTest(clang::NamedDecl *d) { - // The declaration needs to have '$' prefix in its name like every - // persistent declaration and must be inside the scratch AST context. - assert(d); - assert(d->getName().startswith("$")); - assert(&d->getASTContext() == &m_scratch_context->getASTContext()); - m_persistent_decls[d->getName()] = d; - } - -protected: - // ClangExpressionDeclMap hooks. - - clang::NamedDecl *GetPersistentDecl(ConstString name) override { - // ClangExpressionDeclMap wants to know if there is a persistent decl - // with the given name. Check the - return m_persistent_decls.lookup(name.GetStringRef()); - } - -private: - /// The persistent decls in this test with their names as keys. - llvm::DenseMap m_persistent_decls; -}; -} // namespace - -namespace { -struct ClangExpressionDeclMapTest : public testing::Test { - SubsystemRAII subsystems; - - /// The ClangASTImporter used during the test. - std::shared_ptr importer; - /// The ExpressionDeclMap for the current test case. - std::unique_ptr decl_map; - - /// The target AST that lookup results should be imported to. - std::unique_ptr target_ast; - - void SetUp() override { - importer = std::make_shared(); - decl_map = std::make_unique(importer); - target_ast = clang_utils::createAST(); - decl_map->InstallASTContext(*target_ast); - } - - void TearDown() override { - importer.reset(); - decl_map.reset(); - target_ast.reset(); - } -}; -} // namespace - -TEST_F(ClangExpressionDeclMapTest, TestUnknownIdentifierLookup) { - // Tests looking up an identifier that can't be found anywhere. - - // Setup a NameSearchContext for 'foo'. - llvm::SmallVector decls; - clang::DeclarationName name = - clang_utils::getDeclarationName(*target_ast, "foo"); - const clang::DeclContext *dc = target_ast->GetTranslationUnitDecl(); - NameSearchContext search(*target_ast, decls, name, dc); - - decl_map->FindExternalVisibleDecls(search); - - // This shouldn't exist so we should get no lookups. - EXPECT_EQ(0U, decls.size()); -} - -TEST_F(ClangExpressionDeclMapTest, TestPersistentDeclLookup) { - // Tests looking up a persistent decl from the scratch AST context. - - // Create a '$persistent_class' record and add it as a persistent variable - // to the scratch AST context. - llvm::StringRef decl_name = "$persistent_class"; - CompilerType persistent_type = - clang_utils::createRecord(*decl_map->m_scratch_context, decl_name); - decl_map->AddPersistentDeclForTest(ClangUtil::GetAsTagDecl(persistent_type)); - - // Setup a NameSearchContext for $persistent_class; - llvm::SmallVector decls; - clang::DeclarationName name = - clang_utils::getDeclarationName(*target_ast, decl_name); - const clang::DeclContext *dc = target_ast->GetTranslationUnitDecl(); - NameSearchContext search(*target_ast, decls, name, dc); - - // Search and check that we found $persistent_class. - decl_map->FindExternalVisibleDecls(search); - EXPECT_EQ(1U, decls.size()); - EXPECT_EQ(decl_name, decls.front()->getQualifiedNameAsString()); - auto *record = llvm::cast(decls.front()); - // The class was minimally imported from the scratch AST context. - EXPECT_TRUE(record->hasExternalLexicalStorage()); -} diff --git a/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp b/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp deleted file mode 100644 index 4df55747531..00000000000 --- a/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp +++ /dev/null @@ -1,91 +0,0 @@ -//===-- ClangParserTest.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 "clang/Basic/Version.h" - -#include "Plugins/ExpressionParser/Clang/ClangHost.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Host/Config.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/lldb-defines.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -struct ClangHostTest : public testing::Test { - SubsystemRAII subsystems; -}; -} // namespace - -static std::string ComputeClangResourceDir(std::string lldb_shlib_path, - bool verify = false) { - FileSpec clang_dir; - FileSpec lldb_shlib_spec(lldb_shlib_path); - ComputeClangResourceDirectory(lldb_shlib_spec, clang_dir, verify); - return clang_dir.GetPath(); -} - -TEST_F(ClangHostTest, ComputeClangResourceDirectory) { -#if !defined(_WIN32) - std::string path_to_liblldb = "/foo/bar/lib/"; - std::string path_to_clang_dir = "/foo/bar/lib" LLDB_LIBDIR_SUFFIX "/clang/" CLANG_VERSION_STRING; -#else - std::string path_to_liblldb = "C:\\foo\\bar\\lib"; - std::string path_to_clang_dir = "C:\\foo\\bar\\lib\\clang\\" CLANG_VERSION_STRING; -#endif - EXPECT_EQ(ComputeClangResourceDir(path_to_liblldb), path_to_clang_dir); - - // The path doesn't really exist, so setting verify to true should make - // ComputeClangResourceDir not give you path_to_clang_dir. - EXPECT_NE(ComputeClangResourceDir(path_to_liblldb, true), path_to_clang_dir); -} - -#if defined(__APPLE__) -TEST_F(ClangHostTest, MacOSX) { - // This returns whatever the POSIX fallback returns. - std::string posix = "/usr/lib/liblldb.dylib"; - EXPECT_FALSE(ComputeClangResourceDir(posix).empty()); - - std::string build = - "/lldb-macosx-x86_64/Library/Frameworks/LLDB.framework/Versions/A"; - std::string build_clang = - "/lldb-macosx-x86_64/Library/Frameworks/LLDB.framework/Resources/Clang"; - EXPECT_EQ(ComputeClangResourceDir(build), build_clang); - - std::string xcode = "/Applications/Xcode.app/Contents/SharedFrameworks/" - "LLDB.framework/Versions/A"; - std::string xcode_clang = - "/Applications/Xcode.app/Contents/Developer/Toolchains/" - "XcodeDefault.xctoolchain/usr/lib/swift/clang"; - EXPECT_EQ(ComputeClangResourceDir(xcode), xcode_clang); - - std::string toolchain = - "/Applications/Xcode.app/Contents/Developer/Toolchains/" - "Swift-4.1-development-snapshot.xctoolchain/System/Library/" - "PrivateFrameworks/LLDB.framework"; - std::string toolchain_clang = - "/Applications/Xcode.app/Contents/Developer/Toolchains/" - "Swift-4.1-development-snapshot.xctoolchain/usr/lib/swift/clang"; - EXPECT_EQ(ComputeClangResourceDir(toolchain), toolchain_clang); - - std::string cltools = "/Library/Developer/CommandLineTools/Library/" - "PrivateFrameworks/LLDB.framework"; - std::string cltools_clang = - "/Library/Developer/CommandLineTools/Library/PrivateFrameworks/" - "LLDB.framework/Resources/Clang"; - EXPECT_EQ(ComputeClangResourceDir(cltools), cltools_clang); - - // Test that a bogus path is detected. - EXPECT_NE(ComputeClangResourceDir(GetInputFilePath(xcode), true), - ComputeClangResourceDir(GetInputFilePath(xcode))); -} -#endif // __APPLE__ diff --git a/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp b/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp deleted file mode 100644 index c1d0d00dcba..00000000000 --- a/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp +++ /dev/null @@ -1,263 +0,0 @@ -//===-- CppModuleConfigurationTest.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 "Plugins/ExpressionParser/Clang/CppModuleConfiguration.h" -#include "Plugins/ExpressionParser/Clang/ClangHost.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "llvm/Support/SmallVectorMemoryBuffer.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -struct CppModuleConfigurationTest : public testing::Test { - llvm::MemoryBufferRef m_empty_buffer; - llvm::IntrusiveRefCntPtr m_fs; - - CppModuleConfigurationTest() - : m_empty_buffer("", ""), - m_fs(new llvm::vfs::InMemoryFileSystem()) {} - - void SetUp() override { - FileSystem::Initialize(m_fs); - HostInfo::Initialize(); - } - - void TearDown() override { - HostInfo::Terminate(); - FileSystem::Terminate(); - } - - /// Utility function turning a list of paths into a FileSpecList. - FileSpecList makeFiles(llvm::ArrayRef paths) { - FileSpecList result; - for (const std::string &path : paths) { - result.Append(FileSpec(path, FileSpec::Style::posix)); - if (!m_fs->addFileNoOwn(path, static_cast(0), m_empty_buffer)) - llvm_unreachable("Invalid test configuration?"); - } - return result; - } -}; -} // namespace - -/// Returns the Clang resource include directory. -static std::string ResourceInc() { - llvm::SmallString<256> resource_dir; - llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(), - "include"); - return std::string(resource_dir); -} - - -TEST_F(CppModuleConfigurationTest, Linux) { - // Test the average Linux configuration. - - std::string usr = "/usr/include"; - std::string libcpp = "/usr/include/c++/v1"; - std::vector files = {// C library - usr + "/stdio.h", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre(libcpp, ResourceInc(), usr)); -} - -TEST_F(CppModuleConfigurationTest, Sysroot) { - // Test that having a sysroot for the whole system works fine. - - std::string libcpp = "/home/user/sysroot/usr/include/c++/v1"; - std::string usr = "/home/user/sysroot/usr/include"; - std::vector files = {// C library - usr + "/stdio.h", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre(libcpp, ResourceInc(), usr)); -} - -TEST_F(CppModuleConfigurationTest, LinuxLocalLibCpp) { - // Test that a locally build libc++ is detected. - - std::string usr = "/usr/include"; - std::string libcpp = "/home/user/llvm-build/include/c++/v1"; - std::vector files = {// C library - usr + "/stdio.h", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre(libcpp, ResourceInc(), usr)); -} - -TEST_F(CppModuleConfigurationTest, UnrelatedLibrary) { - // Test that having an unrelated library in /usr/include doesn't break. - - std::string usr = "/usr/include"; - std::string libcpp = "/home/user/llvm-build/include/c++/v1"; - std::vector files = {// C library - usr + "/stdio.h", - // unrelated library - usr + "/boost/vector", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre(libcpp, ResourceInc(), usr)); -} - -TEST_F(CppModuleConfigurationTest, Xcode) { - // Test detection of libc++ coming from Xcode with generic platform names. - - std::string p = "/Applications/Xcode.app/Contents/Developer/"; - std::string libcpp = p + "Toolchains/B.xctoolchain/usr/include/c++/v1"; - std::string usr = - p + "Platforms/A.platform/Developer/SDKs/OSVers.sdk/usr/include"; - std::vector files = { - // C library - usr + "/stdio.h", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap", - }; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre(libcpp, ResourceInc(), usr)); -} - -TEST_F(CppModuleConfigurationTest, LibCppV2) { - // Test that a "v2" of libc++ is still correctly detected. - - std::string libcpp = "/usr/include/c++/v2"; - std::vector files = {// C library - "/usr/include/stdio.h", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre("/usr/include/c++/v2", ResourceInc(), - "/usr/include")); -} - -TEST_F(CppModuleConfigurationTest, UnknownLibCppFile) { - // Test that having some unknown file in the libc++ path doesn't break - // anything. - - std::string libcpp = "/usr/include/c++/v1"; - std::vector files = {// C library - "/usr/include/stdio.h", - // C++ library - libcpp + "/non_existing_file", - libcpp + "/module.modulemap", - libcpp + "/vector"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); - EXPECT_THAT(config.GetIncludeDirs(), - testing::ElementsAre("/usr/include/c++/v1", ResourceInc(), - "/usr/include")); -} - -TEST_F(CppModuleConfigurationTest, MissingUsrInclude) { - // Test that we don't load 'std' if we can't find the C standard library. - - std::string libcpp = "/usr/include/c++/v1"; - std::vector files = {// C++ library - libcpp + "/vector", - libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); - EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); -} - -TEST_F(CppModuleConfigurationTest, MissingLibCpp) { - // Test that we don't load 'std' if we don't have a libc++. - - std::string usr = "/usr/include"; - std::vector files = { - // C library - usr + "/stdio.h", - }; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); - EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); -} - -TEST_F(CppModuleConfigurationTest, IgnoreLibStdCpp) { - // Test that we don't do anything bad when we encounter libstdc++ paths. - - std::string usr = "/usr/include"; - std::vector files = { - // C library - usr + "/stdio.h", - // C++ library - usr + "/c++/8.0.1/vector", - }; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); - EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); -} - -TEST_F(CppModuleConfigurationTest, AmbiguousCLib) { - // Test that we don't do anything when we are not sure where the - // right C standard library is. - - std::string usr1 = "/usr/include"; - std::string usr2 = "/usr/include/other/path"; - std::string libcpp = usr1 + "c++/v1"; - std::vector files = { - // First C library - usr1 + "/stdio.h", - // Second C library - usr2 + "/stdio.h", - // C++ library - libcpp + "/vector", - libcpp + "/module.modulemap", - }; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); - EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); -} - -TEST_F(CppModuleConfigurationTest, AmbiguousLibCpp) { - // Test that we don't do anything when we are not sure where the - // right libc++ is. - - std::string usr = "/usr/include"; - std::string libcpp1 = usr + "c++/v1"; - std::string libcpp2 = usr + "c++/v2"; - std::vector files = { - // C library - usr + "/stdio.h", - // First C++ library - libcpp1 + "/vector", - libcpp1 + "/module.modulemap", - // Second C++ library - libcpp2 + "/vector", - libcpp2 + "/module.modulemap", - }; - CppModuleConfiguration config(makeFiles(files)); - EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); - EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); -} diff --git a/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp b/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp deleted file mode 100644 index 92101e913c2..00000000000 --- a/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ /dev/null @@ -1,369 +0,0 @@ -//===-- DWARFExpressionTest.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 "lldb/Expression/DWARFExpression.h" -#include "Plugins/Platform/Linux/PlatformLinux.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/Symbol/YAMLModuleTester.h" -#include "lldb/Core/Value.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/dwarf.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Utility/Reproducer.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -static llvm::Expected Evaluate(llvm::ArrayRef expr, - lldb::ModuleSP module_sp = {}, - DWARFUnit *unit = nullptr, - ExecutionContext *exe_ctx = nullptr) { - DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle, - /*addr_size*/ 4); - Value result; - Status status; - if (!DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp, - extractor, unit, lldb::eRegisterKindLLDB, - /*initial_value_ptr*/ nullptr, - /*object_address_ptr*/ nullptr, result, - &status)) - return status.ToError(); - - switch (result.GetValueType()) { - case Value::ValueType::Scalar: - return result.GetScalar(); - case Value::ValueType::LoadAddress: - return LLDB_INVALID_ADDRESS; - case Value::ValueType::HostAddress: { - // Convert small buffers to scalars to simplify the tests. - DataBufferHeap &buf = result.GetBuffer(); - if (buf.GetByteSize() <= 8) { - uint64_t val = 0; - memcpy(&val, buf.GetBytes(), buf.GetByteSize()); - return Scalar(llvm::APInt(buf.GetByteSize()*8, val, false)); - } - } - LLVM_FALLTHROUGH; - default: - return status.ToError(); - } -} - -class DWARFExpressionTester : public YAMLModuleTester { -public: - using YAMLModuleTester::YAMLModuleTester; - llvm::Expected Eval(llvm::ArrayRef expr) { - return ::Evaluate(expr, m_module_sp, m_dwarf_unit); - } -}; - -/// Unfortunately Scalar's operator==() is really picky. -static Scalar GetScalar(unsigned bits, uint64_t value, bool sign) { - Scalar scalar(value); - scalar.TruncOrExtendTo(bits, sign); - return scalar; -} - -/// This is needed for the tests that use a mock process. -class DWARFExpressionMockProcessTest : public ::testing::Test { -public: - void SetUp() override { - llvm::cantFail(repro::Reproducer::Initialize(repro::ReproducerMode::Off, {})); - FileSystem::Initialize(); - HostInfo::Initialize(); - platform_linux::PlatformLinux::Initialize(); - } - void TearDown() override { - platform_linux::PlatformLinux::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - repro::Reproducer::Terminate(); - } -}; - -TEST(DWARFExpression, DW_OP_pick) { - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 0}), - llvm::HasValue(0)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 1}), - llvm::HasValue(1)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 2}), - llvm::Failed()); -} - -TEST(DWARFExpression, DW_OP_const) { - // Extend to address size. - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1u, 0x88}), llvm::HasValue(0x88)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1s, 0x88}), - llvm::HasValue(0xffffff88)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x47, 0x88}), - llvm::HasValue(0x8847)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2s, 0x47, 0x88}), - llvm::HasValue(0xffff8847)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const4u, 0x44, 0x42, 0x47, 0x88}), - llvm::HasValue(0x88474244)); - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const4s, 0x44, 0x42, 0x47, 0x88}), - llvm::HasValue(0x88474244)); - - // Truncate to address size. - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_const8u, 0x00, 0x11, 0x22, 0x33, 0x44, 0x42, 0x47, 0x88}), - llvm::HasValue(0x33221100)); - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_const8s, 0x00, 0x11, 0x22, 0x33, 0x44, 0x42, 0x47, 0x88}), - llvm::HasValue(0x33221100)); - - // Don't truncate to address size for compatibility with clang (pr48087). - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_constu, 0x81, 0x82, 0x84, 0x88, 0x90, 0xa0, 0x40}), - llvm::HasValue(0x01010101010101)); - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_consts, 0x81, 0x82, 0x84, 0x88, 0x90, 0xa0, 0x40}), - llvm::HasValue(0xffff010101010101)); -} - -TEST(DWARFExpression, DW_OP_convert) { - /// Auxiliary debug info. - const char *yamldata = R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 -DWARF: - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_language - Form: DW_FORM_data2 - - Code: 0x00000002 - Tag: DW_TAG_base_type - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_encoding - Form: DW_FORM_data1 - - Attribute: DW_AT_byte_size - Form: DW_FORM_data1 - debug_info: - - Version: 4 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000001 - Values: - - Value: 0x000000000000000C - # 0x0000000e: - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000007 # DW_ATE_unsigned - - Value: 0x0000000000000004 - # 0x00000011: - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000007 # DW_ATE_unsigned - - Value: 0x0000000000000008 - # 0x00000014: - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000005 # DW_ATE_signed - - Value: 0x0000000000000008 - # 0x00000017: - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000008 # DW_ATE_unsigned_char - - Value: 0x0000000000000001 - # 0x0000001a: - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000006 # DW_ATE_signed_char - - Value: 0x0000000000000001 - # 0x0000001d: - - AbbrCode: 0x00000002 - Values: - - Value: 0x000000000000000b # DW_ATE_numeric_string - - Value: 0x0000000000000001 - - AbbrCode: 0x00000000 -)"; - uint8_t offs_uint32_t = 0x0000000e; - uint8_t offs_uint64_t = 0x00000011; - uint8_t offs_sint64_t = 0x00000014; - uint8_t offs_uchar = 0x00000017; - uint8_t offs_schar = 0x0000001a; - - DWARFExpressionTester t(yamldata); - ASSERT_TRUE((bool)t.GetDwarfUnit()); - - // Constant is given as little-endian. - bool is_signed = true; - bool not_signed = false; - - // - // Positive tests. - // - - // Leave as is. - EXPECT_THAT_EXPECTED( - t.Eval({DW_OP_const4u, 0x11, 0x22, 0x33, 0x44, // - DW_OP_convert, offs_uint32_t, DW_OP_stack_value}), - llvm::HasValue(GetScalar(64, 0x44332211, not_signed))); - - // Zero-extend to 64 bits. - EXPECT_THAT_EXPECTED( - t.Eval({DW_OP_const4u, 0x11, 0x22, 0x33, 0x44, // - DW_OP_convert, offs_uint64_t, DW_OP_stack_value}), - llvm::HasValue(GetScalar(64, 0x44332211, not_signed))); - - // Sign-extend to 64 bits. - EXPECT_THAT_EXPECTED( - t.Eval({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, // - DW_OP_convert, offs_sint64_t, DW_OP_stack_value}), - llvm::HasValue(GetScalar(64, 0xffffffffffeeddcc, is_signed))); - - // Sign-extend, then truncate. - EXPECT_THAT_EXPECTED( - t.Eval({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, // - DW_OP_convert, offs_sint64_t, // - DW_OP_convert, offs_uint32_t, DW_OP_stack_value}), - llvm::HasValue(GetScalar(32, 0xffeeddcc, not_signed))); - - // Truncate to default unspecified (pointer-sized) type. - EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, // - DW_OP_convert, offs_sint64_t, // - DW_OP_convert, 0x00, DW_OP_stack_value}), - llvm::HasValue(GetScalar(32, 0xffeeddcc, not_signed))); - - // Truncate to 8 bits. - EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', DW_OP_convert, - offs_uchar, DW_OP_stack_value}), - llvm::HasValue(GetScalar(8, 'A', not_signed))); - - // Also truncate to 8 bits. - EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', DW_OP_convert, - offs_schar, DW_OP_stack_value}), - llvm::HasValue(GetScalar(8, 'A', is_signed))); - - // - // Errors. - // - - // No Module. - EXPECT_THAT_ERROR(Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x00}, nullptr, - t.GetDwarfUnit()) - .takeError(), - llvm::Failed()); - - // No DIE. - EXPECT_THAT_ERROR( - t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x01}).takeError(), - llvm::Failed()); - - // Unsupported. - EXPECT_THAT_ERROR( - t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(), - llvm::Failed()); -} - -TEST(DWARFExpression, DW_OP_stack_value) { - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_stack_value}), llvm::Failed()); -} - -TEST(DWARFExpression, DW_OP_piece) { - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x11, 0x22, DW_OP_piece, 2, - DW_OP_const2u, 0x33, 0x44, DW_OP_piece, 2}), - llvm::HasValue(GetScalar(32, 0x44332211, true))); - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_piece, 1, DW_OP_const1u, 0xff, DW_OP_piece, 1}), - // Note that the "00" should really be "undef", but we can't - // represent that yet. - llvm::HasValue(GetScalar(16, 0xff00, true))); -} - -TEST(DWARFExpression, DW_OP_implicit_value) { - unsigned char bytes = 4; - - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_implicit_value, bytes, 0x11, 0x22, 0x33, 0x44}), - llvm::HasValue(GetScalar(8 * bytes, 0x44332211, true))); -} - -TEST(DWARFExpression, DW_OP_unknown) { - EXPECT_THAT_EXPECTED( - Evaluate({0xff}), - llvm::FailedWithMessage( - "Unhandled opcode DW_OP_unknown_ff in DWARFExpression")); -} - -TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) { - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed()); - - struct MockProcess : Process { - using Process::Process; - ConstString GetPluginName() override { return ConstString("mock process"); } - uint32_t GetPluginVersion() override { return 0; } - bool CanDebug(lldb::TargetSP target, - bool plugin_specified_by_name) override { - return false; - }; - Status DoDestroy() override { return {}; } - void RefreshStateAfterStop() override {} - bool DoUpdateThreadList(ThreadList &old_thread_list, - ThreadList &new_thread_list) override { - return false; - }; - size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - Status &error) override { - for (size_t i = 0; i < size; ++i) - ((char *)buf)[i] = (vm_addr + i) & 0xff; - error.Clear(); - return size; - } - }; - - // Set up a mock process. - ArchSpec arch("i386-pc-linux"); - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - lldb::DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - lldb::TargetSP target_sp; - lldb::PlatformSP platform_sp; - debugger_sp->GetTargetList().CreateTarget( - *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); - ASSERT_TRUE(target_sp); - ASSERT_TRUE(target_sp->GetArchitecture().IsValid()); - ASSERT_TRUE(platform_sp); - lldb::ListenerSP listener_sp(Listener::MakeListener("dummy")); - lldb::ProcessSP process_sp = - std::make_shared(target_sp, listener_sp); - ASSERT_TRUE(process_sp); - - ExecutionContext exe_ctx(process_sp); - // Implicit location: *0x4. - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, - {}, {}, &exe_ctx), - llvm::HasValue(GetScalar(32, 0x07060504, false))); - // Memory location: *(*0x4). - // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses. - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref}, {}, {}, &exe_ctx), - llvm::HasValue(Scalar(LLDB_INVALID_ADDRESS))); - // Memory location: *0x4. - // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses. - EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4}, {}, {}, &exe_ctx), - llvm::HasValue(Scalar(4))); - // Implicit location: *0x4. - // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses. - EXPECT_THAT_EXPECTED( - Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx), - llvm::HasValue(GetScalar(32, 0x07060504, false))); -} diff --git a/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp b/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp deleted file mode 100644 index 3cfb5ed0b66..00000000000 --- a/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//===-- DiagnosticManagerTest.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 "lldb/Expression/DiagnosticManager.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -static const uint32_t custom_diag_id = 42; - -namespace { -class FixItDiag : public Diagnostic { - bool m_has_fixits; - -public: - FixItDiag(llvm::StringRef msg, bool has_fixits) - : Diagnostic(msg, DiagnosticSeverity::eDiagnosticSeverityError, - DiagnosticOrigin::eDiagnosticOriginLLDB, custom_diag_id), - m_has_fixits(has_fixits) {} - bool HasFixIts() const override { return m_has_fixits; } -}; -} // namespace - -namespace { -class TextDiag : public Diagnostic { -public: - TextDiag(llvm::StringRef msg, DiagnosticSeverity severity) - : Diagnostic(msg, severity, DiagnosticOrigin::eDiagnosticOriginLLDB, - custom_diag_id) {} -}; -} // namespace - -TEST(DiagnosticManagerTest, AddDiagnostic) { - DiagnosticManager mgr; - EXPECT_EQ(0U, mgr.Diagnostics().size()); - - std::string msg = "foo bar has happened"; - DiagnosticSeverity severity = DiagnosticSeverity::eDiagnosticSeverityError; - DiagnosticOrigin origin = DiagnosticOrigin::eDiagnosticOriginLLDB; - auto diag = - std::make_unique(msg, severity, origin, custom_diag_id); - mgr.AddDiagnostic(std::move(diag)); - EXPECT_EQ(1U, mgr.Diagnostics().size()); - const Diagnostic *got = mgr.Diagnostics().front().get(); - EXPECT_EQ(DiagnosticOrigin::eDiagnosticOriginLLDB, got->getKind()); - EXPECT_EQ(msg, got->GetMessage()); - EXPECT_EQ(severity, got->GetSeverity()); - EXPECT_EQ(custom_diag_id, got->GetCompilerID()); - EXPECT_EQ(false, got->HasFixIts()); -} - -TEST(DiagnosticManagerTest, HasFixits) { - DiagnosticManager mgr; - // By default we shouldn't have any fixits. - EXPECT_FALSE(mgr.HasFixIts()); - // Adding a diag without fixits shouldn't make HasFixIts return true. - mgr.AddDiagnostic(std::make_unique("no fixit", false)); - EXPECT_FALSE(mgr.HasFixIts()); - // Adding a diag with fixits will mark the manager as containing fixits. - mgr.AddDiagnostic(std::make_unique("fixit", true)); - EXPECT_TRUE(mgr.HasFixIts()); - // Adding another diag without fixit shouldn't make it return false. - mgr.AddDiagnostic(std::make_unique("no fixit", false)); - EXPECT_TRUE(mgr.HasFixIts()); - // Adding a diag with fixits. The manager should still return true. - mgr.AddDiagnostic(std::make_unique("fixit", true)); - EXPECT_TRUE(mgr.HasFixIts()); -} - -TEST(DiagnosticManagerTest, GetStringNoDiags) { - DiagnosticManager mgr; - EXPECT_EQ("", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, GetStringBasic) { - DiagnosticManager mgr; - mgr.AddDiagnostic( - std::make_unique("abc", eDiagnosticSeverityError)); - EXPECT_EQ("error: abc\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, GetStringMultiline) { - DiagnosticManager mgr; - - // Multiline diagnostics should only get one severity label. - mgr.AddDiagnostic( - std::make_unique("b\nc", eDiagnosticSeverityError)); - EXPECT_EQ("error: b\nc\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, GetStringMultipleDiags) { - DiagnosticManager mgr; - mgr.AddDiagnostic( - std::make_unique("abc", eDiagnosticSeverityError)); - EXPECT_EQ("error: abc\n", mgr.GetString()); - mgr.AddDiagnostic( - std::make_unique("def", eDiagnosticSeverityError)); - EXPECT_EQ("error: abc\nerror: def\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, GetStringSeverityLabels) { - DiagnosticManager mgr; - - // Different severities should cause different labels. - mgr.AddDiagnostic( - std::make_unique("foo", eDiagnosticSeverityError)); - mgr.AddDiagnostic( - std::make_unique("bar", eDiagnosticSeverityWarning)); - // Remarks have no labels. - mgr.AddDiagnostic( - std::make_unique("baz", eDiagnosticSeverityRemark)); - EXPECT_EQ("error: foo\nwarning: bar\nbaz\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, GetStringPreserveOrder) { - DiagnosticManager mgr; - - // Make sure we preserve the diagnostic order and do not sort them in any way. - mgr.AddDiagnostic( - std::make_unique("baz", eDiagnosticSeverityRemark)); - mgr.AddDiagnostic( - std::make_unique("bar", eDiagnosticSeverityWarning)); - mgr.AddDiagnostic( - std::make_unique("foo", eDiagnosticSeverityError)); - EXPECT_EQ("baz\nwarning: bar\nerror: foo\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, AppendMessageNoDiag) { - DiagnosticManager mgr; - - // FIXME: This *really* should not just fail silently. - mgr.AppendMessageToDiagnostic("no diag has been pushed yet"); - EXPECT_EQ(0U, mgr.Diagnostics().size()); -} - -TEST(DiagnosticManagerTest, AppendMessageAttachToLastDiag) { - DiagnosticManager mgr; - - mgr.AddDiagnostic( - std::make_unique("foo", eDiagnosticSeverityError)); - mgr.AddDiagnostic( - std::make_unique("bar", eDiagnosticSeverityError)); - // This should append to 'bar' and not to 'foo'. - mgr.AppendMessageToDiagnostic("message text"); - - EXPECT_EQ("error: foo\nerror: bar\nmessage text\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, AppendMessageSubsequentDiags) { - DiagnosticManager mgr; - - mgr.AddDiagnostic( - std::make_unique("bar", eDiagnosticSeverityError)); - mgr.AppendMessageToDiagnostic("message text"); - // Pushing another diag after the message should work fine. - mgr.AddDiagnostic( - std::make_unique("foo", eDiagnosticSeverityError)); - - EXPECT_EQ("error: bar\nmessage text\nerror: foo\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, PutString) { - DiagnosticManager mgr; - - mgr.PutString(eDiagnosticSeverityError, "foo"); - EXPECT_EQ(1U, mgr.Diagnostics().size()); - EXPECT_EQ(eDiagnosticOriginLLDB, mgr.Diagnostics().front()->getKind()); - EXPECT_EQ("error: foo\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, PutStringMultiple) { - DiagnosticManager mgr; - - // Multiple PutString should behave like multiple diagnostics. - mgr.PutString(eDiagnosticSeverityError, "foo"); - mgr.PutString(eDiagnosticSeverityError, "bar"); - EXPECT_EQ(2U, mgr.Diagnostics().size()); - EXPECT_EQ("error: foo\nerror: bar\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, PutStringSeverities) { - DiagnosticManager mgr; - - // Multiple PutString with different severities should behave like we - // created multiple diagnostics. - mgr.PutString(eDiagnosticSeverityError, "foo"); - mgr.PutString(eDiagnosticSeverityWarning, "bar"); - EXPECT_EQ(2U, mgr.Diagnostics().size()); - EXPECT_EQ("error: foo\nwarning: bar\n", mgr.GetString()); -} - -TEST(DiagnosticManagerTest, FixedExpression) { - DiagnosticManager mgr; - - // By default there should be no fixed expression. - EXPECT_EQ("", mgr.GetFixedExpression()); - - // Setting the fixed expression should change it. - mgr.SetFixedExpression("foo"); - EXPECT_EQ("foo", mgr.GetFixedExpression()); - - // Setting the fixed expression again should also change it. - mgr.SetFixedExpression("bar"); - EXPECT_EQ("bar", mgr.GetFixedExpression()); -} diff --git a/gnu/llvm/lldb/unittests/Host/CMakeLists.txt b/gnu/llvm/lldb/unittests/Host/CMakeLists.txt deleted file mode 100644 index 1cc0cb081e4..00000000000 --- a/gnu/llvm/lldb/unittests/Host/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -set (FILES - ConnectionFileDescriptorTest.cpp - FileActionTest.cpp - FileSystemTest.cpp - FileTest.cpp - HostInfoTest.cpp - HostTest.cpp - MainLoopTest.cpp - NativeProcessProtocolTest.cpp - PipeTest.cpp - ProcessLaunchInfoTest.cpp - SocketAddressTest.cpp - SocketTest.cpp - SocketTestUtilities.cpp -) - -if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") - list(APPEND FILES - linux/HostTest.cpp - linux/SupportTest.cpp - ) -endif() - -add_lldb_unittest(HostTests - ${FILES} - LINK_LIBS - lldbHost - lldbUtilityHelpers - LLVMTestingSupport - ) diff --git a/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp b/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp deleted file mode 100644 index 76c54a96b22..00000000000 --- a/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===-- ConnectionFileDescriptorTest.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 "SocketTestUtilities.h" -#include "gtest/gtest.h" - -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" -#include "lldb/Utility/UriParser.h" - -using namespace lldb_private; - -class ConnectionFileDescriptorTest : public testing::Test { -public: - SubsystemRAII subsystems; - - void TestGetURI(std::string ip) { - std::unique_ptr socket_a_up; - std::unique_ptr socket_b_up; - CreateTCPConnectedSockets(ip, &socket_a_up, &socket_b_up); - auto socket = socket_a_up.release(); - ConnectionFileDescriptor connection_file_descriptor(socket); - - llvm::StringRef scheme; - llvm::StringRef hostname; - int port; - llvm::StringRef path; - std::string uri(connection_file_descriptor.GetURI()); - EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); - EXPECT_EQ(ip, hostname); - EXPECT_EQ(socket->GetRemotePortNumber(), port); - } -}; - -TEST_F(ConnectionFileDescriptorTest, TCPGetURIv4) { - if (!HostSupportsIPv4()) - return; - TestGetURI("127.0.0.1"); -} - -TEST_F(ConnectionFileDescriptorTest, TCPGetURIv6) { - if (!HostSupportsIPv6()) - return; - TestGetURI("::1"); -} diff --git a/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp b/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp deleted file mode 100644 index b208169aac2..00000000000 --- a/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//===-- FileActionTest.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 "lldb/Host/FileAction.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(FileActionTest, Open) { - FileAction Action; - Action.Open(47, FileSpec("/tmp"), /*read*/ true, /*write*/ false); - EXPECT_EQ(Action.GetAction(), FileAction::eFileActionOpen); - EXPECT_EQ(Action.GetFileSpec(), FileSpec("/tmp")); -} diff --git a/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp b/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp deleted file mode 100644 index f31c5c42a1e..00000000000 --- a/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp +++ /dev/null @@ -1,331 +0,0 @@ -//===-- FileSystemTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "lldb/Host/FileSystem.h" -#include "llvm/Support/Errc.h" - -extern const char *TestMainArgv0; - -using namespace lldb_private; -using namespace llvm; -using llvm::sys::fs::UniqueID; - -// Modified from llvm/unittests/Support/VirtualFileSystemTest.cpp -namespace { -struct DummyFile : public vfs::File { - vfs::Status S; - explicit DummyFile(vfs::Status S) : S(S) {} - llvm::ErrorOr status() override { return S; } - llvm::ErrorOr> - getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, - bool IsVolatile) override { - llvm_unreachable("unimplemented"); - } - std::error_code close() override { return std::error_code(); } -}; - -class DummyFileSystem : public vfs::FileSystem { - int FSID; // used to produce UniqueIDs - int FileID; // used to produce UniqueIDs - std::string cwd; - std::map FilesAndDirs; - - static int getNextFSID() { - static int Count = 0; - return Count++; - } - -public: - DummyFileSystem() : FSID(getNextFSID()), FileID(0) {} - - ErrorOr status(const Twine &Path) override { - std::map::iterator I = - FilesAndDirs.find(Path.str()); - if (I == FilesAndDirs.end()) - return make_error_code(llvm::errc::no_such_file_or_directory); - return I->second; - } - ErrorOr> - openFileForRead(const Twine &Path) override { - auto S = status(Path); - if (S) - return std::unique_ptr(new DummyFile{*S}); - return S.getError(); - } - llvm::ErrorOr getCurrentWorkingDirectory() const override { - return cwd; - } - std::error_code setCurrentWorkingDirectory(const Twine &Path) override { - cwd = Path.str(); - return std::error_code(); - } - // Map any symlink to "/symlink". - std::error_code getRealPath(const Twine &Path, - SmallVectorImpl &Output) const override { - auto I = FilesAndDirs.find(Path.str()); - if (I == FilesAndDirs.end()) - return make_error_code(llvm::errc::no_such_file_or_directory); - if (I->second.isSymlink()) { - Output.clear(); - Twine("/symlink").toVector(Output); - return std::error_code(); - } - Output.clear(); - Path.toVector(Output); - return std::error_code(); - } - - struct DirIterImpl : public llvm::vfs::detail::DirIterImpl { - std::map &FilesAndDirs; - std::map::iterator I; - std::string Path; - bool isInPath(StringRef S) { - if (Path.size() < S.size() && S.find(Path) == 0) { - auto LastSep = S.find_last_of('/'); - if (LastSep == Path.size() || LastSep == Path.size() - 1) - return true; - } - return false; - } - DirIterImpl(std::map &FilesAndDirs, - const Twine &_Path) - : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()), - Path(_Path.str()) { - for (; I != FilesAndDirs.end(); ++I) { - if (isInPath(I->first)) { - CurrentEntry = vfs::directory_entry(std::string(I->second.getName()), - I->second.getType()); - break; - } - } - } - std::error_code increment() override { - ++I; - for (; I != FilesAndDirs.end(); ++I) { - if (isInPath(I->first)) { - CurrentEntry = vfs::directory_entry(std::string(I->second.getName()), - I->second.getType()); - break; - } - } - if (I == FilesAndDirs.end()) - CurrentEntry = vfs::directory_entry(); - return std::error_code(); - } - }; - - vfs::directory_iterator dir_begin(const Twine &Dir, - std::error_code &EC) override { - return vfs::directory_iterator( - std::make_shared(FilesAndDirs, Dir)); - } - - void addEntry(StringRef Path, const vfs::Status &Status) { - FilesAndDirs[std::string(Path)] = Status; - } - - void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { - vfs::Status S(Path, UniqueID(FSID, FileID++), - std::chrono::system_clock::now(), 0, 0, 1024, - sys::fs::file_type::regular_file, Perms); - addEntry(Path, S); - } - - void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { - vfs::Status S(Path, UniqueID(FSID, FileID++), - std::chrono::system_clock::now(), 0, 0, 0, - sys::fs::file_type::directory_file, Perms); - addEntry(Path, S); - } - - void addSymlink(StringRef Path) { - vfs::Status S(Path, UniqueID(FSID, FileID++), - std::chrono::system_clock::now(), 0, 0, 0, - sys::fs::file_type::symlink_file, sys::fs::all_all); - addEntry(Path, S); - } -}; -} // namespace - -TEST(FileSystemTest, FileAndDirectoryComponents) { - using namespace std::chrono; - FileSystem fs; - -#ifdef _WIN32 - FileSpec fs1("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT"); -#else - FileSpec fs1("/file/that/does/not/exist.txt"); -#endif - FileSpec fs2(TestMainArgv0); - - fs.Resolve(fs2); - - EXPECT_EQ(system_clock::time_point(), fs.GetModificationTime(fs1)); - EXPECT_LT(system_clock::time_point() + hours(24 * 365 * 20), - fs.GetModificationTime(fs2)); -} - -static IntrusiveRefCntPtr GetSimpleDummyFS() { - IntrusiveRefCntPtr D(new DummyFileSystem()); - D->addRegularFile("/foo"); - D->addDirectory("/bar"); - D->addSymlink("/baz"); - D->addRegularFile("/qux", ~sys::fs::perms::all_read); - D->setCurrentWorkingDirectory("/"); - return D; -} - -TEST(FileSystemTest, Exists) { - FileSystem fs(GetSimpleDummyFS()); - - EXPECT_TRUE(fs.Exists("/foo")); - EXPECT_TRUE(fs.Exists(FileSpec("/foo", FileSpec::Style::posix))); -} - -TEST(FileSystemTest, Readable) { - FileSystem fs(GetSimpleDummyFS()); - - EXPECT_TRUE(fs.Readable("/foo")); - EXPECT_TRUE(fs.Readable(FileSpec("/foo", FileSpec::Style::posix))); - - EXPECT_FALSE(fs.Readable("/qux")); - EXPECT_FALSE(fs.Readable(FileSpec("/qux", FileSpec::Style::posix))); -} - -TEST(FileSystemTest, GetByteSize) { - FileSystem fs(GetSimpleDummyFS()); - - EXPECT_EQ((uint64_t)1024, fs.GetByteSize("/foo")); - EXPECT_EQ((uint64_t)1024, - fs.GetByteSize(FileSpec("/foo", FileSpec::Style::posix))); -} - -TEST(FileSystemTest, GetPermissions) { - FileSystem fs(GetSimpleDummyFS()); - - EXPECT_EQ(sys::fs::all_all, fs.GetPermissions("/foo")); - EXPECT_EQ(sys::fs::all_all, - fs.GetPermissions(FileSpec("/foo", FileSpec::Style::posix))); -} - -TEST(FileSystemTest, MakeAbsolute) { - FileSystem fs(GetSimpleDummyFS()); - - { - StringRef foo_relative = "foo"; - SmallString<16> foo(foo_relative); - auto EC = fs.MakeAbsolute(foo); - EXPECT_FALSE(EC); - EXPECT_TRUE(foo.equals("/foo")); - } - - { - FileSpec file_spec("foo"); - auto EC = fs.MakeAbsolute(file_spec); - EXPECT_FALSE(EC); - EXPECT_EQ(FileSpec("/foo"), file_spec); - } -} - -TEST(FileSystemTest, Resolve) { - FileSystem fs(GetSimpleDummyFS()); - - { - StringRef foo_relative = "foo"; - SmallString<16> foo(foo_relative); - fs.Resolve(foo); - EXPECT_TRUE(foo.equals("/foo")); - } - - { - FileSpec file_spec("foo"); - fs.Resolve(file_spec); - EXPECT_EQ(FileSpec("/foo"), file_spec); - } - - { - StringRef foo_relative = "bogus"; - SmallString<16> foo(foo_relative); - fs.Resolve(foo); - EXPECT_TRUE(foo.equals("bogus")); - } - - { - FileSpec file_spec("bogus"); - fs.Resolve(file_spec); - EXPECT_EQ(FileSpec("bogus"), file_spec); - } -} - -FileSystem::EnumerateDirectoryResult -VFSCallback(void *baton, llvm::sys::fs::file_type file_type, - llvm::StringRef path) { - auto visited = static_cast *>(baton); - visited->push_back(path.str()); - return FileSystem::eEnumerateDirectoryResultNext; -} - -TEST(FileSystemTest, EnumerateDirectory) { - FileSystem fs(GetSimpleDummyFS()); - - std::vector visited; - - constexpr bool find_directories = true; - constexpr bool find_files = true; - constexpr bool find_other = true; - - fs.EnumerateDirectory("/", find_directories, find_files, find_other, - VFSCallback, &visited); - - EXPECT_THAT(visited, - testing::UnorderedElementsAre("/foo", "/bar", "/baz", "/qux")); -} - -TEST(FileSystemTest, OpenErrno) { -#ifdef _WIN32 - FileSpec spec("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT"); -#else - FileSpec spec("/file/that/does/not/exist.txt"); -#endif - FileSystem fs; - auto file = fs.Open(spec, File::eOpenOptionRead, 0, true); - ASSERT_FALSE(file); - std::error_code code = errorToErrorCode(file.takeError()); - EXPECT_EQ(code.category(), std::system_category()); - EXPECT_EQ(code.value(), ENOENT); -} - -TEST(FileSystemTest, EmptyTest) { - FileSpec spec; - FileSystem fs; - - { - std::error_code ec; - fs.DirBegin(spec, ec); - EXPECT_EQ(ec.category(), std::system_category()); - EXPECT_EQ(ec.value(), ENOENT); - } - - { - llvm::ErrorOr status = fs.GetStatus(spec); - ASSERT_FALSE(status); - EXPECT_EQ(status.getError().category(), std::system_category()); - EXPECT_EQ(status.getError().value(), ENOENT); - } - - EXPECT_EQ(sys::TimePoint<>(), fs.GetModificationTime(spec)); - EXPECT_EQ(static_cast(0), fs.GetByteSize(spec)); - EXPECT_EQ(llvm::sys::fs::perms::perms_not_known, fs.GetPermissions(spec)); - EXPECT_FALSE(fs.Exists(spec)); - EXPECT_FALSE(fs.Readable(spec)); - EXPECT_FALSE(fs.IsDirectory(spec)); - EXPECT_FALSE(fs.IsLocal(spec)); -} diff --git a/gnu/llvm/lldb/unittests/Host/FileTest.cpp b/gnu/llvm/lldb/unittests/Host/FileTest.cpp deleted file mode 100644 index 126d5e31486..00000000000 --- a/gnu/llvm/lldb/unittests/Host/FileTest.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//===-- FileTest.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 "lldb/Host/File.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(File, GetWaitableHandleFileno) { - const auto *Info = testing::UnitTest::GetInstance()->current_test_info(); - - llvm::SmallString<128> name; - int fd; - llvm::sys::fs::createTemporaryFile(llvm::Twine(Info->test_case_name()) + "-" + - Info->name(), - "test", fd, name); - llvm::FileRemover remover(name); - ASSERT_GE(fd, 0); - - FILE *stream = fdopen(fd, "r"); - ASSERT_TRUE(stream); - - NativeFile file(stream, true); - EXPECT_EQ(file.GetWaitableHandle(), fd); -} - -TEST(File, GetStreamFromDescriptor) { - const auto *Info = testing::UnitTest::GetInstance()->current_test_info(); - llvm::SmallString<128> name; - int fd; - llvm::sys::fs::createTemporaryFile(llvm::Twine(Info->test_case_name()) + "-" + - Info->name(), - "test", fd, name); - - llvm::FileRemover remover(name); - ASSERT_GE(fd, 0); - - NativeFile file(fd, File::eOpenOptionWrite, true); - ASSERT_TRUE(file.IsValid()); - - FILE *stream = file.GetStream(); - ASSERT_TRUE(stream != NULL); - - EXPECT_EQ(file.GetDescriptor(), fd); - EXPECT_EQ(file.GetWaitableHandle(), fd); -} diff --git a/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp b/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp deleted file mode 100644 index 0accdd8dbcd..00000000000 --- a/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//===-- HostInfoTest.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 "lldb/Host/HostInfo.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/lldb-defines.h" -#include "llvm/Support/Host.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace llvm; - -namespace { -class HostInfoTest : public ::testing::Test { - SubsystemRAII subsystems; -}; -} // namespace - -TEST_F(HostInfoTest, GetAugmentedArchSpec) { - // Fully specified triple should not be changed. - ArchSpec spec = HostInfo::GetAugmentedArchSpec("x86_64-pc-linux-gnu"); - EXPECT_EQ(spec.GetTriple().getTriple(), "x86_64-pc-linux-gnu"); - - // Same goes if we specify at least one of (os, vendor, env). - spec = HostInfo::GetAugmentedArchSpec("x86_64-pc"); - EXPECT_EQ(spec.GetTriple().getTriple(), "x86_64-pc"); - - // But if we specify only an arch, we should fill in the rest from the host. - spec = HostInfo::GetAugmentedArchSpec("x86_64"); - Triple triple(sys::getDefaultTargetTriple()); - EXPECT_EQ(spec.GetTriple().getArch(), Triple::x86_64); - EXPECT_EQ(spec.GetTriple().getOS(), triple.getOS()); - EXPECT_EQ(spec.GetTriple().getVendor(), triple.getVendor()); - EXPECT_EQ(spec.GetTriple().getEnvironment(), triple.getEnvironment()); - - // Test LLDB_ARCH_DEFAULT - EXPECT_EQ(HostInfo::GetAugmentedArchSpec(LLDB_ARCH_DEFAULT).GetTriple(), - HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple()); -} - -TEST_F(HostInfoTest, GetHostname) { - // Check non-empty string input works correctly. - std::string s("abc"); - EXPECT_TRUE(HostInfo::GetHostname(s)); -} - -#if defined(__APPLE__) -TEST_F(HostInfoTest, GetXcodeSDK) { - EXPECT_FALSE(HostInfo::GetXcodeSDKPath(XcodeSDK("MacOSX.sdk")).empty()); - // These are expected to fall back to an available version. - EXPECT_FALSE(HostInfo::GetXcodeSDKPath(XcodeSDK("MacOSX9999.sdk")).empty()); - // This is expected to fail. - EXPECT_TRUE(HostInfo::GetXcodeSDKPath(XcodeSDK("CeciNestPasUnOS.sdk")).empty()); -} -#endif - -TEST(HostInfoTestInitialization, InitTwice) { - llvm::VersionTuple Version; - { - SubsystemRAII subsystems; - Version = HostInfo::GetOSVersion(); - } - - { - SubsystemRAII subsystems; - EXPECT_EQ(Version, HostInfo::GetOSVersion()); - } -} diff --git a/gnu/llvm/lldb/unittests/Host/HostTest.cpp b/gnu/llvm/lldb/unittests/Host/HostTest.cpp deleted file mode 100644 index 5e01a6835c0..00000000000 --- a/gnu/llvm/lldb/unittests/Host/HostTest.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===-- HostTest.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 "lldb/Host/Host.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace llvm; - -TEST(Host, WaitStatusFormat) { - EXPECT_EQ("W01", formatv("{0:g}", WaitStatus{WaitStatus::Exit, 1}).str()); - EXPECT_EQ("X02", formatv("{0:g}", WaitStatus{WaitStatus::Signal, 2}).str()); - EXPECT_EQ("S03", formatv("{0:g}", WaitStatus{WaitStatus::Stop, 3}).str()); - EXPECT_EQ("Exited with status 4", - formatv("{0}", WaitStatus{WaitStatus::Exit, 4}).str()); -} - -TEST(Host, GetEnvironment) { - putenv(const_cast("LLDB_TEST_ENVIRONMENT_VAR=Host::GetEnvironment")); - ASSERT_EQ("Host::GetEnvironment", - Host::GetEnvironment().lookup("LLDB_TEST_ENVIRONMENT_VAR")); -} diff --git a/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp b/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp deleted file mode 100644 index 890f6eb6619..00000000000 --- a/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//===-- MainLoopTest.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 "lldb/Host/MainLoop.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/PseudoTerminal.h" -#include "lldb/Host/common/TCPSocket.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" -#include - -using namespace lldb_private; - -namespace { -class MainLoopTest : public testing::Test { -public: - SubsystemRAII subsystems; - - void SetUp() override { - bool child_processes_inherit = false; - Status error; - std::unique_ptr listen_socket_up( - new TCPSocket(true, child_processes_inherit)); - ASSERT_TRUE(error.Success()); - error = listen_socket_up->Listen("localhost:0", 5); - ASSERT_TRUE(error.Success()); - - Socket *accept_socket; - std::future accept_error = std::async(std::launch::async, [&] { - return listen_socket_up->Accept(accept_socket); - }); - - std::unique_ptr connect_socket_up( - new TCPSocket(true, child_processes_inherit)); - error = connect_socket_up->Connect( - llvm::formatv("localhost:{0}", listen_socket_up->GetLocalPortNumber()) - .str()); - ASSERT_TRUE(error.Success()); - ASSERT_TRUE(accept_error.get().Success()); - - callback_count = 0; - socketpair[0] = std::move(connect_socket_up); - socketpair[1].reset(accept_socket); - } - - void TearDown() override { - socketpair[0].reset(); - socketpair[1].reset(); - } - -protected: - MainLoop::Callback make_callback() { - return [&](MainLoopBase &loop) { - ++callback_count; - loop.RequestTermination(); - }; - } - std::shared_ptr socketpair[2]; - unsigned callback_count; -}; -} // namespace - -TEST_F(MainLoopTest, ReadObject) { - char X = 'X'; - size_t len = sizeof(X); - ASSERT_TRUE(socketpair[0]->Write(&X, len).Success()); - - MainLoop loop; - - Status error; - auto handle = loop.RegisterReadObject(socketpair[1], make_callback(), error); - ASSERT_TRUE(error.Success()); - ASSERT_TRUE(handle); - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(1u, callback_count); -} - -TEST_F(MainLoopTest, TerminatesImmediately) { - char X = 'X'; - size_t len = sizeof(X); - ASSERT_TRUE(socketpair[0]->Write(&X, len).Success()); - ASSERT_TRUE(socketpair[1]->Write(&X, len).Success()); - - MainLoop loop; - Status error; - auto handle0 = loop.RegisterReadObject(socketpair[0], make_callback(), error); - ASSERT_TRUE(error.Success()); - auto handle1 = loop.RegisterReadObject(socketpair[1], make_callback(), error); - ASSERT_TRUE(error.Success()); - - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(1u, callback_count); -} - -#ifdef LLVM_ON_UNIX -TEST_F(MainLoopTest, DetectsEOF) { - - PseudoTerminal term; - ASSERT_THAT_ERROR(term.OpenFirstAvailablePrimary(O_RDWR), llvm::Succeeded()); - ASSERT_THAT_ERROR(term.OpenSecondary(O_RDWR | O_NOCTTY), llvm::Succeeded()); - auto conn = std::make_unique( - term.ReleasePrimaryFileDescriptor(), true); - - Status error; - MainLoop loop; - auto handle = - loop.RegisterReadObject(conn->GetReadObject(), make_callback(), error); - ASSERT_TRUE(error.Success()); - term.CloseSecondaryFileDescriptor(); - - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(1u, callback_count); -} - -TEST_F(MainLoopTest, Signal) { - MainLoop loop; - Status error; - - auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error); - ASSERT_TRUE(error.Success()); - kill(getpid(), SIGUSR1); - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(1u, callback_count); -} - -// Test that a signal which is not monitored by the MainLoop does not -// cause a premature exit. -TEST_F(MainLoopTest, UnmonitoredSignal) { - MainLoop loop; - Status error; - struct sigaction sa; - sa.sa_sigaction = [](int, siginfo_t *, void *) { }; - sa.sa_flags = SA_SIGINFO; // important: no SA_RESTART - sigemptyset(&sa.sa_mask); - ASSERT_EQ(0, sigaction(SIGUSR2, &sa, nullptr)); - - auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error); - ASSERT_TRUE(error.Success()); - std::thread killer([]() { - sleep(1); - kill(getpid(), SIGUSR2); - sleep(1); - kill(getpid(), SIGUSR1); - }); - ASSERT_TRUE(loop.Run().Success()); - killer.join(); - ASSERT_EQ(1u, callback_count); -} - -// Test that two callbacks can be registered for the same signal -// and unregistered independently. -TEST_F(MainLoopTest, TwoSignalCallbacks) { - MainLoop loop; - Status error; - unsigned callback2_count = 0; - unsigned callback3_count = 0; - - auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error); - ASSERT_TRUE(error.Success()); - - { - // Run a single iteration with two callbacks enabled. - auto handle2 = loop.RegisterSignal( - SIGUSR1, [&](MainLoopBase &loop) { ++callback2_count; }, error); - ASSERT_TRUE(error.Success()); - - kill(getpid(), SIGUSR1); - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(1u, callback_count); - ASSERT_EQ(1u, callback2_count); - ASSERT_EQ(0u, callback3_count); - } - - { - // Make sure that remove + add new works. - auto handle3 = loop.RegisterSignal( - SIGUSR1, [&](MainLoopBase &loop) { ++callback3_count; }, error); - ASSERT_TRUE(error.Success()); - - kill(getpid(), SIGUSR1); - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(2u, callback_count); - ASSERT_EQ(1u, callback2_count); - ASSERT_EQ(1u, callback3_count); - } - - // Both extra callbacks should be unregistered now. - kill(getpid(), SIGUSR1); - ASSERT_TRUE(loop.Run().Success()); - ASSERT_EQ(3u, callback_count); - ASSERT_EQ(1u, callback2_count); - ASSERT_EQ(1u, callback3_count); -} -#endif diff --git a/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp b/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp deleted file mode 100644 index a48e67c9213..00000000000 --- a/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp +++ /dev/null @@ -1,149 +0,0 @@ -//===-- NativeProcessProtocolTest.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 "TestingSupport/Host/NativeProcessTestUtils.h" - -#include "lldb/Host/common/NativeProcessProtocol.h" -#include "llvm/Support/Process.h" -#include "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" - -using namespace lldb_private; -using namespace lldb; -using namespace testing; - -TEST(NativeProcessProtocolTest, SetBreakpoint) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("x86_64-pc-linux")); - auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1)); - InSequence S; - EXPECT_CALL(Process, ReadMemory(0x47, 1)) - .WillOnce(Return(ByMove(std::vector{0xbb}))); - EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1))); - EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap))); - EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(), - llvm::Succeeded()); -} - -TEST(NativeProcessProtocolTest, SetBreakpointFailRead) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("x86_64-pc-linux")); - EXPECT_CALL(Process, ReadMemory(0x47, 1)) - .WillOnce(Return(ByMove( - llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo")))); - EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(), - llvm::Failed()); -} - -TEST(NativeProcessProtocolTest, SetBreakpointFailWrite) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("x86_64-pc-linux")); - auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1)); - InSequence S; - EXPECT_CALL(Process, ReadMemory(0x47, 1)) - .WillOnce(Return(ByMove(std::vector{0xbb}))); - EXPECT_CALL(Process, WriteMemory(0x47, Trap)) - .WillOnce(Return(ByMove( - llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo")))); - EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(), - llvm::Failed()); -} - -TEST(NativeProcessProtocolTest, SetBreakpointFailVerify) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("x86_64-pc-linux")); - auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1)); - InSequence S; - EXPECT_CALL(Process, ReadMemory(0x47, 1)) - .WillOnce(Return(ByMove(std::vector{0xbb}))); - EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1))); - EXPECT_CALL(Process, ReadMemory(0x47, 1)) - .WillOnce(Return(ByMove( - llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo")))); - EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(), - llvm::Failed()); -} - -TEST(NativeProcessProtocolTest, ReadMemoryWithoutTrap) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("aarch64-pc-linux")); - FakeMemory M{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; - EXPECT_CALL(Process, ReadMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); - EXPECT_CALL(Process, WriteMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Write)); - - EXPECT_THAT_ERROR(Process.SetBreakpoint(0x4, 0, false).ToError(), - llvm::Succeeded()); - EXPECT_THAT_EXPECTED( - Process.ReadMemoryWithoutTrap(0, 10), - llvm::HasValue(std::vector{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); - EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(0, 6), - llvm::HasValue(std::vector{0, 1, 2, 3, 4, 5})); - EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 4), - llvm::HasValue(std::vector{6, 7, 8, 9})); - EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 2), - llvm::HasValue(std::vector{6, 7})); - EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(4, 2), - llvm::HasValue(std::vector{4, 5})); -} - -TEST(NativeProcessProtocolTest, ReadCStringFromMemory) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("aarch64-pc-linux")); - FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'}); - EXPECT_CALL(Process, ReadMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); - - char string[1024]; - size_t bytes_read; - EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory( - 0x0, &string[0], sizeof(string), bytes_read), - llvm::HasValue(llvm::StringRef("hello"))); - EXPECT_EQ(bytes_read, 6UL); -} - -TEST(NativeProcessProtocolTest, ReadCStringFromMemory_MaxSize) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("aarch64-pc-linux")); - FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'}); - EXPECT_CALL(Process, ReadMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); - - char string[4]; - size_t bytes_read; - EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory( - 0x0, &string[0], sizeof(string), bytes_read), - llvm::HasValue(llvm::StringRef("hel"))); - EXPECT_EQ(bytes_read, 3UL); -} - -TEST(NativeProcessProtocolTest, ReadCStringFromMemory_CrossPageBoundary) { - NiceMock DummyDelegate; - MockProcess Process(DummyDelegate, - ArchSpec("aarch64-pc-linux")); - unsigned string_start = llvm::sys::Process::getPageSizeEstimate() - 3; - FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'}, string_start); - EXPECT_CALL(Process, ReadMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); - - char string[1024]; - size_t bytes_read; - EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(string_start, &string[0], - sizeof(string), - bytes_read), - llvm::HasValue(llvm::StringRef("hello"))); - EXPECT_EQ(bytes_read, 6UL); -} \ No newline at end of file diff --git a/gnu/llvm/lldb/unittests/Host/PipeTest.cpp b/gnu/llvm/lldb/unittests/Host/PipeTest.cpp deleted file mode 100644 index 35a44ccf037..00000000000 --- a/gnu/llvm/lldb/unittests/Host/PipeTest.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//===-- PipeTest.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 "lldb/Host/Pipe.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -class PipeTest : public testing::Test { -public: - SubsystemRAII subsystems; -}; - -TEST_F(PipeTest, CreateWithUniqueName) { - Pipe pipe; - llvm::SmallString<0> name; - ASSERT_THAT_ERROR(pipe.CreateWithUniqueName("PipeTest-CreateWithUniqueName", - /*child_process_inherit=*/false, - name) - .ToError(), - llvm::Succeeded()); -} - -// Test broken -#ifndef _WIN32 -TEST_F(PipeTest, OpenAsReader) { - Pipe pipe; - llvm::SmallString<0> name; - ASSERT_THAT_ERROR(pipe.CreateWithUniqueName("PipeTest-OpenAsReader", - /*child_process_inherit=*/false, - name) - .ToError(), - llvm::Succeeded()); - - // Ensure name is not null-terminated - size_t name_len = name.size(); - name += "foobar"; - llvm::StringRef name_ref(name.data(), name_len); - ASSERT_THAT_ERROR( - pipe.OpenAsReader(name_ref, /*child_process_inherit=*/false).ToError(), - llvm::Succeeded()); -} -#endif diff --git a/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp b/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp deleted file mode 100644 index 0b3607092e8..00000000000 --- a/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===-- ProcessLaunchInfoTest.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 "lldb/Host/ProcessLaunchInfo.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb; - -TEST(ProcessLaunchInfoTest, Constructor) { - ProcessLaunchInfo Info(FileSpec("/stdin"), FileSpec("/stdout"), - FileSpec("/stderr"), FileSpec("/wd"), - eLaunchFlagStopAtEntry); - EXPECT_EQ(FileSpec("/stdin"), - Info.GetFileActionForFD(STDIN_FILENO)->GetFileSpec()); - EXPECT_EQ(FileSpec("/stdout"), - Info.GetFileActionForFD(STDOUT_FILENO)->GetFileSpec()); - EXPECT_EQ(FileSpec("/stderr"), - Info.GetFileActionForFD(STDERR_FILENO)->GetFileSpec()); - EXPECT_EQ(FileSpec("/wd"), Info.GetWorkingDirectory()); - EXPECT_EQ(eLaunchFlagStopAtEntry, Info.GetFlags().Get()); -} diff --git a/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp b/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp deleted file mode 100644 index dc5f55253f6..00000000000 --- a/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//===-- SocketAddressTest.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 "lldb/Host/SocketAddress.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/Socket.h" -#include "llvm/Testing/Support/Error.h" - -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -class SocketAddressTest : public testing::Test { -public: - SubsystemRAII subsystems; -}; -} // namespace - -TEST_F(SocketAddressTest, Set) { - SocketAddress sa; - ASSERT_TRUE(sa.SetToLocalhost(AF_INET, 1138)); - ASSERT_STREQ("127.0.0.1", sa.GetIPAddress().c_str()); - ASSERT_EQ(1138, sa.GetPort()); - - ASSERT_TRUE(sa.SetToAnyAddress(AF_INET, 0)); - ASSERT_STREQ("0.0.0.0", sa.GetIPAddress().c_str()); - ASSERT_EQ(0, sa.GetPort()); - - ASSERT_TRUE(sa.SetToLocalhost(AF_INET6, 1139)); - ASSERT_TRUE(sa.GetIPAddress() == "::1" || - sa.GetIPAddress() == "0:0:0:0:0:0:0:1") - << "Address was: " << sa.GetIPAddress(); - ASSERT_EQ(1139, sa.GetPort()); -} - -TEST_F(SocketAddressTest, GetAddressInfo) { - auto addr = SocketAddress::GetAddressInfo("127.0.0.1", nullptr, AF_UNSPEC, - SOCK_STREAM, IPPROTO_TCP); - ASSERT_EQ(1u, addr.size()); - EXPECT_EQ(AF_INET, addr[0].GetFamily()); - EXPECT_EQ("127.0.0.1", addr[0].GetIPAddress()); -} - -#ifdef _WIN32 - -// we need to test our inet_ntop implementation for Windows XP -const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); - -TEST_F(SocketAddressTest, inet_ntop) { - const uint8_t address4[4] = {255, 0, 1, 100}; - const uint8_t address6[16] = {0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 255, 0}; - - char buffer[INET6_ADDRSTRLEN]; - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ("1:203:405:607:809:a0b:c0d:ff00", - inet_ntop(AF_INET6, address6, buffer, sizeof(buffer))); - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ("1:203:405:607:809:a0b:c0d:ff00", - inet_ntop(AF_INET6, address6, buffer, 31)); - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ(nullptr, inet_ntop(AF_INET6, address6, buffer, 0)); - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ(nullptr, inet_ntop(AF_INET6, address6, buffer, 30)); - - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ("255.0.1.100", - inet_ntop(AF_INET, address4, buffer, sizeof(buffer))); - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ("255.0.1.100", inet_ntop(AF_INET, address4, buffer, 12)); - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ(nullptr, inet_ntop(AF_INET, address4, buffer, 0)); - memset(buffer, 'x', sizeof(buffer)); - EXPECT_STREQ(nullptr, inet_ntop(AF_INET, address4, buffer, 11)); -} - -#endif diff --git a/gnu/llvm/lldb/unittests/Host/SocketTest.cpp b/gnu/llvm/lldb/unittests/Host/SocketTest.cpp deleted file mode 100644 index 27d42f83571..00000000000 --- a/gnu/llvm/lldb/unittests/Host/SocketTest.cpp +++ /dev/null @@ -1,239 +0,0 @@ -//===-- SocketTest.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 "SocketTestUtilities.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/Config.h" -#include "lldb/Utility/UriParser.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -struct SocketTestParams { - bool is_ipv6; - std::string localhost_ip; -}; - -class SocketTest : public testing::TestWithParam { -public: - SubsystemRAII subsystems; - -protected: - bool HostSupportsProtocol() const { - if (GetParam().is_ipv6) - return HostSupportsIPv6(); - return HostSupportsIPv4(); - } -}; - -TEST_P(SocketTest, DecodeHostAndPort) { - std::string host_str; - std::string port_str; - int32_t port; - Status error; - EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str, - port, &error)); - EXPECT_STREQ("localhost", host_str.c_str()); - EXPECT_STREQ("1138", port_str.c_str()); - EXPECT_EQ(1138, port); - EXPECT_TRUE(error.Success()); - - EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, - port, &error)); - EXPECT_TRUE(error.Fail()); - EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", - error.AsCString()); - - EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str, - port, &error)); - EXPECT_TRUE(error.Fail()); - EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'", - error.AsCString()); - - EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, - port, &error)); - EXPECT_TRUE(error.Fail()); - EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", - error.AsCString()); - - EXPECT_TRUE( - Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error)); - EXPECT_STREQ("", host_str.c_str()); - EXPECT_STREQ("12345", port_str.c_str()); - EXPECT_EQ(12345, port); - EXPECT_TRUE(error.Success()); - - EXPECT_TRUE( - Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error)); - EXPECT_STREQ("*", host_str.c_str()); - EXPECT_STREQ("0", port_str.c_str()); - EXPECT_EQ(0, port); - EXPECT_TRUE(error.Success()); - - EXPECT_TRUE( - Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error)); - EXPECT_STREQ("*", host_str.c_str()); - EXPECT_STREQ("65535", port_str.c_str()); - EXPECT_EQ(65535, port); - EXPECT_TRUE(error.Success()); - - EXPECT_TRUE( - Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error)); - EXPECT_STREQ("::1", host_str.c_str()); - EXPECT_STREQ("12345", port_str.c_str()); - EXPECT_EQ(12345, port); - EXPECT_TRUE(error.Success()); - - EXPECT_TRUE( - Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error)); - EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str()); - EXPECT_STREQ("12345", port_str.c_str()); - EXPECT_EQ(12345, port); - EXPECT_TRUE(error.Success()); -} - -#if LLDB_ENABLE_POSIX -TEST_P(SocketTest, DomainListenConnectAccept) { - llvm::SmallString<64> Path; - std::error_code EC = llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path); - ASSERT_FALSE(EC); - llvm::sys::path::append(Path, "test"); - - // Skip the test if the $TMPDIR is too long to hold a domain socket. - if (Path.size() > 107u) - return; - - std::unique_ptr socket_a_up; - std::unique_ptr socket_b_up; - CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up); -} -#endif - -TEST_P(SocketTest, TCPListen0ConnectAccept) { - if (!HostSupportsProtocol()) - return; - std::unique_ptr socket_a_up; - std::unique_ptr socket_b_up; - CreateTCPConnectedSockets(GetParam().localhost_ip, &socket_a_up, - &socket_b_up); -} - -TEST_P(SocketTest, TCPGetAddress) { - std::unique_ptr socket_a_up; - std::unique_ptr socket_b_up; - if (!HostSupportsProtocol()) - return; - CreateTCPConnectedSockets(GetParam().localhost_ip, &socket_a_up, - &socket_b_up); - - EXPECT_EQ(socket_a_up->GetLocalPortNumber(), - socket_b_up->GetRemotePortNumber()); - EXPECT_EQ(socket_b_up->GetLocalPortNumber(), - socket_a_up->GetRemotePortNumber()); - EXPECT_NE(socket_a_up->GetLocalPortNumber(), - socket_b_up->GetLocalPortNumber()); - EXPECT_STREQ(GetParam().localhost_ip.c_str(), - socket_a_up->GetRemoteIPAddress().c_str()); - EXPECT_STREQ(GetParam().localhost_ip.c_str(), - socket_b_up->GetRemoteIPAddress().c_str()); -} - -TEST_P(SocketTest, UDPConnect) { - // UDPSocket::Connect() creates sockets with AF_INET (IPv4). - if (!HostSupportsIPv4()) - return; - llvm::Expected> socket = - UDPSocket::Connect("127.0.0.1:0", /*child_processes_inherit=*/false); - - ASSERT_THAT_EXPECTED(socket, llvm::Succeeded()); - EXPECT_TRUE(socket.get()->IsValid()); -} - -TEST_P(SocketTest, TCPListen0GetPort) { - if (!HostSupportsIPv4()) - return; - Predicate port_predicate; - port_predicate.SetValue(0, eBroadcastNever); - llvm::Expected> sock = - Socket::TcpListen("10.10.12.3:0", false, &port_predicate); - ASSERT_THAT_EXPECTED(sock, llvm::Succeeded()); - ASSERT_TRUE(sock.get()->IsValid()); - EXPECT_NE(sock.get()->GetLocalPortNumber(), 0); -} - -TEST_P(SocketTest, TCPGetConnectURI) { - std::unique_ptr socket_a_up; - std::unique_ptr socket_b_up; - if (!HostSupportsProtocol()) - return; - CreateTCPConnectedSockets(GetParam().localhost_ip, &socket_a_up, - &socket_b_up); - - llvm::StringRef scheme; - llvm::StringRef hostname; - int port; - llvm::StringRef path; - std::string uri(socket_a_up->GetRemoteConnectionURI()); - EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); - EXPECT_EQ(scheme, "connect"); - EXPECT_EQ(port, socket_a_up->GetRemotePortNumber()); -} - -TEST_P(SocketTest, UDPGetConnectURI) { - // UDPSocket::Connect() creates sockets with AF_INET (IPv4). - if (!HostSupportsIPv4()) - return; - llvm::Expected> socket = - UDPSocket::Connect("127.0.0.1:0", /*child_processes_inherit=*/false); - ASSERT_THAT_EXPECTED(socket, llvm::Succeeded()); - - llvm::StringRef scheme; - llvm::StringRef hostname; - int port; - llvm::StringRef path; - std::string uri = socket.get()->GetRemoteConnectionURI(); - EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); - EXPECT_EQ(scheme, "udp"); -} - -#if LLDB_ENABLE_POSIX -TEST_P(SocketTest, DomainGetConnectURI) { - llvm::SmallString<64> domain_path; - std::error_code EC = - llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", domain_path); - ASSERT_FALSE(EC); - llvm::sys::path::append(domain_path, "test"); - - // Skip the test if the $TMPDIR is too long to hold a domain socket. - if (domain_path.size() > 107u) - return; - - std::unique_ptr socket_a_up; - std::unique_ptr socket_b_up; - CreateDomainConnectedSockets(domain_path, &socket_a_up, &socket_b_up); - - llvm::StringRef scheme; - llvm::StringRef hostname; - int port; - llvm::StringRef path; - std::string uri(socket_a_up->GetRemoteConnectionURI()); - EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); - EXPECT_EQ(scheme, "unix-connect"); - EXPECT_EQ(path, domain_path); -} -#endif - -INSTANTIATE_TEST_SUITE_P( - SocketTests, SocketTest, - testing::Values(SocketTestParams{/*is_ipv6=*/false, - /*localhost_ip=*/"127.0.0.1"}, - SocketTestParams{/*is_ipv6=*/true, /*localhost_ip=*/"::1"}), - // Prints "SocketTests/SocketTest.DecodeHostAndPort/ipv4" etc. in test logs. - [](const testing::TestParamInfo &info) { - return info.param.is_ipv6 ? "ipv6" : "ipv4"; - }); diff --git a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp b/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp deleted file mode 100644 index 3b52a66a09e..00000000000 --- a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp +++ /dev/null @@ -1,128 +0,0 @@ -//===-- SocketTestUtilities.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 "SocketTestUtilities.h" -#include "lldb/Host/Config.h" -#include "lldb/Utility/StreamString.h" - -#ifdef _WIN32 -#include -#include -#else -#include -#endif - -using namespace lldb_private; - -static void AcceptThread(Socket *listen_socket, bool child_processes_inherit, - Socket **accept_socket, Status *error) { - *error = listen_socket->Accept(*accept_socket); -} - -template -void lldb_private::CreateConnectedSockets( - llvm::StringRef listen_remote_address, - const std::function &get_connect_addr, - std::unique_ptr *a_up, std::unique_ptr *b_up) { - bool child_processes_inherit = false; - Status error; - std::unique_ptr listen_socket_up( - new SocketType(true, child_processes_inherit)); - ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); - error = listen_socket_up->Listen(listen_remote_address, 5); - ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); - ASSERT_TRUE(listen_socket_up->IsValid()); - - Status accept_error; - Socket *accept_socket; - std::thread accept_thread(AcceptThread, listen_socket_up.get(), - child_processes_inherit, &accept_socket, - &accept_error); - - std::string connect_remote_address = get_connect_addr(*listen_socket_up); - std::unique_ptr connect_socket_up( - new SocketType(true, child_processes_inherit)); - ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); - error = connect_socket_up->Connect(connect_remote_address); - ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); - ASSERT_TRUE(connect_socket_up->IsValid()); - - a_up->swap(connect_socket_up); - ASSERT_TRUE((*a_up)->IsValid()); - - accept_thread.join(); - b_up->reset(static_cast(accept_socket)); - ASSERT_THAT_ERROR(accept_error.ToError(), llvm::Succeeded()); - ASSERT_NE(nullptr, b_up->get()); - ASSERT_TRUE((*b_up)->IsValid()); - - listen_socket_up.reset(); -} - -bool lldb_private::CreateTCPConnectedSockets( - std::string listen_remote_ip, std::unique_ptr *socket_a_up, - std::unique_ptr *socket_b_up) { - StreamString strm; - strm.Printf("[%s]:0", listen_remote_ip.c_str()); - CreateConnectedSockets( - strm.GetString(), - [=](const TCPSocket &s) { - char connect_remote_address[64]; - snprintf(connect_remote_address, sizeof(connect_remote_address), - "[%s]:%u", listen_remote_ip.c_str(), s.GetLocalPortNumber()); - return std::string(connect_remote_address); - }, - socket_a_up, socket_b_up); - return true; -} - -#if LLDB_ENABLE_POSIX -void lldb_private::CreateDomainConnectedSockets( - llvm::StringRef path, std::unique_ptr *socket_a_up, - std::unique_ptr *socket_b_up) { - return CreateConnectedSockets( - path, [=](const DomainSocket &) { return path.str(); }, socket_a_up, - socket_b_up); -} -#endif - -static bool CheckIPSupport(llvm::StringRef Proto, llvm::StringRef Addr) { - llvm::Expected> Sock = Socket::TcpListen( - Addr, /*child_processes_inherit=*/false, /*predicate=*/nullptr); - if (Sock) - return true; - llvm::Error Err = Sock.takeError(); - GTEST_LOG_(WARNING) << llvm::formatv( - "Creating a canary {0} TCP socket failed: {1}.", - Proto, Err) - .str(); - bool HasProtocolError = false; - handleAllErrors(std::move(Err), [&](std::unique_ptr ECErr) { - std::error_code ec = ECErr->convertToErrorCode(); - if (ec == std::make_error_code(std::errc::address_family_not_supported) || - ec == std::make_error_code(std::errc::address_not_available)) - HasProtocolError = true; - }); - if (HasProtocolError) { - GTEST_LOG_(WARNING) - << llvm::formatv( - "Assuming the host does not support {0}. Skipping test.", Proto) - .str(); - return false; - } - GTEST_LOG_(WARNING) << "Continuing anyway. The test will probably fail."; - return true; -} - -bool lldb_private::HostSupportsIPv4() { - return CheckIPSupport("IPv4", "127.0.0.1:0"); -} - -bool lldb_private::HostSupportsIPv6() { - return CheckIPSupport("IPv6", "[::1]:0"); -} diff --git a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h b/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h deleted file mode 100644 index 943d98a96be..00000000000 --- a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h +++ /dev/null @@ -1,47 +0,0 @@ -//===--------------------- SocketTestUtilities.h ----------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_HOST_SOCKETTESTUTILITIES_H -#define LLDB_UNITTESTS_HOST_SOCKETTESTUTILITIES_H - -#include -#include -#include - -#include "lldb/Host/Config.h" -#include "lldb/Host/Socket.h" -#include "lldb/Host/common/TCPSocket.h" -#include "lldb/Host/common/UDPSocket.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Testing/Support/Error.h" - -#if LLDB_ENABLE_POSIX -#include "lldb/Host/posix/DomainSocket.h" -#endif - -namespace lldb_private { -template -void CreateConnectedSockets( - llvm::StringRef listen_remote_address, - const std::function &get_connect_addr, - std::unique_ptr *a_up, std::unique_ptr *b_up); -bool CreateTCPConnectedSockets(std::string listen_remote_ip, - std::unique_ptr *a_up, - std::unique_ptr *b_up); -#if LLDB_ENABLE_POSIX -void CreateDomainConnectedSockets(llvm::StringRef path, - std::unique_ptr *a_up, - std::unique_ptr *b_up); -#endif - -bool HostSupportsIPv6(); -bool HostSupportsIPv4(); -} // namespace lldb_private - -#endif diff --git a/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp b/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp deleted file mode 100644 index 699ccba0a98..00000000000 --- a/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===-- HostTest.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 "lldb/Host/Host.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Process.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -class HostTest : public testing::Test { -public: - static void SetUpTestCase() { - FileSystem::Initialize(); - HostInfo::Initialize(); - } - static void TearDownTestCase() { - HostInfo::Terminate(); - FileSystem::Terminate(); - } -}; -} // namespace - -TEST_F(HostTest, GetProcessInfo) { - ProcessInstanceInfo Info; - ASSERT_FALSE(Host::GetProcessInfo(0, Info)); - - ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); - - ASSERT_TRUE(Info.ProcessIDIsValid()); - EXPECT_EQ(lldb::pid_t(getpid()), Info.GetProcessID()); - - ASSERT_TRUE(Info.ParentProcessIDIsValid()); - EXPECT_EQ(lldb::pid_t(getppid()), Info.GetParentProcessID()); - - ASSERT_TRUE(Info.EffectiveUserIDIsValid()); - EXPECT_EQ(geteuid(), Info.GetEffectiveUserID()); - - ASSERT_TRUE(Info.EffectiveGroupIDIsValid()); - EXPECT_EQ(getegid(), Info.GetEffectiveGroupID()); - - ASSERT_TRUE(Info.UserIDIsValid()); - EXPECT_EQ(geteuid(), Info.GetUserID()); - - ASSERT_TRUE(Info.GroupIDIsValid()); - EXPECT_EQ(getegid(), Info.GetGroupID()); - - EXPECT_TRUE(Info.GetArchitecture().IsValid()); - EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), - Info.GetArchitecture()); -} diff --git a/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp b/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp deleted file mode 100644 index 680893c03d0..00000000000 --- a/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp +++ /dev/null @@ -1,25 +0,0 @@ -//===-- SupportTest.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 "lldb/Host/linux/Support.h" -#include "llvm/Support/Threading.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(Support, getProcFile_Pid) { - auto BufferOrError = getProcFile(getpid(), "maps"); - ASSERT_TRUE(BufferOrError); - ASSERT_TRUE(*BufferOrError); -} - -TEST(Support, getProcFile_Tid) { - auto BufferOrError = getProcFile(getpid(), llvm::get_threadid(), "comm"); - ASSERT_TRUE(BufferOrError); - ASSERT_TRUE(*BufferOrError); -} diff --git a/gnu/llvm/lldb/unittests/Instruction/CMakeLists.txt b/gnu/llvm/lldb/unittests/Instruction/CMakeLists.txt deleted file mode 100644 index 63d82983102..00000000000 --- a/gnu/llvm/lldb/unittests/Instruction/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -if("ARM" IN_LIST LLVM_TARGETS_TO_BUILD) - add_lldb_unittest(EmulatorTests - TestAArch64Emulator.cpp - LINK_LIBS - lldbCore - lldbSymbol - lldbTarget - lldbPluginInstructionARM64 - LINK_COMPONENTS - Support - ${LLVM_TARGETS_TO_BUILD}) -endif() diff --git a/gnu/llvm/lldb/unittests/Instruction/TestAArch64Emulator.cpp b/gnu/llvm/lldb/unittests/Instruction/TestAArch64Emulator.cpp deleted file mode 100644 index 4506c200dee..00000000000 --- a/gnu/llvm/lldb/unittests/Instruction/TestAArch64Emulator.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//===-- TestAArch64Emulator.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 "gtest/gtest.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/Disassembler.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Utility/ArchSpec.h" - -#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" - -using namespace lldb; -using namespace lldb_private; - -struct Arch64EmulatorTester : public EmulateInstructionARM64 { - Arch64EmulatorTester() - : EmulateInstructionARM64(ArchSpec("arm64-apple-ios")) {} - - static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in, - EmulateInstructionARM64::ProcState &proc_state) { - return EmulateInstructionARM64::AddWithCarry(N, x, y, carry_in, proc_state); - } -}; - -class TestAArch64Emulator : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: -}; - -void TestAArch64Emulator::SetUpTestCase() { - EmulateInstructionARM64::Initialize(); -} - -void TestAArch64Emulator::TearDownTestCase() { - EmulateInstructionARM64::Terminate(); -} - -TEST_F(TestAArch64Emulator, TestOverflow) { - EmulateInstructionARM64::ProcState pstate; - memset(&pstate, 0, sizeof(pstate)); - uint64_t ll_max = std::numeric_limits::max(); - Arch64EmulatorTester emu; - ASSERT_EQ(emu.AddWithCarry(64, ll_max, 0, 0, pstate), ll_max); - ASSERT_EQ(pstate.V, 0ULL); - ASSERT_EQ(pstate.C, 0ULL); - ASSERT_EQ(emu.AddWithCarry(64, ll_max, 1, 0, pstate), (uint64_t)(ll_max + 1)); - ASSERT_EQ(pstate.V, 1ULL); - ASSERT_EQ(pstate.C, 0ULL); - ASSERT_EQ(emu.AddWithCarry(64, ll_max, 0, 1, pstate), (uint64_t)(ll_max + 1)); - ASSERT_EQ(pstate.V, 1ULL); - ASSERT_EQ(pstate.C, 0ULL); -} diff --git a/gnu/llvm/lldb/unittests/Interpreter/CMakeLists.txt b/gnu/llvm/lldb/unittests/Interpreter/CMakeLists.txt deleted file mode 100644 index 6ea5996e2b0..00000000000 --- a/gnu/llvm/lldb/unittests/Interpreter/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_lldb_unittest(InterpreterTests - TestCompletion.cpp - TestOptionArgParser.cpp - TestOptionValue.cpp - TestOptionValueFileColonLine.cpp - - LINK_LIBS - lldbInterpreter - lldbUtilityHelpers - ) diff --git a/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp b/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp deleted file mode 100644 index 361b31e1068..00000000000 --- a/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp +++ /dev/null @@ -1,272 +0,0 @@ -//===-- TestCompletion.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 "lldb/Host/FileSystem.h" -#include "lldb/Interpreter/CommandCompletions.h" -#include "lldb/Utility/StringList.h" -#include "lldb/Utility/TildeExpressionResolver.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "TestingSupport/MockTildeExpressionResolver.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" - -namespace fs = llvm::sys::fs; -namespace path = llvm::sys::path; -using namespace llvm; -using namespace lldb_private; - -namespace { - -class CompletionTest : public testing::Test { - SubsystemRAII subsystems; - -protected: - /// Unique temporary directory in which all created filesystem entities must - /// be placed. It is removed at the end of the test suite. - SmallString<128> BaseDir; - - /// The working directory that we got when starting the test. Every test - /// should chdir into this directory first because some tests maybe chdir - /// into another one during their run. - static SmallString<128> OriginalWorkingDir; - - SmallString<128> DirFoo; - SmallString<128> DirFooA; - SmallString<128> DirFooB; - SmallString<128> DirFooC; - SmallString<128> DirBar; - SmallString<128> DirBaz; - SmallString<128> DirTestFolder; - SmallString<128> DirNested; - - SmallString<128> FileAA; - SmallString<128> FileAB; - SmallString<128> FileAC; - SmallString<128> FileFoo; - SmallString<128> FileBar; - SmallString<128> FileBaz; - - void SetUp() override { - // chdir back into the original working dir this test binary started with. - // A previous test may have have changed the working dir. - ASSERT_NO_ERROR(fs::set_current_path(OriginalWorkingDir)); - - // Get the name of the current test. To prevent that by chance two tests - // get the same temporary directory if createUniqueDirectory fails. - auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - ASSERT_TRUE(test_info != nullptr); - std::string name = test_info->name(); - ASSERT_NO_ERROR(fs::createUniqueDirectory("FsCompletion-" + name, BaseDir)); - - const char *DirNames[] = {"foo", "fooa", "foob", "fooc", - "bar", "baz", "test_folder", "foo/nested"}; - const char *FileNames[] = {"aa1234.tmp", "ab1234.tmp", "ac1234.tmp", - "foo1234.tmp", "bar1234.tmp", "baz1234.tmp"}; - SmallString<128> *Dirs[] = {&DirFoo, &DirFooA, &DirFooB, &DirFooC, - &DirBar, &DirBaz, &DirTestFolder, &DirNested}; - for (auto Dir : llvm::zip(DirNames, Dirs)) { - auto &Path = *std::get<1>(Dir); - Path = BaseDir; - path::append(Path, std::get<0>(Dir)); - ASSERT_NO_ERROR(fs::create_directories(Path)); - } - - SmallString<128> *Files[] = {&FileAA, &FileAB, &FileAC, - &FileFoo, &FileBar, &FileBaz}; - for (auto File : llvm::zip(FileNames, Files)) { - auto &Path = *std::get<1>(File); - Path = BaseDir; - path::append(Path, std::get<0>(File)); - int FD; - ASSERT_NO_ERROR(fs::createUniqueFile(Path, FD, Path)); - ::close(FD); - } - } - - static void SetUpTestCase() { - ASSERT_NO_ERROR(fs::current_path(OriginalWorkingDir)); - } - - void TearDown() override { - ASSERT_NO_ERROR(fs::remove_directories(BaseDir)); - } - - static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) { - for (size_t I = 0; I < Paths.GetSize(); ++I) { - if (fs::equivalent(Path, Paths[I])) - return true; - } - return false; - } - - void DoDirCompletions(const Twine &Prefix, - StandardTildeExpressionResolver &Resolver, - StringList &Results) { - // When a partial name matches, it returns all matches. If it matches both - // a full name AND some partial names, it returns all of them. - CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver); - ASSERT_EQ(4u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirFoo, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooA, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooB, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooC, Results)); - - // If it matches only partial names, it still works as expected. - CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results, Resolver); - ASSERT_EQ(2u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirBar, Results)); - EXPECT_TRUE(HasEquivalentFile(DirBaz, Results)); - } -}; - -SmallString<128> CompletionTest::OriginalWorkingDir; -} // namespace - -static std::vector toVector(const StringList &SL) { - std::vector Result; - for (size_t Idx = 0; Idx < SL.GetSize(); ++Idx) - Result.push_back(SL[Idx]); - return Result; -} -using testing::UnorderedElementsAre; - -TEST_F(CompletionTest, DirCompletionAbsolute) { - // All calls to DiskDirectories() return only directories, even when - // there are files which also match. The tests below all check this - // by asserting an exact result count, and verifying against known - // folders. - - std::string Prefixes[] = {(Twine(BaseDir) + "/").str(), ""}; - - StandardTildeExpressionResolver Resolver; - StringList Results; - - // When a directory is specified that doesn't end in a slash, it searches - // for that directory, not items under it. - // Sanity check that the path we complete on exists and isn't too long. - CommandCompletions::DiskDirectories(Twine(BaseDir) + "/fooa", Results, - Resolver); - ASSERT_EQ(1u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirFooA, Results)); - - CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results, Resolver); - ASSERT_EQ(0u, Results.GetSize()); - - // When the same directory ends with a slash, it finds all children. - CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver); - ASSERT_EQ(7u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirFoo, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooA, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooB, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooC, Results)); - EXPECT_TRUE(HasEquivalentFile(DirBar, Results)); - EXPECT_TRUE(HasEquivalentFile(DirBaz, Results)); - EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results)); - - DoDirCompletions(Twine(BaseDir) + "/", Resolver, Results); - llvm::sys::fs::set_current_path(BaseDir); - DoDirCompletions("", Resolver, Results); -} - -TEST_F(CompletionTest, FileCompletionAbsolute) { - // All calls to DiskFiles() return both files and directories The tests below - // all check this by asserting an exact result count, and verifying against - // known folders. - - StandardTildeExpressionResolver Resolver; - StringList Results; - // When an item is specified that doesn't end in a slash but exactly matches - // one item, it returns that item. - CommandCompletions::DiskFiles(Twine(BaseDir) + "/fooa", Results, Resolver); - ASSERT_EQ(1u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirFooA, Results)); - - // The previous check verified a directory match. But it should work for - // files too. - CommandCompletions::DiskFiles(Twine(BaseDir) + "/aa", Results, Resolver); - ASSERT_EQ(1u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(FileAA, Results)); - - // When it ends with a slash, it should find all files and directories. - CommandCompletions::DiskFiles(Twine(BaseDir) + "/", Results, Resolver); - ASSERT_EQ(13u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirFoo, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooA, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooB, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooC, Results)); - EXPECT_TRUE(HasEquivalentFile(DirBar, Results)); - EXPECT_TRUE(HasEquivalentFile(DirBaz, Results)); - EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results)); - - EXPECT_TRUE(HasEquivalentFile(FileAA, Results)); - EXPECT_TRUE(HasEquivalentFile(FileAB, Results)); - EXPECT_TRUE(HasEquivalentFile(FileAC, Results)); - EXPECT_TRUE(HasEquivalentFile(FileFoo, Results)); - EXPECT_TRUE(HasEquivalentFile(FileBar, Results)); - EXPECT_TRUE(HasEquivalentFile(FileBaz, Results)); - - // When a partial name matches, it returns all file & directory matches. - CommandCompletions::DiskFiles(Twine(BaseDir) + "/foo", Results, Resolver); - ASSERT_EQ(5u, Results.GetSize()); - EXPECT_TRUE(HasEquivalentFile(DirFoo, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooA, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooB, Results)); - EXPECT_TRUE(HasEquivalentFile(DirFooC, Results)); - EXPECT_TRUE(HasEquivalentFile(FileFoo, Results)); -} - -TEST_F(CompletionTest, DirCompletionUsername) { - MockTildeExpressionResolver Resolver("James", BaseDir); - Resolver.AddKnownUser("Kirk", DirFooB); - Resolver.AddKnownUser("Lars", DirFooC); - Resolver.AddKnownUser("Jason", DirFoo); - Resolver.AddKnownUser("Larry", DirFooA); - std::string sep = std::string(path::get_separator()); - - // Just resolving current user's home directory by itself should return the - // directory. - StringList Results; - CommandCompletions::DiskDirectories("~", Results, Resolver); - EXPECT_THAT(toVector(Results), UnorderedElementsAre("~" + sep)); - - // With a slash appended, it should return all items in the directory. - CommandCompletions::DiskDirectories("~/", Results, Resolver); - EXPECT_THAT(toVector(Results), - UnorderedElementsAre( - "~/foo" + sep, "~/fooa" + sep, "~/foob" + sep, "~/fooc" + sep, - "~/bar" + sep, "~/baz" + sep, "~/test_folder" + sep)); - - // Check that we can complete directories in nested paths - CommandCompletions::DiskDirectories("~/foo/", Results, Resolver); - EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep)); - - CommandCompletions::DiskDirectories("~/foo/nes", Results, Resolver); - EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep)); - - // With ~username syntax it should return one match if there is an exact - // match. It shouldn't translate to the actual directory, it should keep the - // form the user typed. - CommandCompletions::DiskDirectories("~Lars", Results, Resolver); - EXPECT_THAT(toVector(Results), UnorderedElementsAre("~Lars" + sep)); - - // But with a username that is not found, no results are returned. - CommandCompletions::DiskDirectories("~Dave", Results, Resolver); - EXPECT_THAT(toVector(Results), UnorderedElementsAre()); - - // And if there are multiple matches, it should return all of them. - CommandCompletions::DiskDirectories("~La", Results, Resolver); - EXPECT_THAT(toVector(Results), - UnorderedElementsAre("~Lars" + sep, "~Larry" + sep)); -} diff --git a/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp b/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp deleted file mode 100644 index e173febcfa8..00000000000 --- a/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//===-- ArgsTest.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 "gtest/gtest.h" -#include "lldb/Interpreter/OptionArgParser.h" - -using namespace lldb_private; - -TEST(OptionArgParserTest, toBoolean) { - bool success = false; - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("true"), false, nullptr)); - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("on"), false, nullptr)); - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("yes"), false, nullptr)); - EXPECT_TRUE(OptionArgParser::ToBoolean(llvm::StringRef("1"), false, nullptr)); - - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("true"), false, &success)); - EXPECT_TRUE(success); - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("on"), false, &success)); - EXPECT_TRUE(success); - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("yes"), false, &success)); - EXPECT_TRUE(success); - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("1"), false, &success)); - EXPECT_TRUE(success); - - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("false"), true, nullptr)); - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("off"), true, nullptr)); - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("no"), true, nullptr)); - EXPECT_FALSE(OptionArgParser::ToBoolean(llvm::StringRef("0"), true, nullptr)); - - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("false"), true, &success)); - EXPECT_TRUE(success); - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("off"), true, &success)); - EXPECT_TRUE(success); - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("no"), true, &success)); - EXPECT_TRUE(success); - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("0"), true, &success)); - EXPECT_TRUE(success); - - EXPECT_FALSE( - OptionArgParser::ToBoolean(llvm::StringRef("10"), false, &success)); - EXPECT_FALSE(success); - EXPECT_TRUE( - OptionArgParser::ToBoolean(llvm::StringRef("10"), true, &success)); - EXPECT_FALSE(success); - EXPECT_TRUE(OptionArgParser::ToBoolean(llvm::StringRef(""), true, &success)); - EXPECT_FALSE(success); -} - -TEST(OptionArgParserTest, toChar) { - bool success = false; - - EXPECT_EQ('A', OptionArgParser::ToChar("A", 'B', nullptr)); - EXPECT_EQ('B', OptionArgParser::ToChar("B", 'A', nullptr)); - - EXPECT_EQ('A', OptionArgParser::ToChar("A", 'B', &success)); - EXPECT_TRUE(success); - EXPECT_EQ('B', OptionArgParser::ToChar("B", 'A', &success)); - EXPECT_TRUE(success); - - EXPECT_EQ('A', OptionArgParser::ToChar("", 'A', &success)); - EXPECT_FALSE(success); - EXPECT_EQ('A', OptionArgParser::ToChar("ABC", 'A', &success)); - EXPECT_FALSE(success); -} - -TEST(OptionArgParserTest, toScriptLanguage) { - bool success = false; - - EXPECT_EQ(lldb::eScriptLanguageDefault, - OptionArgParser::ToScriptLanguage(llvm::StringRef("default"), - lldb::eScriptLanguageNone, - nullptr)); - EXPECT_EQ(lldb::eScriptLanguagePython, - OptionArgParser::ToScriptLanguage( - llvm::StringRef("python"), lldb::eScriptLanguageNone, nullptr)); - EXPECT_EQ(lldb::eScriptLanguageNone, - OptionArgParser::ToScriptLanguage( - llvm::StringRef("none"), lldb::eScriptLanguagePython, nullptr)); - - EXPECT_EQ(lldb::eScriptLanguageDefault, - OptionArgParser::ToScriptLanguage(llvm::StringRef("default"), - lldb::eScriptLanguageNone, - &success)); - EXPECT_TRUE(success); - EXPECT_EQ(lldb::eScriptLanguagePython, - OptionArgParser::ToScriptLanguage(llvm::StringRef("python"), - lldb::eScriptLanguageNone, - &success)); - EXPECT_TRUE(success); - EXPECT_EQ(lldb::eScriptLanguageNone, - OptionArgParser::ToScriptLanguage(llvm::StringRef("none"), - lldb::eScriptLanguagePython, - &success)); - EXPECT_TRUE(success); - - EXPECT_EQ(lldb::eScriptLanguagePython, - OptionArgParser::ToScriptLanguage(llvm::StringRef("invalid"), - lldb::eScriptLanguagePython, - &success)); - EXPECT_FALSE(success); -} diff --git a/gnu/llvm/lldb/unittests/Interpreter/TestOptionValue.cpp b/gnu/llvm/lldb/unittests/Interpreter/TestOptionValue.cpp deleted file mode 100644 index 7f383424368..00000000000 --- a/gnu/llvm/lldb/unittests/Interpreter/TestOptionValue.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//===-- TestOptionValue.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 "lldb/Interpreter/OptionValues.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -class Callback { -public: - virtual void Invoke() const {} - void operator()() const { Invoke(); } -protected: - ~Callback() = default; -}; - -class MockCallback final : public Callback { -public: - MOCK_CONST_METHOD0(Invoke, void()); -}; - -// Test a single-value class. -TEST(OptionValueString, DeepCopy) { - OptionValueString str; - str.SetValueFromString("ab"); - - MockCallback callback; - str.SetValueChangedCallback([&callback] { callback(); }); - EXPECT_CALL(callback, Invoke()); - - auto copy_sp = str.DeepCopy(nullptr); - - // Test that the base class data members are copied/set correctly. - ASSERT_TRUE(copy_sp); - ASSERT_EQ(copy_sp->GetParent().get(), nullptr); - ASSERT_TRUE(copy_sp->OptionWasSet()); - ASSERT_EQ(copy_sp->GetStringValue(), "ab"); - - // Trigger the callback. - copy_sp->SetValueFromString("c", eVarSetOperationAppend); - ASSERT_EQ(copy_sp->GetStringValue(), "abc"); -} - -// Test an aggregate class. -TEST(OptionValueArgs, DeepCopy) { - OptionValueArgs args; - args.SetValueFromString("A B"); - - MockCallback callback; - args.SetValueChangedCallback([&callback] { callback(); }); - EXPECT_CALL(callback, Invoke()); - - auto copy_sp = args.DeepCopy(nullptr); - - // Test that the base class data members are copied/set correctly. - ASSERT_TRUE(copy_sp); - ASSERT_EQ(copy_sp->GetParent(), nullptr); - ASSERT_TRUE(copy_sp->OptionWasSet()); - - auto *args_copy_ptr = copy_sp->GetAsArgs(); - ASSERT_EQ(args_copy_ptr->GetSize(), 2U); - ASSERT_EQ((*args_copy_ptr)[0]->GetParent(), copy_sp); - ASSERT_EQ((*args_copy_ptr)[0]->GetStringValue(), "A"); - ASSERT_EQ((*args_copy_ptr)[1]->GetParent(), copy_sp); - ASSERT_EQ((*args_copy_ptr)[1]->GetStringValue(), "B"); - - // Trigger the callback. - copy_sp->SetValueFromString("C", eVarSetOperationAppend); - ASSERT_TRUE(args_copy_ptr); - ASSERT_EQ(args_copy_ptr->GetSize(), 3U); - ASSERT_EQ((*args_copy_ptr)[2]->GetStringValue(), "C"); -} - -class TestProperties : public OptionValueProperties { -public: - static std::shared_ptr CreateGlobal() { - auto props_sp = std::make_shared(); - const bool is_global = false; - - auto dict_sp = std::make_shared(1 << eTypeUInt64); - props_sp->AppendProperty(ConstString("dict"), ConstString(), is_global, - dict_sp); - - auto file_list_sp = std::make_shared(); - props_sp->AppendProperty(ConstString("file-list"), ConstString(), is_global, - file_list_sp); - return props_sp; - } - - void SetDictionaryChangedCallback(const MockCallback &callback) { - SetValueChangedCallback(m_dict_index, [&callback] { callback(); }); - } - - void SetFileListChangedCallback(const MockCallback &callback) { - SetValueChangedCallback(m_file_list_index, [&callback] { callback(); }); - } - - OptionValueDictionary *GetDictionary() { - return GetPropertyAtIndexAsOptionValueDictionary(nullptr, m_dict_index); - } - - OptionValueFileSpecList *GetFileList() { - return GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, - m_file_list_index); - } - -private: - lldb::OptionValueSP Clone() const { - return std::make_shared(*this); - } - - uint32_t m_dict_index = 0; - uint32_t m_file_list_index = 1; -}; - -// Test a user-defined propery class. -TEST(TestProperties, DeepCopy) { - auto props_sp = TestProperties::CreateGlobal(); - props_sp->GetDictionary()->SetValueFromString("A=1 B=2"); - props_sp->GetFileList()->SetValueFromString("path/to/file"); - - MockCallback callback; - props_sp->SetDictionaryChangedCallback(callback); - props_sp->SetFileListChangedCallback(callback); - EXPECT_CALL(callback, Invoke()).Times(2); - - auto copy_sp = props_sp->DeepCopy(nullptr); - - // Test that the base class data members are copied/set correctly. - ASSERT_TRUE(copy_sp); - ASSERT_EQ(copy_sp->GetParent(), nullptr); - - // This cast is safe only if the class overrides Clone(). - auto *props_copy_ptr = static_cast(copy_sp.get()); - ASSERT_TRUE(props_copy_ptr); - - // Test the first child. - auto dict_copy_ptr = props_copy_ptr->GetDictionary(); - ASSERT_TRUE(dict_copy_ptr); - ASSERT_EQ(dict_copy_ptr->GetParent(), copy_sp); - ASSERT_TRUE(dict_copy_ptr->OptionWasSet()); - ASSERT_EQ(dict_copy_ptr->GetNumValues(), 2U); - - auto value_ptr = dict_copy_ptr->GetValueForKey(ConstString("A")); - ASSERT_TRUE(value_ptr); - ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr); - ASSERT_EQ(value_ptr->GetUInt64Value(), 1U); - - value_ptr = dict_copy_ptr->GetValueForKey(ConstString("B")); - ASSERT_TRUE(value_ptr); - ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr); - ASSERT_EQ(value_ptr->GetUInt64Value(), 2U); - - // Test the second child. - auto file_list_copy_ptr = props_copy_ptr->GetFileList(); - ASSERT_TRUE(file_list_copy_ptr); - ASSERT_EQ(file_list_copy_ptr->GetParent(), copy_sp); - ASSERT_TRUE(file_list_copy_ptr->OptionWasSet()); - - auto file_list_copy = file_list_copy_ptr->GetCurrentValue(); - ASSERT_EQ(file_list_copy.GetSize(), 1U); - ASSERT_EQ(file_list_copy.GetFileSpecAtIndex(0), FileSpec("path/to/file")); - - // Trigger the callback first time. - dict_copy_ptr->SetValueFromString("C=3", eVarSetOperationAppend); - - // Trigger the callback second time. - file_list_copy_ptr->SetValueFromString("0 another/path", eVarSetOperationReplace); -} diff --git a/gnu/llvm/lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp b/gnu/llvm/lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp deleted file mode 100644 index 079c26bdd8a..00000000000 --- a/gnu/llvm/lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===-- ArgsTest.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 "lldb/Interpreter/OptionValueFileColonLine.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Status.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -void CheckSetting(const char *input, bool success, FileSpec path = {}, - uint32_t line_number = LLDB_INVALID_LINE_NUMBER, - uint32_t column_number = LLDB_INVALID_COLUMN_NUMBER) { - - OptionValueFileColonLine value; - Status error; - llvm::StringRef s_ref(input); - error = value.SetValueFromString(s_ref); - ASSERT_EQ(error.Success(), success); - - // If we were meant to fail, we don't need to do more checks: - if (!success) - return; - - ASSERT_EQ(value.GetLineNumber(), line_number); - ASSERT_EQ(value.GetColumnNumber(), column_number); - ASSERT_EQ(value.GetFileSpec(), path); -} - -TEST(OptionValueFileColonLine, setFromString) { - OptionValueFileColonLine value; - Status error; - - // Make sure a default constructed value is invalid: - ASSERT_EQ(value.GetLineNumber(), - static_cast(LLDB_INVALID_LINE_NUMBER)); - ASSERT_EQ(value.GetColumnNumber(), - static_cast(LLDB_INVALID_COLUMN_NUMBER)); - ASSERT_FALSE(value.GetFileSpec()); - - // Make sure it is an error to pass a specifier with no line number: - CheckSetting("foo.c", false); - - // Now try with just a file & line: - CheckSetting("foo.c:12", true, FileSpec("foo.c"), 12); - CheckSetting("foo.c:12:20", true, FileSpec("foo.c"), 12, 20); - // Make sure a colon doesn't mess us up: - CheckSetting("foo:bar.c:12", true, FileSpec("foo:bar.c"), 12); - CheckSetting("foo:bar.c:12:20", true, FileSpec("foo:bar.c"), 12, 20); - // Try errors in the line number: - CheckSetting("foo.c:12c", false); - CheckSetting("foo.c:12:20c", false); -} diff --git a/gnu/llvm/lldb/unittests/Language/CLanguages/CLanguagesTest.cpp b/gnu/llvm/lldb/unittests/Language/CLanguages/CLanguagesTest.cpp deleted file mode 100644 index c68bd56c337..00000000000 --- a/gnu/llvm/lldb/unittests/Language/CLanguages/CLanguagesTest.cpp +++ /dev/null @@ -1,46 +0,0 @@ -//===-- CLanguagesTest.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 "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/lldb-enumerations.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -/// Returns the name of the LLDB plugin for the given language or a null -/// ConstString if there is no fitting plugin. -static ConstString GetPluginName(lldb::LanguageType language) { - Language *language_plugin = Language::FindPlugin(language); - if (language_plugin) - return language_plugin->GetPluginName(); - return ConstString(); -} - -TEST(CLanguages, LookupCLanguagesByLanguageType) { - SubsystemRAII langs; - - // There is no plugin to find for C. - EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC), nullptr); - EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC89), nullptr); - EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC99), nullptr); - EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC11), nullptr); - - EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus), "cplusplus"); - EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus_03), "cplusplus"); - EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus_11), "cplusplus"); - EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus_14), "cplusplus"); - - EXPECT_EQ(GetPluginName(lldb::eLanguageTypeObjC), "objc"); - - EXPECT_EQ(GetPluginName(lldb::eLanguageTypeObjC_plus_plus), "objcplusplus"); -} diff --git a/gnu/llvm/lldb/unittests/Language/CLanguages/CMakeLists.txt b/gnu/llvm/lldb/unittests/Language/CLanguages/CMakeLists.txt deleted file mode 100644 index 136140487da..00000000000 --- a/gnu/llvm/lldb/unittests/Language/CLanguages/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_lldb_unittest(LanguageCLanguagesTests - CLanguagesTest.cpp - - LINK_LIBS - lldbPluginCPlusPlusLanguage - lldbPluginObjCLanguage - lldbPluginObjCPlusPlusLanguage -) diff --git a/gnu/llvm/lldb/unittests/Language/CMakeLists.txt b/gnu/llvm/lldb/unittests/Language/CMakeLists.txt deleted file mode 100644 index 3cca831956a..00000000000 --- a/gnu/llvm/lldb/unittests/Language/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_subdirectory(CPlusPlus) -add_subdirectory(CLanguages) -add_subdirectory(Highlighting) diff --git a/gnu/llvm/lldb/unittests/Language/CPlusPlus/CMakeLists.txt b/gnu/llvm/lldb/unittests/Language/CPlusPlus/CMakeLists.txt deleted file mode 100644 index 4882eafc8d8..00000000000 --- a/gnu/llvm/lldb/unittests/Language/CPlusPlus/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_lldb_unittest(LanguageCPlusPlusTests - CPlusPlusLanguageTest.cpp - - LINK_LIBS - lldbPluginCPlusPlusLanguage - ) diff --git a/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp b/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp deleted file mode 100644 index e8e6a4c0da0..00000000000 --- a/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ /dev/null @@ -1,216 +0,0 @@ -//===-- CPlusPlusLanguageTest.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 "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusNameParser.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(CPlusPlusLanguage, MethodNameParsing) { - struct TestCase { - std::string input; - std::string context, basename, arguments, qualifiers, scope_qualified_name; - }; - - TestCase test_cases[] = { - {"main(int, char *[]) ", "", "main", "(int, char *[])", "", "main"}, - {"foo::bar(baz) const", "foo", "bar", "(baz)", "const", "foo::bar"}, - {"foo::~bar(baz)", "foo", "~bar", "(baz)", "", "foo::~bar"}, - {"a::b::c::d(e,f)", "a::b::c", "d", "(e,f)", "", "a::b::c::d"}, - {"void f(int)", "", "f", "(int)", "", "f"}, - - // Operators - {"std::basic_ostream >& " - "std::operator<< >" - "(std::basic_ostream >&, char const*)", - "std", "operator<< >", - "(std::basic_ostream >&, char const*)", "", - "std::operator<< >"}, - {"operator delete[](void*, clang::ASTContext const&, unsigned long)", "", - "operator delete[]", "(void*, clang::ASTContext const&, unsigned long)", - "", "operator delete[]"}, - {"llvm::Optional::operator bool() const", - "llvm::Optional", "operator bool", "()", "const", - "llvm::Optional::operator bool"}, - {"(anonymous namespace)::FactManager::operator[](unsigned short)", - "(anonymous namespace)::FactManager", "operator[]", "(unsigned short)", - "", "(anonymous namespace)::FactManager::operator[]"}, - {"const int& std::map>::operator[](short) const", - "std::map>", "operator[]", "(short)", "const", - "std::map>::operator[]"}, - {"CompareInsn::operator()(llvm::StringRef, InsnMatchEntry const&)", - "CompareInsn", "operator()", "(llvm::StringRef, InsnMatchEntry const&)", - "", "CompareInsn::operator()"}, - {"llvm::Optional::operator*() const &", - "llvm::Optional", "operator*", "()", "const &", - "llvm::Optional::operator*"}, - // Internal classes - {"operator<<(Cls, Cls)::Subclass::function()", - "operator<<(Cls, Cls)::Subclass", "function", "()", "", - "operator<<(Cls, Cls)::Subclass::function"}, - {"SAEC::checkFunction(context&) const::CallBack::CallBack(int)", - "SAEC::checkFunction(context&) const::CallBack", "CallBack", "(int)", "", - "SAEC::checkFunction(context&) const::CallBack::CallBack"}, - // Anonymous namespace - {"XX::(anonymous namespace)::anon_class::anon_func() const", - "XX::(anonymous namespace)::anon_class", "anon_func", "()", "const", - "XX::(anonymous namespace)::anon_class::anon_func"}, - - // Lambda - {"main::{lambda()#1}::operator()() const::{lambda()#1}::operator()() const", - "main::{lambda()#1}::operator()() const::{lambda()#1}", "operator()", "()", "const", - "main::{lambda()#1}::operator()() const::{lambda()#1}::operator()"}, - - // Function pointers - {"string (*f(vector&&))(float)", "", "f", "(vector&&)", "", - "f"}, - {"void (*&std::_Any_data::_M_access())()", "std::_Any_data", - "_M_access", "()", "", - "std::_Any_data::_M_access"}, - {"void (*(*(*(*(*(*(*(* const&func1(int))())())())())())())())()", "", - "func1", "(int)", "", "func1"}, - - // Decltype - {"decltype(nullptr)&& std::forward" - "(std::remove_reference::type&)", - "std", "forward", - "(std::remove_reference::type&)", "", - "std::forward"}, - - // Templates - {"void llvm::PM>::" - "addPass(llvm::VP)", - "llvm::PM>", "addPass", - "(llvm::VP)", "", - "llvm::PM>::" - "addPass"}, - {"void std::vector >" - "::_M_emplace_back_aux(Class const&)", - "std::vector >", - "_M_emplace_back_aux", "(Class const&)", "", - "std::vector >::" - "_M_emplace_back_aux"}, - {"unsigned long llvm::countTrailingOnes" - "(unsigned int, llvm::ZeroBehavior)", - "llvm", "countTrailingOnes", - "(unsigned int, llvm::ZeroBehavior)", "", - "llvm::countTrailingOnes"}, - {"std::enable_if<(10u)<(64), bool>::type llvm::isUInt<10u>(unsigned " - "long)", - "llvm", "isUInt<10u>", "(unsigned long)", "", "llvm::isUInt<10u>"}, - {"f, sizeof(B)()", "", - "f, sizeof(B)", "()", "", - "f, sizeof(B)"}}; - - for (const auto &test : test_cases) { - CPlusPlusLanguage::MethodName method(ConstString(test.input)); - EXPECT_TRUE(method.IsValid()) << test.input; - if (method.IsValid()) { - EXPECT_EQ(test.context, method.GetContext().str()); - EXPECT_EQ(test.basename, method.GetBasename().str()); - EXPECT_EQ(test.arguments, method.GetArguments().str()); - EXPECT_EQ(test.qualifiers, method.GetQualifiers().str()); - EXPECT_EQ(test.scope_qualified_name, method.GetScopeQualifiedName()); - } - } -} - -TEST(CPlusPlusLanguage, ExtractContextAndIdentifier) { - struct TestCase { - std::string input; - std::string context, basename; - }; - - TestCase test_cases[] = { - {"main", "", "main"}, - {"main ", "", "main"}, - {"foo01::bar", "foo01", "bar"}, - {"foo::~bar", "foo", "~bar"}, - {"std::vector::push_back", "std::vector", "push_back"}, - {"operator<<(Cls, Cls)::Subclass::function", - "operator<<(Cls, Cls)::Subclass", "function"}, - {"std::vector>" - "::_M_emplace_back_aux", - "std::vector>", - "_M_emplace_back_aux"}, - {"`anonymous namespace'::foo", "`anonymous namespace'", "foo"}, - {"`operator<'::`2'::B<0>::operator>", "`operator<'::`2'::B<0>", - "operator>"}, - {"`anonymous namespace'::S::<<::__l2::Foo", - "`anonymous namespace'::S::<<::__l2", "Foo"}, - // These cases are idiosyncratic in how clang generates debug info for - // names when we have template parameters. They are not valid C++ names - // but if we fix this we need to support them for older compilers. - {"A::operator>", "A", "operator>"}, - {"operator>", "", "operator>"}, - {"A::operator<", "A", "operator<"}, - {"operator<", "", "operator<"}, - {"A::operator<<", "A", "operator<<"}, - {"operator<<", "", "operator<<"}, - }; - - llvm::StringRef context, basename; - for (const auto &test : test_cases) { - EXPECT_TRUE(CPlusPlusLanguage::ExtractContextAndIdentifier( - test.input.c_str(), context, basename)); - EXPECT_EQ(test.context, context.str()); - EXPECT_EQ(test.basename, basename.str()); - } - - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier("void", context, - basename)); - EXPECT_FALSE( - CPlusPlusLanguage::ExtractContextAndIdentifier("321", context, basename)); - EXPECT_FALSE( - CPlusPlusLanguage::ExtractContextAndIdentifier("", context, basename)); - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( - "selector:", context, basename)); - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( - "selector:otherField:", context, basename)); - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( - "abc::", context, basename)); - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( - "f>", context, basename)); - - // We expect these cases to fail until we turn on C++2a - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( - "A::operator<=>", context, basename)); - EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( - "operator<=>", context, basename)); -} - -static std::set FindAlternate(llvm::StringRef Name) { - std::set Results; - uint32_t Count = CPlusPlusLanguage::FindAlternateFunctionManglings( - ConstString(Name), Results); - EXPECT_EQ(Count, Results.size()); - std::set Strings; - for (ConstString Str : Results) - Strings.insert(std::string(Str.GetStringRef())); - return Strings; -} - -TEST(CPlusPlusLanguage, FindAlternateFunctionManglings) { - using namespace testing; - - EXPECT_THAT(FindAlternate("_ZN1A1fEv"), - UnorderedElementsAre("_ZNK1A1fEv", "_ZLN1A1fEv")); - EXPECT_THAT(FindAlternate("_ZN1A1fEa"), Contains("_ZN1A1fEc")); - EXPECT_THAT(FindAlternate("_ZN1A1fEx"), Contains("_ZN1A1fEl")); - EXPECT_THAT(FindAlternate("_ZN1A1fEy"), Contains("_ZN1A1fEm")); - EXPECT_THAT(FindAlternate("_ZN1A1fEai"), Contains("_ZN1A1fEci")); - EXPECT_THAT(FindAlternate("_ZN1AC1Ev"), Contains("_ZN1AC2Ev")); - EXPECT_THAT(FindAlternate("_ZN1AD1Ev"), Contains("_ZN1AD2Ev")); - EXPECT_THAT(FindAlternate("_bogus"), IsEmpty()); -} - -TEST(CPlusPlusLanguage, CPlusPlusNameParser) { - // Don't crash. - CPlusPlusNameParser((const char *)nullptr); -} diff --git a/gnu/llvm/lldb/unittests/Language/Highlighting/CMakeLists.txt b/gnu/llvm/lldb/unittests/Language/Highlighting/CMakeLists.txt deleted file mode 100644 index 576f8dff10f..00000000000 --- a/gnu/llvm/lldb/unittests/Language/Highlighting/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_lldb_unittest(HighlighterTests - HighlighterTest.cpp - - LINK_LIBS - lldbPluginCPlusPlusLanguage - lldbPluginObjCLanguage - lldbPluginObjCPlusPlusLanguage - ) diff --git a/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp b/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp deleted file mode 100644 index 7a2d7160e94..00000000000 --- a/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp +++ /dev/null @@ -1,318 +0,0 @@ -//===-- HighlighterTest.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 "gtest/gtest.h" - -#include "lldb/Core/Highlighter.h" -#include "lldb/Host/FileSystem.h" - -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" -#include "TestingSupport/SubsystemRAII.h" - -using namespace lldb_private; - -namespace { -class HighlighterTest : public testing::Test { - SubsystemRAII - subsystems; -}; -} // namespace - -static std::string getName(lldb::LanguageType type) { - HighlighterManager m; - return m.getHighlighterFor(type, "").GetName().str(); -} - -static std::string getName(llvm::StringRef path) { - HighlighterManager m; - return m.getHighlighterFor(lldb::eLanguageTypeUnknown, path).GetName().str(); -} - -TEST_F(HighlighterTest, HighlighterSelectionType) { - EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus), "clang"); - EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_03), "clang"); - EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_11), "clang"); - EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_14), "clang"); - EXPECT_EQ(getName(lldb::eLanguageTypeObjC), "clang"); - EXPECT_EQ(getName(lldb::eLanguageTypeObjC_plus_plus), "clang"); - - EXPECT_EQ(getName(lldb::eLanguageTypeUnknown), "none"); - EXPECT_EQ(getName(lldb::eLanguageTypeJulia), "none"); - EXPECT_EQ(getName(lldb::eLanguageTypeHaskell), "none"); -} - -TEST_F(HighlighterTest, HighlighterSelectionPath) { - EXPECT_EQ(getName("myfile.cc"), "clang"); - EXPECT_EQ(getName("moo.cpp"), "clang"); - EXPECT_EQ(getName("mar.cxx"), "clang"); - EXPECT_EQ(getName("foo.C"), "clang"); - EXPECT_EQ(getName("bar.CC"), "clang"); - EXPECT_EQ(getName("a/dir.CC"), "clang"); - EXPECT_EQ(getName("/a/dir.hpp"), "clang"); - EXPECT_EQ(getName("header.h"), "clang"); - EXPECT_EQ(getName("foo.m"), "clang"); - EXPECT_EQ(getName("foo.mm"), "clang"); - - EXPECT_EQ(getName(""), "none"); - EXPECT_EQ(getName("/dev/null"), "none"); - EXPECT_EQ(getName("Factory.java"), "none"); - EXPECT_EQ(getName("poll.py"), "none"); - EXPECT_EQ(getName("reducer.hs"), "none"); -} - -TEST_F(HighlighterTest, FallbackHighlighter) { - HighlighterManager mgr; - const Highlighter &h = - mgr.getHighlighterFor(lldb::eLanguageTypePascal83, "foo.pas"); - - HighlightStyle style; - style.identifier.Set("[", "]"); - style.semicolons.Set("<", ">"); - - const char *code = "program Hello;"; - std::string output = h.Highlight(style, code, llvm::Optional()); - - EXPECT_STREQ(output.c_str(), code); -} - -static std::string -highlightDefault(llvm::StringRef code, HighlightStyle style, - llvm::Optional cursor = llvm::Optional()) { - HighlighterManager mgr; - return mgr.getDefaultHighlighter().Highlight(style, code, cursor); -} - -TEST_F(HighlighterTest, DefaultHighlighter) { - const char *code = "int my_main() { return 22; } \n"; - - HighlightStyle style; - EXPECT_EQ(code, highlightDefault(code, style)); -} - -TEST_F(HighlighterTest, DefaultHighlighterWithCursor) { - HighlightStyle style; - style.selected.Set("", ""); - EXPECT_EQ("a bc", highlightDefault("a bc", style, 0)); - EXPECT_EQ("a bc", highlightDefault("a bc", style, 1)); - EXPECT_EQ("a bc", highlightDefault("a bc", style, 2)); - EXPECT_EQ("a bc", highlightDefault("a bc", style, 3)); -} - -TEST_F(HighlighterTest, DefaultHighlighterWithCursorOutOfBounds) { - HighlightStyle style; - style.selected.Set("", ""); - EXPECT_EQ("a bc", highlightDefault("a bc", style, 4)); -} -// Tests highlighting with the Clang highlighter. - -static std::string -highlightC(llvm::StringRef code, HighlightStyle style, - llvm::Optional cursor = llvm::Optional()) { - HighlighterManager mgr; - const Highlighter &h = mgr.getHighlighterFor(lldb::eLanguageTypeC, "main.c"); - return h.Highlight(style, code, cursor); -} - -TEST_F(HighlighterTest, ClangEmptyInput) { - HighlightStyle s; - EXPECT_EQ("", highlightC("", s)); -} - -TEST_F(HighlighterTest, ClangScalarLiterals) { - HighlightStyle s; - s.scalar_literal.Set("", ""); - - EXPECT_EQ(" int i = 22;", highlightC(" int i = 22;", s)); -} - -TEST_F(HighlighterTest, ClangStringLiterals) { - HighlightStyle s; - s.string_literal.Set("", ""); - - EXPECT_EQ("const char *f = 22 + \"foo\";", - highlightC("const char *f = 22 + \"foo\";", s)); -} - -TEST_F(HighlighterTest, ClangUnterminatedString) { - HighlightStyle s; - s.string_literal.Set("", ""); - - EXPECT_EQ(" f = \"", highlightC(" f = \"", s)); -} - -TEST_F(HighlighterTest, Keywords) { - HighlightStyle s; - s.keyword.Set("", ""); - - EXPECT_EQ(" return 1; ", highlightC(" return 1; ", s)); -} - -TEST_F(HighlighterTest, Colons) { - HighlightStyle s; - s.colon.Set("", ""); - - EXPECT_EQ("foo::bar:", highlightC("foo::bar:", s)); -} - -TEST_F(HighlighterTest, ClangBraces) { - HighlightStyle s; - s.braces.Set("", ""); - - EXPECT_EQ("a{}", highlightC("a{}", s)); -} - -TEST_F(HighlighterTest, ClangSquareBrackets) { - HighlightStyle s; - s.square_brackets.Set("", ""); - - EXPECT_EQ("a[]", highlightC("a[]", s)); -} - -TEST_F(HighlighterTest, ClangCommas) { - HighlightStyle s; - s.comma.Set("", ""); - - EXPECT_EQ(" bool f = foo(), 1;", - highlightC(" bool f = foo(), 1;", s)); -} - -TEST_F(HighlighterTest, ClangPPDirectives) { - HighlightStyle s; - s.pp_directive.Set("", ""); - - EXPECT_EQ("#include \"foo\" //c", - highlightC("#include \"foo\" //c", s)); -} - -TEST_F(HighlighterTest, ClangPreserveNewLine) { - HighlightStyle s; - s.comment.Set("", ""); - - EXPECT_EQ("//\n", highlightC("//\n", s)); -} - -TEST_F(HighlighterTest, ClangTrailingBackslashBeforeNewline) { - HighlightStyle s; - - EXPECT_EQ("\\\n", highlightC("\\\n", s)); - EXPECT_EQ("\\\r\n", highlightC("\\\r\n", s)); - - EXPECT_EQ("#define a \\\n", highlightC("#define a \\\n", s)); - EXPECT_EQ("#define a \\\r\n", highlightC("#define a \\\r\n", s)); - EXPECT_EQ("#define a \\\r", highlightC("#define a \\\r", s)); -} - -TEST_F(HighlighterTest, ClangTrailingBackslashWithWhitespace) { - HighlightStyle s; - - EXPECT_EQ("\\ \n", highlightC("\\ \n", s)); - EXPECT_EQ("\\ \t\n", highlightC("\\ \t\n", s)); - EXPECT_EQ("\\ \n", highlightC("\\ \n", s)); - EXPECT_EQ("\\\t\n", highlightC("\\\t\n", s)); - - EXPECT_EQ("#define a \\ \n", highlightC("#define a \\ \n", s)); - EXPECT_EQ("#define a \\ \t\n", highlightC("#define a \\ \t\n", s)); - EXPECT_EQ("#define a \\ \n", highlightC("#define a \\ \n", s)); - EXPECT_EQ("#define a \\\t\n", highlightC("#define a \\\t\n", s)); -} - -TEST_F(HighlighterTest, ClangTrailingBackslashMissingNewLine) { - HighlightStyle s; - EXPECT_EQ("\\", highlightC("\\", s)); - EXPECT_EQ("#define a\\", highlightC("#define a\\", s)); -} - -TEST_F(HighlighterTest, ClangComments) { - HighlightStyle s; - s.comment.Set("", ""); - - EXPECT_EQ(" /*com */ // com /*n*/", - highlightC(" /*com */ // com /*n*/", s)); -} - -TEST_F(HighlighterTest, ClangOperators) { - HighlightStyle s; - s.operators.Set("[", "]"); - - EXPECT_EQ(" 1[+]2[/]a[*]f[&]x[|][~]l", highlightC(" 1+2/a*f&x|~l", s)); -} - -TEST_F(HighlighterTest, ClangIdentifiers) { - HighlightStyle s; - s.identifier.Set("", ""); - - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s)); -} - -TEST_F(HighlighterTest, ClangCursorPos) { - HighlightStyle s; - s.selected.Set("", ""); - - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 0)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 1)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 2)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 3)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 4)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 5)); -} - -TEST_F(HighlighterTest, ClangCursorPosEndOfLine) { - HighlightStyle s; - s.selected.Set("", ""); - - EXPECT_EQ("f", highlightC("f", s, 1)); -} - -TEST_F(HighlighterTest, ClangCursorOutOfBounds) { - HighlightStyle s; - s.selected.Set("", ""); - EXPECT_EQ("f", highlightC("f", s, 2)); - EXPECT_EQ("f", highlightC("f", s, 3)); - EXPECT_EQ("f", highlightC("f", s, 4)); -} - -TEST_F(HighlighterTest, ClangCursorPosBeforeOtherToken) { - HighlightStyle s; - s.selected.Set("", ""); - s.identifier.Set("", ""); - - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 0)); -} - -TEST_F(HighlighterTest, ClangCursorPosAfterOtherToken) { - HighlightStyle s; - s.selected.Set("", ""); - s.identifier.Set("", ""); - - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 4)); -} - -TEST_F(HighlighterTest, ClangCursorPosInOtherToken) { - HighlightStyle s; - s.selected.Set("", ""); - s.identifier.Set("", ""); - - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 1)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 2)); - EXPECT_EQ(" foo c = bar(); return 1;", - highlightC(" foo c = bar(); return 1;", s, 3)); -} diff --git a/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp b/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp deleted file mode 100644 index b621ad233e6..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp +++ /dev/null @@ -1,153 +0,0 @@ -//===-- BreakpadRecordsTest.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 "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::breakpad; - -TEST(Record, classify) { - EXPECT_EQ(Record::Module, Record::classify("MODULE")); - EXPECT_EQ(Record::Info, Record::classify("INFO")); - EXPECT_EQ(Record::File, Record::classify("FILE")); - EXPECT_EQ(Record::Func, Record::classify("FUNC")); - EXPECT_EQ(Record::Public, Record::classify("PUBLIC")); - EXPECT_EQ(Record::StackCFI, Record::classify("STACK CFI")); - EXPECT_EQ(Record::StackWin, Record::classify("STACK WIN")); - - // Any obviously incorrect lines will be classified as such. - EXPECT_EQ(llvm::None, Record::classify("STACK")); - EXPECT_EQ(llvm::None, Record::classify("STACK CODE_ID")); - EXPECT_EQ(llvm::None, Record::classify("CODE_ID")); - - // Any line which does not start with a known keyword will be classified as a - // line record, as those are the only ones that start without a keyword. - EXPECT_EQ(Record::Line, Record::classify("deadbeef")); - EXPECT_EQ(Record::Line, Record::classify("12")); -} - -TEST(ModuleRecord, parse) { - EXPECT_EQ(ModuleRecord(llvm::Triple::Linux, llvm::Triple::x86_64, - UUID::fromData("@ABCDEFGHIJKLMNO", 16)), - ModuleRecord::parse( - "MODULE Linux x86_64 404142434445464748494a4b4c4d4e4f0 a.out")); - - EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE")); - EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE Linux")); - EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE Linux x86_64")); - EXPECT_EQ(llvm::None, - ModuleRecord::parse("MODULE Linux x86_64 deadbeefbaadf00d")); -} - -TEST(InfoRecord, parse) { - EXPECT_EQ(InfoRecord(UUID::fromData("@ABCDEFGHIJKLMNO", 16)), - InfoRecord::parse("INFO CODE_ID 404142434445464748494a4b4c4d4e4f")); - EXPECT_EQ(InfoRecord(UUID()), InfoRecord::parse("INFO CODE_ID 47 a.exe")); - - EXPECT_EQ(llvm::None, InfoRecord::parse("INFO")); - EXPECT_EQ(llvm::None, InfoRecord::parse("INFO CODE_ID")); -} - -TEST(FileRecord, parse) { - EXPECT_EQ(FileRecord(47, "foo"), FileRecord::parse("FILE 47 foo")); - EXPECT_EQ(llvm::None, FileRecord::parse("FILE 47")); - EXPECT_EQ(llvm::None, FileRecord::parse("FILE")); - EXPECT_EQ(llvm::None, FileRecord::parse("")); -} - -TEST(FuncRecord, parse) { - EXPECT_EQ(FuncRecord(true, 0x47, 0x7, 0x8, "foo"), - FuncRecord::parse("FUNC m 47 7 8 foo")); - EXPECT_EQ(FuncRecord(false, 0x47, 0x7, 0x8, "foo"), - FuncRecord::parse("FUNC 47 7 8 foo")); - - EXPECT_EQ(llvm::None, FuncRecord::parse("PUBLIC 47 7 8 foo")); - EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47 7 8")); - EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47 7")); - EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47")); - EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC m")); - EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC")); -} - -TEST(LineRecord, parse) { - EXPECT_EQ(LineRecord(0x47, 0x74, 47, 74), LineRecord::parse("47 74 47 74")); - EXPECT_EQ(llvm::None, LineRecord::parse("47 74 47")); - EXPECT_EQ(llvm::None, LineRecord::parse("47 74")); - EXPECT_EQ(llvm::None, LineRecord::parse("47")); - EXPECT_EQ(llvm::None, LineRecord::parse("")); - EXPECT_EQ(llvm::None, LineRecord::parse("FUNC")); -} - -TEST(PublicRecord, parse) { - EXPECT_EQ(PublicRecord(true, 0x47, 0x8, "foo"), - PublicRecord::parse("PUBLIC m 47 8 foo")); - EXPECT_EQ(PublicRecord(false, 0x47, 0x8, "foo"), - PublicRecord::parse("PUBLIC 47 8 foo")); - - EXPECT_EQ(llvm::None, PublicRecord::parse("FUNC 47 8 foo")); - EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC 47 8")); - EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC 47")); - EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC m")); - EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC")); -} - -TEST(StackCFIRecord, parse) { - EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: $esp 4 + $eip: .cfa 4 - ^"), - StackCFIRecord::parse( - "STACK CFI INIT 47 8 .cfa: $esp 4 + $eip: .cfa 4 - ^")); - - EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: $esp 4 +"), - StackCFIRecord::parse("STACK CFI INIT 47 8 .cfa: $esp 4 + ")); - - EXPECT_EQ(StackCFIRecord(0x47, llvm::None, ".cfa: $esp 4 +"), - StackCFIRecord::parse("STACK CFI 47 .cfa: $esp 4 +")); - - // The validity of the register value expressions is not checked - EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: ^ ^ ^"), - StackCFIRecord::parse("STACK CFI INIT 47 8 .cfa: ^ ^ ^")); - - EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI INIT 47")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI INIT")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47")); -} - -TEST(StackWinRecord, parse) { - EXPECT_EQ( - StackWinRecord(0x47, 0x8, 3, 4, 5, llvm::StringRef("$eip $esp ^ =")), - StackWinRecord::parse("STACK WIN 4 47 8 1 2 3 4 5 6 1 $eip $esp ^ =")); - - EXPECT_EQ(llvm::None, StackWinRecord::parse( - "STACK WIN 0 47 8 1 0 0 0 0 0 1 $eip $esp ^ =")); - EXPECT_EQ(llvm::None, - StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0 0 1")); - EXPECT_EQ(llvm::None, StackWinRecord::parse( - "STACK WIN 3 47 8 1 0 0 0 0 0 1 $eip $esp ^ =")); - EXPECT_EQ(llvm::None, - StackWinRecord::parse("STACK WIN 3 47 8 1 0 0 0 0 0 0 1")); - EXPECT_EQ(llvm::None, StackWinRecord::parse( - "STACK WIN 4 47 8 1 0 0 0 0 1 $eip $esp ^ =")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK")); - EXPECT_EQ(llvm::None, StackWinRecord::parse("")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo")); - EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47")); -} diff --git a/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/CMakeLists.txt b/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/CMakeLists.txt deleted file mode 100644 index 34237c139f8..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_lldb_unittest(ObjectFileBreakpadTests - BreakpadRecordsTest.cpp - - LINK_LIBS - lldbPluginObjectFileBreakpad - ) diff --git a/gnu/llvm/lldb/unittests/ObjectFile/CMakeLists.txt b/gnu/llvm/lldb/unittests/ObjectFile/CMakeLists.txt deleted file mode 100644 index b5d248e3965..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_subdirectory(Breakpad) -add_subdirectory(ELF) -add_subdirectory(MachO) -add_subdirectory(PECOFF) diff --git a/gnu/llvm/lldb/unittests/ObjectFile/ELF/CMakeLists.txt b/gnu/llvm/lldb/unittests/ObjectFile/ELF/CMakeLists.txt deleted file mode 100644 index 4c59ca109a5..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/ELF/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_lldb_unittest(ObjectFileELFTests - TestObjectFileELF.cpp - - LINK_LIBS - lldbPluginObjectFileELF - lldbPluginSymbolFileSymtab - lldbCore - lldbUtilityHelpers - LLVMTestingSupport - ) - -set(test_inputs - early-section-headers.so - ) -add_unittest_inputs(ObjectFileELFTests "${test_inputs}") diff --git a/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp deleted file mode 100644 index 9718ad3d27e..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ /dev/null @@ -1,278 +0,0 @@ -//===-- TestObjectFileELF.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 "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/Section.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "llvm/ADT/Optional.h" -#include "llvm/Support/Compression.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb; - -class ObjectFileELFTest : public testing::Test { - SubsystemRAII - subsystems; -}; - -TEST_F(ObjectFileELFTest, SectionsResolveConsistently) { - auto ExpectedFile = TestFile::fromYaml(R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_X86_64 - Entry: 0x0000000000400180 -Sections: - - Name: .note.gnu.build-id - Type: SHT_NOTE - Flags: [ SHF_ALLOC ] - Address: 0x0000000000400158 - AddressAlign: 0x0000000000000004 - Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6 - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - Address: 0x0000000000400180 - AddressAlign: 0x0000000000000010 - Content: 554889E58B042500106000890425041060005DC3 - - Name: .data - Type: SHT_PROGBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x0000000000601000 - AddressAlign: 0x0000000000000004 - Content: 2F000000 - - Name: .bss - Type: SHT_NOBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x0000000000601004 - AddressAlign: 0x0000000000000004 - Size: 0x0000000000000004 -Symbols: - - Name: Y - Type: STT_OBJECT - Section: .data - Value: 0x0000000000601000 - Size: 0x0000000000000004 - Binding: STB_GLOBAL - - Name: _start - Type: STT_FUNC - Section: .text - Value: 0x0000000000400180 - Size: 0x0000000000000014 - Binding: STB_GLOBAL - - Name: X - Type: STT_OBJECT - Section: .bss - Value: 0x0000000000601004 - Size: 0x0000000000000004 - Binding: STB_GLOBAL -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); - SectionList *list = module_sp->GetSectionList(); - ASSERT_NE(nullptr, list); - - auto bss_sp = list->FindSectionByName(ConstString(".bss")); - ASSERT_NE(nullptr, bss_sp); - auto data_sp = list->FindSectionByName(ConstString(".data")); - ASSERT_NE(nullptr, data_sp); - auto text_sp = list->FindSectionByName(ConstString(".text")); - ASSERT_NE(nullptr, text_sp); - - const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"), - eSymbolTypeAny); - ASSERT_NE(nullptr, X); - EXPECT_EQ(bss_sp, X->GetAddress().GetSection()); - - const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"), - eSymbolTypeAny); - ASSERT_NE(nullptr, Y); - EXPECT_EQ(data_sp, Y->GetAddress().GetSection()); - - const Symbol *start = module_sp->FindFirstSymbolWithNameAndType( - ConstString("_start"), eSymbolTypeAny); - ASSERT_NE(nullptr, start); - EXPECT_EQ(text_sp, start->GetAddress().GetSection()); -} - -// Test that GetModuleSpecifications works on an "atypical" object file which -// has section headers right after the ELF header (instead of the more common -// layout where the section headers are at the very end of the object file). -// -// Test file generated with yaml2obj (@svn rev 324254) from the following input: -/* ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_X86_64 - Entry: 0x00000000004003D0 -Sections: - - Name: .note.gnu.build-id - Type: SHT_NOTE - Flags: [ SHF_ALLOC ] - Address: 0x0000000000400274 - AddressAlign: 0x0000000000000004 - Content: 040000001400000003000000474E55001B8A73AC238390E32A7FF4AC8EBE4D6A41ECF5C9 - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - Address: 0x00000000004003D0 - AddressAlign: 0x0000000000000010 - Content: DEADBEEFBAADF00D -... -*/ -TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) { - std::string SO = GetInputFilePath("early-section-headers.so"); - ModuleSpecList Specs; - ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs)); - ModuleSpec Spec; - ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; - UUID Uuid; - Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9"); - EXPECT_EQ(Spec.GetUUID(), Uuid); -} - -TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) { - /* - // nosym-entrypoint-arm-thumb.s - .thumb_func - _start: - mov r0, #42 - mov r7, #1 - svc #0 - // arm-linux-androideabi-as nosym-entrypoint-arm-thumb.s - // -o nosym-entrypoint-arm-thumb.o - // arm-linux-androideabi-ld nosym-entrypoint-arm-thumb.o - // -o nosym-entrypoint-arm-thumb -e 0x8075 -s - */ - auto ExpectedFile = TestFile::fromYaml(R"( ---- !ELF -FileHeader: - Class: ELFCLASS32 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_ARM - Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] - Entry: 0x0000000000008075 -Sections: - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - Address: 0x0000000000008074 - AddressAlign: 0x0000000000000002 - Content: 2A20012700DF - - Name: .data - Type: SHT_PROGBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x0000000000009000 - AddressAlign: 0x0000000000000001 - Content: '' - - Name: .bss - Type: SHT_NOBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x0000000000009000 - AddressAlign: 0x0000000000000001 - - Name: .note.gnu.gold-version - Type: SHT_NOTE - AddressAlign: 0x0000000000000004 - Content: 040000000900000004000000474E5500676F6C6420312E3131000000 - - Name: .ARM.attributes - Type: SHT_ARM_ATTRIBUTES - AddressAlign: 0x0000000000000001 - Content: '4113000000616561626900010900000006020901' -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); - - auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); - ASSERT_TRUE(entry_point_addr.GetOffset() & 1); - // Decrease the offsite by 1 to make it into a breakable address since this - // is Thumb. - entry_point_addr.SetOffset(entry_point_addr.GetOffset() - 1); - ASSERT_EQ(entry_point_addr.GetAddressClass(), - AddressClass::eCodeAlternateISA); -} - -TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) { - /* - // nosym-entrypoint-arm.s - _start: - movs r0, #42 - movs r7, #1 - svc #0 - // arm-linux-androideabi-as nosym-entrypoint-arm.s - // -o nosym-entrypoint-arm.o - // arm-linux-androideabi-ld nosym-entrypoint-arm.o - // -o nosym-entrypoint-arm -e 0x8074 -s - */ - auto ExpectedFile = TestFile::fromYaml(R"( ---- !ELF -FileHeader: - Class: ELFCLASS32 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_ARM - Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] - Entry: 0x0000000000008074 -Sections: - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - Address: 0x0000000000008074 - AddressAlign: 0x0000000000000004 - Content: 2A00A0E30170A0E3000000EF - - Name: .data - Type: SHT_PROGBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x0000000000009000 - AddressAlign: 0x0000000000000001 - Content: '' - - Name: .bss - Type: SHT_NOBITS - Flags: [ SHF_WRITE, SHF_ALLOC ] - Address: 0x0000000000009000 - AddressAlign: 0x0000000000000001 - - Name: .note.gnu.gold-version - Type: SHT_NOTE - AddressAlign: 0x0000000000000004 - Content: 040000000900000004000000474E5500676F6C6420312E3131000000 - - Name: .ARM.attributes - Type: SHT_ARM_ATTRIBUTES - AddressAlign: 0x0000000000000001 - Content: '4113000000616561626900010900000006010801' -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); - - auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); - ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode); -} diff --git a/gnu/llvm/lldb/unittests/ObjectFile/MachO/CMakeLists.txt b/gnu/llvm/lldb/unittests/ObjectFile/MachO/CMakeLists.txt deleted file mode 100644 index b6c4225114a..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/MachO/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_lldb_unittest(ObjectFileMachOTests - TestObjectFileMachO.cpp - - LINK_LIBS - lldbPluginObjectFileMachO - lldbPluginSymbolFileSymtab - lldbCore - lldbUtilityHelpers - LLVMTestingSupport - ) diff --git a/gnu/llvm/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/gnu/llvm/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp deleted file mode 100644 index 119be3822cc..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//===-- ObjectFileMachOTest.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 "lldb/Host/HostInfo.h" -#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Core/Module.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/lldb-defines.h" -#include "gtest/gtest.h" - -#ifdef __APPLE__ -#include -#endif - -using namespace lldb_private; -using namespace llvm; - -namespace { -class ObjectFileMachOTest : public ::testing::Test { - SubsystemRAII subsystems; -}; -} // namespace - -#if defined(__APPLE__) -TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { - SharedCacheImageInfo image_info = - HostInfo::GetSharedCacheImageInfo("/usr/lib/libobjc.A.dylib"); - EXPECT_TRUE(image_info.uuid); - EXPECT_TRUE(image_info.data_sp); - - ModuleSpec spec(FileSpec(), UUID(), image_info.data_sp); - lldb::ModuleSP module = std::make_shared(spec); - ObjectFile *OF = module->GetObjectFile(); - ASSERT_TRUE(llvm::isa(OF)); - EXPECT_TRUE( - OF->GetArchitecture().IsCompatibleMatch(HostInfo::GetArchitecture())); - Symtab *symtab = OF->GetSymtab(); - ASSERT_NE(symtab, nullptr); - void *libobjc = dlopen("/usr/lib/libobjc.A.dylib", RTLD_LAZY); - ASSERT_NE(libobjc, nullptr); - - // This function checks that if we read something from the - // ObjectFile we get through the shared cache in-mmeory - // buffer, it matches what we get by reading directly the - // memory of the symbol. - auto check_symbol = [&](const char *sym_name) { - std::vector symbol_indices; - symtab->FindAllSymbolsWithNameAndType(ConstString(sym_name), - lldb::eSymbolTypeAny, symbol_indices); - EXPECT_EQ(symbol_indices.size(), 1u); - - Symbol *sym = symtab->SymbolAtIndex(symbol_indices[0]); - ASSERT_NE(sym, nullptr); - Address base = sym->GetAddress(); - size_t size = sym->GetByteSize(); - ASSERT_NE(size, 0u); - uint8_t buffer[size]; - EXPECT_EQ(OF->ReadSectionData(base.GetSection().get(), base.GetOffset(), - buffer, size), - size); - - void *sym_addr = dlsym(libobjc, sym_name); - ASSERT_NE(sym_addr, nullptr); - EXPECT_EQ(memcmp(buffer, sym_addr, size), 0); - }; - - // Read a symbol from the __TEXT segment... - check_symbol("objc_msgSend"); - // ... and one from the __DATA segment - check_symbol("OBJC_CLASS_$_NSObject"); -} -#endif diff --git a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/CMakeLists.txt b/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/CMakeLists.txt deleted file mode 100644 index 3ce5a7b9739..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_lldb_unittest(ObjectFilePECOFFTests - TestPECallFrameInfo.cpp - - LINK_LIBS - lldbUtilityHelpers - lldbPluginObjectFilePECOFF - LLVMTestingSupport - ) diff --git a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp b/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp deleted file mode 100644 index e842df59888..00000000000 --- a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp +++ /dev/null @@ -1,328 +0,0 @@ -//===-- TestPECallFrameInfo.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 "gtest/gtest.h" - -#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" -#include "Plugins/Process/Utility/lldb-x86-register-enums.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" - -#include "lldb/Core/Module.h" -#include "lldb/Symbol/CallFrameInfo.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private; -using namespace lldb; - -class PECallFrameInfoTest : public testing::Test { - SubsystemRAII subsystems; - -protected: - void GetUnwindPlan(addr_t file_addr, UnwindPlan &plan) const; -}; - -void PECallFrameInfoTest::GetUnwindPlan(addr_t file_addr, UnwindPlan &plan) const { - llvm::Expected ExpectedFile = TestFile::fromYaml( - R"( ---- !COFF -OptionalHeader: - AddressOfEntryPoint: 0 - ImageBase: 16777216 - SectionAlignment: 4096 - FileAlignment: 512 - MajorOperatingSystemVersion: 6 - MinorOperatingSystemVersion: 0 - MajorImageVersion: 0 - MinorImageVersion: 0 - MajorSubsystemVersion: 6 - MinorSubsystemVersion: 0 - Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI - DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ] - SizeOfStackReserve: 1048576 - SizeOfStackCommit: 4096 - SizeOfHeapReserve: 1048576 - SizeOfHeapCommit: 4096 - ExportTable: - RelativeVirtualAddress: 0 - Size: 0 - ImportTable: - RelativeVirtualAddress: 0 - Size: 0 - ResourceTable: - RelativeVirtualAddress: 0 - Size: 0 - ExceptionTable: - RelativeVirtualAddress: 12288 - Size: 60 - CertificateTable: - RelativeVirtualAddress: 0 - Size: 0 - BaseRelocationTable: - RelativeVirtualAddress: 0 - Size: 0 - Debug: - RelativeVirtualAddress: 0 - Size: 0 - Architecture: - RelativeVirtualAddress: 0 - Size: 0 - GlobalPtr: - RelativeVirtualAddress: 0 - Size: 0 - TlsTable: - RelativeVirtualAddress: 0 - Size: 0 - LoadConfigTable: - RelativeVirtualAddress: 0 - Size: 0 - BoundImport: - RelativeVirtualAddress: 0 - Size: 0 - IAT: - RelativeVirtualAddress: 0 - Size: 0 - DelayImportDescriptor: - RelativeVirtualAddress: 0 - Size: 0 - ClrRuntimeHeader: - RelativeVirtualAddress: 0 - Size: 0 -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - VirtualAddress: 4096 - VirtualSize: 4096 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - VirtualAddress: 8192 - VirtualSize: 68 - SectionData: 010C06000C3208F006E00470036002302105020005540D0000100000001100000020000019400E352F74670028646600213465001A3315015E000EF00CE00AD008C00650 - - -# Unwind info at 0x2000: -# 01 0C 06 00 No chained info, prolog size = 0xC, unwind codes size is 6 words, no frame register -# 0C 32 UOP_AllocSmall(2) 3 * 8 + 8 bytes, offset in prolog is 0xC -# 08 F0 UOP_PushNonVol(0) R15(0xF), offset in prolog is 8 -# 06 E0 UOP_PushNonVol(0) R14(0xE), offset in prolog is 6 -# 04 70 UOP_PushNonVol(0) RDI(7), offset in prolog is 4 -# 03 60 UOP_PushNonVol(0) RSI(6), offset in prolog is 3 -# 02 30 UOP_PushNonVol(0) RBX(3), offset in prolog is 2 -# Corresponding prolog: -# 00 push rbx -# 02 push rsi -# 03 push rdi -# 04 push r14 -# 06 push r15 -# 08 sub rsp, 20h - -# Unwind info at 0x2010: -# 21 05 02 00 Has chained info, prolog size = 5, unwind codes size is 2 words, no frame register -# 05 54 0D 00 UOP_SaveNonVol(4) RBP(5) to RSP + 0xD * 8, offset in prolog is 5 -# Chained runtime function: -# 00 10 00 00 Start address is 0x1000 -# 00 11 00 00 End address is 0x1100 -# 00 20 00 00 Unwind info RVA is 0x2000 -# Corresponding prolog: -# 00 mov [rsp+68h], rbp - -# Unwind info at 0x2024: -# 19 40 0E 35 No chained info, prolog size = 0x40, unwind codes size is 0xE words, frame register is RBP, frame register offset is RSP + 3 * 16 -# 2F 74 67 00 UOP_SaveNonVol(4) RDI(7) to RSP + 0x67 * 8, offset in prolog is 0x2F -# 28 64 66 00 UOP_SaveNonVol(4) RSI(6) to RSP + 0x66 * 8, offset in prolog is 0x28 -# 21 34 65 00 UOP_SaveNonVol(4) RBX(3) to RSP + 0x65 * 8, offset in prolog is 0x21 -# 1A 33 UOP_SetFPReg(3), offset in prolog is 0x1A -# 15 01 5E 00 UOP_AllocLarge(1) 0x5E * 8 bytes, offset in prolog is 0x15 -# 0E F0 UOP_PushNonVol(0) R15(0xF), offset in prolog is 0xE -# 0C E0 UOP_PushNonVol(0) R14(0xE), offset in prolog is 0xC -# 0A D0 UOP_PushNonVol(0) R13(0xD), offset in prolog is 0xA -# 08 C0 UOP_PushNonVol(0) R12(0xC), offset in prolog is 8 -# 06 50 UOP_PushNonVol(0) RBP(5), offset in prolog is 6 -# Corresponding prolog: -# 00 mov [rsp+8], rcx -# 05 push rbp -# 06 push r12 -# 08 push r13 -# 0A push r14 -# 0C push r15 -# 0E sub rsp, 2F0h -# 15 lea rbp, [rsp+30h] -# 1A mov [rbp+2F8h], rbx -# 21 mov [rbp+300h], rsi -# 28 mov [rbp+308h], rdi - - - Name: .pdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - VirtualAddress: 12288 - VirtualSize: 60 - SectionData: 000000000000000000000000000000000000000000000000001000000011000000200000001100000012000010200000001200000013000024200000 - -# 00 00 00 00 -# 00 00 00 00 Test correct processing of empty runtime functions at begin -# 00 00 00 00 - -# 00 00 00 00 -# 00 00 00 00 Test correct processing of empty runtime functions at begin -# 00 00 00 00 - -# 00 10 00 00 Start address is 0x1000 -# 00 11 00 00 End address is 0x1100 -# 00 20 00 00 Unwind info RVA is 0x2000 - -# 00 11 00 00 Start address is 0x1100 -# 00 12 00 00 End address is 0x1200 -# 10 20 00 00 Unwind info RVA is 0x2010 - -# 00 12 00 00 Start address is 0x1200 -# 00 13 00 00 End address is 0x1300 -# 24 20 00 00 Unwind info RVA is 0x2024 - -symbols: [] -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - ModuleSP module_sp = std::make_shared(ExpectedFile->moduleSpec()); - ObjectFile *object_file = module_sp->GetObjectFile(); - ASSERT_NE(object_file, nullptr); - - std::unique_ptr cfi = object_file->CreateCallFrameInfo(); - ASSERT_NE(cfi.get(), nullptr); - - SectionList *sect_list = object_file->GetSectionList(); - ASSERT_NE(sect_list, nullptr); - - EXPECT_TRUE(cfi->GetUnwindPlan(Address(file_addr, sect_list), plan)); -} - -TEST_F(PECallFrameInfoTest, Basic_eh) { - UnwindPlan plan(eRegisterKindLLDB); - GetUnwindPlan(0x1001080, plan); - EXPECT_EQ(plan.GetRowCount(), 7); - - UnwindPlan::Row row; - row.SetOffset(0); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 8); - row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true); - EXPECT_EQ(*plan.GetRowAtIndex(0), row); - - row.SetOffset(2); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x10); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, -0x10, true); - EXPECT_EQ(*plan.GetRowAtIndex(1), row); - - row.SetOffset(3); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x18); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, -0x18, true); - EXPECT_EQ(*plan.GetRowAtIndex(2), row); - - row.SetOffset(4); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x20); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, -0x20, true); - EXPECT_EQ(*plan.GetRowAtIndex(3), row); - - row.SetOffset(6); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x28); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true); - EXPECT_EQ(*plan.GetRowAtIndex(4), row); - - row.SetOffset(8); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x30); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true); - EXPECT_EQ(*plan.GetRowAtIndex(5), row); - - row.SetOffset(0xC); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x50); - EXPECT_EQ(*plan.GetRowAtIndex(6), row); -} - -TEST_F(PECallFrameInfoTest, Chained_eh) { - UnwindPlan plan(eRegisterKindLLDB); - GetUnwindPlan(0x1001180, plan); - EXPECT_EQ(plan.GetRowCount(), 2); - - UnwindPlan::Row row; - row.SetOffset(0); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x50); - row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, -0x10, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, -0x18, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, -0x20, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true); - EXPECT_EQ(*plan.GetRowAtIndex(0), row); - - row.SetOffset(5); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbp_x86_64, 0x18, true); - EXPECT_EQ(*plan.GetRowAtIndex(1), row); -} - -TEST_F(PECallFrameInfoTest, Frame_reg_eh) { - UnwindPlan plan(eRegisterKindLLDB); - GetUnwindPlan(0x1001280, plan); - EXPECT_EQ(plan.GetRowCount(), 11); - - UnwindPlan::Row row; - row.SetOffset(0); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 8); - row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true); - EXPECT_EQ(*plan.GetRowAtIndex(0), row); - - row.SetOffset(6); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x10); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbp_x86_64, -0x10, true); - EXPECT_EQ(*plan.GetRowAtIndex(1), row); - - row.SetOffset(8); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x18); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r12_x86_64, -0x18, true); - EXPECT_EQ(*plan.GetRowAtIndex(2), row); - - row.SetOffset(0xA); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x20); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r13_x86_64, -0x20, true); - EXPECT_EQ(*plan.GetRowAtIndex(3), row); - - row.SetOffset(0xC); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x28); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true); - EXPECT_EQ(*plan.GetRowAtIndex(4), row); - - row.SetOffset(0xE); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x30); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true); - EXPECT_EQ(*plan.GetRowAtIndex(5), row); - - row.SetOffset(0x15); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x320); - EXPECT_EQ(*plan.GetRowAtIndex(6), row); - - row.SetOffset(0x1A); - row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rbp_x86_64, 0x2F0); - EXPECT_EQ(*plan.GetRowAtIndex(7), row); - - row.SetOffset(0x21); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, 8, true); - EXPECT_EQ(*plan.GetRowAtIndex(8), row); - - row.SetOffset(0x28); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, 0x10, true); - EXPECT_EQ(*plan.GetRowAtIndex(9), row); - - row.SetOffset(0x2F); - row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, 0x18, true); - EXPECT_EQ(*plan.GetRowAtIndex(10), row); -} diff --git a/gnu/llvm/lldb/unittests/Platform/Android/AdbClientTest.cpp b/gnu/llvm/lldb/unittests/Platform/Android/AdbClientTest.cpp deleted file mode 100644 index 0808b96f69f..00000000000 --- a/gnu/llvm/lldb/unittests/Platform/Android/AdbClientTest.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//===-- AdbClientTest.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 "gtest/gtest.h" -#include "Plugins/Platform/Android/AdbClient.h" -#include - -static void set_env(const char *var, const char *value) { -#ifdef _WIN32 - _putenv_s(var, value); -#else - setenv(var, value, true); -#endif -} - -using namespace lldb; -using namespace lldb_private; - -namespace lldb_private { -namespace platform_android { - -class AdbClientTest : public ::testing::Test { -public: - void SetUp() override { set_env("ANDROID_SERIAL", ""); } - - void TearDown() override { set_env("ANDROID_SERIAL", ""); } -}; - -TEST(AdbClientTest, CreateByDeviceId) { - AdbClient adb; - Status error = AdbClient::CreateByDeviceID("device1", adb); - EXPECT_TRUE(error.Success()); - EXPECT_EQ("device1", adb.GetDeviceID()); -} - -TEST(AdbClientTest, CreateByDeviceId_ByEnvVar) { - set_env("ANDROID_SERIAL", "device2"); - - AdbClient adb; - Status error = AdbClient::CreateByDeviceID("", adb); - EXPECT_TRUE(error.Success()); - EXPECT_EQ("device2", adb.GetDeviceID()); -} - -} // end namespace platform_android -} // end namespace lldb_private diff --git a/gnu/llvm/lldb/unittests/Platform/Android/CMakeLists.txt b/gnu/llvm/lldb/unittests/Platform/Android/CMakeLists.txt deleted file mode 100644 index 489fdab7036..00000000000 --- a/gnu/llvm/lldb/unittests/Platform/Android/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -include_directories(${LLDB_SOURCE_DIR}/source/Plugins/Platform/Android) - -add_lldb_unittest(AdbClientTests - AdbClientTest.cpp - - LINK_LIBS - lldbPluginPlatformAndroid - ) diff --git a/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt b/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt deleted file mode 100644 index ca5031b9b43..00000000000 --- a/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_lldb_unittest(LLDBPlatformTests - PlatformAppleSimulatorTest.cpp - PlatformDarwinTest.cpp - - LINK_LIBS - lldbPluginPlatformMacOSX - LINK_COMPONENTS - Support - ) - -add_subdirectory(Android) diff --git a/gnu/llvm/lldb/unittests/Platform/PlatformAppleSimulatorTest.cpp b/gnu/llvm/lldb/unittests/Platform/PlatformAppleSimulatorTest.cpp deleted file mode 100644 index 42549e89cc3..00000000000 --- a/gnu/llvm/lldb/unittests/Platform/PlatformAppleSimulatorTest.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===-- PlatformAppleSimulatorTest.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 "gtest/gtest.h" - -#include "Plugins/Platform/MacOSX/PlatformAppleSimulator.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Platform.h" - -using namespace lldb; -using namespace lldb_private; - -class PlatformAppleSimulatorTest : public ::testing::Test { - SubsystemRAII - subsystems; -}; - -#ifdef __APPLE__ - -static void testSimPlatformArchHasSimEnvironment(llvm::StringRef name) { - Status error; - auto platform_sp = Platform::Create(ConstString(name), error); - ASSERT_TRUE(platform_sp); - int num_arches = 0; - - while (true) { - ArchSpec arch; - if (!platform_sp->GetSupportedArchitectureAtIndex(num_arches, arch)) - break; - EXPECT_EQ(arch.GetTriple().getEnvironment(), llvm::Triple::Simulator); - num_arches++; - } - - EXPECT_GT(num_arches, 0); -} - -TEST_F(PlatformAppleSimulatorTest, TestSimHasSimEnvionament) { - testSimPlatformArchHasSimEnvironment("ios-simulator"); - testSimPlatformArchHasSimEnvironment("tvos-simulator"); - testSimPlatformArchHasSimEnvironment("watchos-simulator"); -} - -TEST_F(PlatformAppleSimulatorTest, TestHostPlatformToSim) { - static const ArchSpec platform_arch( - HostInfo::GetArchitecture(HostInfo::eArchKindDefault)); - - const llvm::Triple::OSType sim_platforms[] = { - llvm::Triple::IOS, - llvm::Triple::TvOS, - llvm::Triple::WatchOS, - }; - - for (auto sim : sim_platforms) { - ArchSpec arch = platform_arch; - arch.GetTriple().setOS(sim); - arch.GetTriple().setEnvironment(llvm::Triple::Simulator); - - Status error; - auto platform_sp = Platform::Create(arch, nullptr, error); - EXPECT_TRUE(platform_sp); - } -} - -#endif diff --git a/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp b/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp deleted file mode 100644 index 285dc2ee3db..00000000000 --- a/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//===-- PlatformDarwinTest.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 "gtest/gtest.h" - -#include "Plugins/Platform/MacOSX/PlatformDarwin.h" - -#include "llvm/ADT/StringRef.h" - -#include - -using namespace lldb; -using namespace lldb_private; - -struct PlatformDarwinTester : public PlatformDarwin { -public: - using PlatformDarwin::FindComponentInPath; -}; - -TEST(PlatformDarwinTest, TestParseVersionBuildDir) { - llvm::VersionTuple V; - llvm::StringRef D; - - std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("1.2.3 (test1)"); - EXPECT_EQ(llvm::VersionTuple(1, 2, 3), V); - EXPECT_EQ("test1", D); - - std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("2.3 (test2)"); - EXPECT_EQ(llvm::VersionTuple(2, 3), V); - EXPECT_EQ("test2", D); - - std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("3 (test3)"); - EXPECT_EQ(llvm::VersionTuple(3), V); - EXPECT_EQ("test3", D); - - std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("1.2.3 (test"); - EXPECT_EQ(llvm::VersionTuple(1, 2, 3), V); - EXPECT_EQ("test", D); - - std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("2.3.4 test"); - EXPECT_EQ(llvm::VersionTuple(2, 3, 4), V); - EXPECT_EQ("", D); - - std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("3.4.5"); - EXPECT_EQ(llvm::VersionTuple(3, 4, 5), V); -} - -TEST(PlatformDarwinTest, FindComponentInPath) { - EXPECT_EQ("/path/to/foo", - PlatformDarwinTester::FindComponentInPath("/path/to/foo/", "foo")); - - EXPECT_EQ("/path/to/foo", - PlatformDarwinTester::FindComponentInPath("/path/to/foo", "foo")); - - EXPECT_EQ("/path/to/foobar", PlatformDarwinTester::FindComponentInPath( - "/path/to/foobar", "foo")); - - EXPECT_EQ("/path/to/foobar", PlatformDarwinTester::FindComponentInPath( - "/path/to/foobar", "bar")); - - EXPECT_EQ("", - PlatformDarwinTester::FindComponentInPath("/path/to/foo", "bar")); -} diff --git a/gnu/llvm/lldb/unittests/Process/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/CMakeLists.txt deleted file mode 100644 index 5fbecfcfa25..00000000000 --- a/gnu/llvm/lldb/unittests/Process/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -add_subdirectory(gdb-remote) -if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") - add_subdirectory(Linux) - add_subdirectory(POSIX) -endif() -add_subdirectory(Utility) -add_subdirectory(minidump) - -add_lldb_unittest(ProcessEventDataTests - ProcessEventDataTest.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbTarget - lldbSymbol - lldbUtility - lldbUtilityHelpers - lldbInterpreter - lldbPluginPlatformMacOSX - ) diff --git a/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt deleted file mode 100644 index ae021023cf7..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_lldb_unittest(TraceIntelPTTests - IntelPTManagerTests.cpp - - LINK_LIBS - lldbPluginProcessLinux - ) - -target_include_directories(TraceIntelPTTests PRIVATE - ${LLDB_SOURCE_DIR}/source/Plugins/Process/Linux) diff --git a/gnu/llvm/lldb/unittests/Process/Linux/IntelPTManagerTests.cpp b/gnu/llvm/lldb/unittests/Process/Linux/IntelPTManagerTests.cpp deleted file mode 100644 index 76eb78a5193..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Linux/IntelPTManagerTests.cpp +++ /dev/null @@ -1,147 +0,0 @@ -//===-- IntelPTManagerTests.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 "gtest/gtest.h" - -#include "IntelPTManager.h" -#include "llvm/ADT/ArrayRef.h" - - -using namespace lldb_private; -using namespace process_linux; - -size_t ReadCylicBufferWrapper(void *buf, size_t buf_size, void *cyc_buf, - size_t cyc_buf_size, size_t cyc_start, - size_t offset) { - llvm::MutableArrayRef dst(reinterpret_cast(buf), - buf_size); - llvm::MutableArrayRef src(reinterpret_cast(cyc_buf), - cyc_buf_size); - IntelPTThreadTrace::ReadCyclicBuffer(dst, src, cyc_start, offset); - return dst.size(); -} - -TEST(CyclicBuffer, EdgeCases) { - size_t bytes_read; - uint8_t cyclic_buffer[6] = {'l', 'i', 'c', 'c', 'y', 'c'}; - - // We will always leave the last bytes untouched - // so that string comparisons work. - char smaller_buffer[4] = {}; - - // empty buffer to read into - bytes_read = ReadCylicBufferWrapper(smaller_buffer, 0, cyclic_buffer, - sizeof(cyclic_buffer), 3, 0); - ASSERT_EQ(0u, bytes_read); - - // empty cyclic buffer - bytes_read = ReadCylicBufferWrapper(smaller_buffer, sizeof(smaller_buffer), - cyclic_buffer, 0, 3, 0); - ASSERT_EQ(0u, bytes_read); - - // bigger offset - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, sizeof(smaller_buffer), - cyclic_buffer, sizeof(cyclic_buffer), 3, 6); - ASSERT_EQ(0u, bytes_read); - - // wrong offset - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, sizeof(smaller_buffer), - cyclic_buffer, sizeof(cyclic_buffer), 3, 7); - ASSERT_EQ(0u, bytes_read); - - // wrong start - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, sizeof(smaller_buffer), - cyclic_buffer, sizeof(cyclic_buffer), 3, 7); - ASSERT_EQ(0u, bytes_read); -} - -TEST(CyclicBuffer, EqualSizeBuffer) { - size_t bytes_read = 0; - uint8_t cyclic_buffer[6] = {'l', 'i', 'c', 'c', 'y', 'c'}; - - char cyclic[] = "cyclic"; - for (size_t i = 0; i < sizeof(cyclic); i++) { - // We will always leave the last bytes untouched - // so that string comparisons work. - char equal_size_buffer[7] = {}; - bytes_read = - ReadCylicBufferWrapper(equal_size_buffer, sizeof(cyclic_buffer), - cyclic_buffer, sizeof(cyclic_buffer), 3, i); - ASSERT_EQ((sizeof(cyclic) - i - 1), bytes_read); - ASSERT_STREQ(equal_size_buffer, (cyclic + i)); - } -} - -TEST(CyclicBuffer, SmallerSizeBuffer) { - size_t bytes_read; - uint8_t cyclic_buffer[6] = {'l', 'i', 'c', 'c', 'y', 'c'}; - - // We will always leave the last bytes untouched - // so that string comparisons work. - char smaller_buffer[4] = {}; - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, 0); - ASSERT_EQ(3u, bytes_read); - ASSERT_STREQ(smaller_buffer, "cyc"); - - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, 1); - ASSERT_EQ(3u, bytes_read); - ASSERT_STREQ(smaller_buffer, "ycl"); - - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, 2); - ASSERT_EQ(3u, bytes_read); - ASSERT_STREQ(smaller_buffer, "cli"); - - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, 3); - ASSERT_EQ(3u, bytes_read); - ASSERT_STREQ(smaller_buffer, "lic"); - - { - char smaller_buffer[4] = {}; - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, 4); - ASSERT_EQ(2u, bytes_read); - ASSERT_STREQ(smaller_buffer, "ic"); - } - { - char smaller_buffer[4] = {}; - bytes_read = - ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, 5); - ASSERT_EQ(1u, bytes_read); - ASSERT_STREQ(smaller_buffer, "c"); - } -} - -TEST(CyclicBuffer, BiggerSizeBuffer) { - size_t bytes_read = 0; - uint8_t cyclic_buffer[6] = {'l', 'i', 'c', 'c', 'y', 'c'}; - - char cyclic[] = "cyclic"; - for (size_t i = 0; i < sizeof(cyclic); i++) { - // We will always leave the last bytes untouched - // so that string comparisons work. - char bigger_buffer[10] = {}; - bytes_read = - ReadCylicBufferWrapper(bigger_buffer, (sizeof(bigger_buffer) - 1), - cyclic_buffer, sizeof(cyclic_buffer), 3, i); - ASSERT_EQ((sizeof(cyclic) - i - 1), bytes_read); - ASSERT_STREQ(bigger_buffer, (cyclic + i)); - } -} diff --git a/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt deleted file mode 100644 index 9d12495dd3e..00000000000 --- a/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_lldb_unittest(ProcessPOSIXTests - NativeProcessELFTest.cpp - - LINK_LIBS - lldbPluginProcessPOSIX - ) - -target_include_directories(ProcessPOSIXTests PRIVATE - ${LLDB_SOURCE_DIR}/source/Plugins/Process/POSIX) diff --git a/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp b/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp deleted file mode 100644 index 19163aeac69..00000000000 --- a/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp +++ /dev/null @@ -1,155 +0,0 @@ -//===-- NativeProcessELFTest.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 "TestingSupport/Host/NativeProcessTestUtils.h" - -#include "Plugins/Process/POSIX/NativeProcessELF.h" -#include "Plugins/Process/Utility/AuxVector.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataEncoder.h" -#include "lldb/Utility/DataExtractor.h" -#include "llvm/BinaryFormat/ELF.h" -#include "llvm/Support/MemoryBuffer.h" - -#include "gmock/gmock.h" - -using namespace lldb_private; -using namespace lldb; -using namespace testing; - -namespace { -class MockProcessELF : public MockProcess { -public: - using MockProcess::MockProcess; - using NativeProcessELF::GetAuxValue; - using NativeProcessELF::GetELFImageInfoAddress; -}; - -std::unique_ptr CreateAuxvData( - MockProcessELF &process, - llvm::ArrayRef> auxv_data) { - auto addr_size = process.GetAddressByteSize(); - DataBufferSP buffer_sp( - new DataBufferHeap(auxv_data.size() * addr_size * 2, 0)); - DataEncoder encoder(buffer_sp, process.GetByteOrder(), addr_size); - uint32_t offset = 0; - for (auto &pair : auxv_data) { - offset = encoder.PutAddress(offset, pair.first); - offset = encoder.PutAddress(offset, pair.second); - } - return llvm::MemoryBuffer::getMemBufferCopy( - llvm::toStringRef(buffer_sp->GetData()), ""); -} - -} // namespace - -TEST(NativeProcessELFTest, GetAuxValue) { - NiceMock DummyDelegate; - MockProcessELF process(DummyDelegate, ArchSpec("i386-pc-linux")); - - uint64_t phdr_addr = 0x42; - auto auxv_buffer = CreateAuxvData( - process, {std::make_pair(AuxVector::AUXV_AT_PHDR, phdr_addr)}); - EXPECT_CALL(process, GetAuxvData()) - .WillOnce(Return(ByMove(std::move(auxv_buffer)))); - - ASSERT_EQ(phdr_addr, process.GetAuxValue(AuxVector::AUXV_AT_PHDR)); -} - -TEST(NativeProcessELFTest, GetELFImageInfoAddress) { - NiceMock DummyDelegate; - MockProcessELF process(DummyDelegate, ArchSpec("i386-pc-linux")); - - uint32_t load_base = 0x1000; - uint32_t info_addr = 0x3741; - uint32_t phdr_addr = load_base + sizeof(llvm::ELF::Elf32_Ehdr); - - auto auxv_buffer = CreateAuxvData( - process, - {std::make_pair(AuxVector::AUXV_AT_PHDR, phdr_addr), - std::make_pair(AuxVector::AUXV_AT_PHENT, sizeof(llvm::ELF::Elf32_Phdr)), - std::make_pair(AuxVector::AUXV_AT_PHNUM, 2)}); - EXPECT_CALL(process, GetAuxvData()) - .WillOnce(Return(ByMove(std::move(auxv_buffer)))); - - // We're going to set up a fake memory with 2 program headers and 1 entry in - // the dynamic section. For simplicity sake they will be contiguous in memory. - struct MemoryContents { - llvm::ELF::Elf32_Phdr phdr_load; - llvm::ELF::Elf32_Phdr phdr_dynamic; - llvm::ELF::Elf32_Dyn dyn_debug; - } MC; - // Setup the 2 program header entries - MC.phdr_load.p_type = llvm::ELF::PT_PHDR; - MC.phdr_load.p_vaddr = phdr_addr - load_base; - - MC.phdr_dynamic.p_type = llvm::ELF::PT_DYNAMIC; - MC.phdr_dynamic.p_vaddr = - (phdr_addr + 2 * sizeof(llvm::ELF::Elf32_Phdr)) - load_base; - MC.phdr_dynamic.p_memsz = sizeof(llvm::ELF::Elf32_Dyn); - - // Setup the single entry in the .dynamic section - MC.dyn_debug.d_tag = llvm::ELF::DT_DEBUG; - MC.dyn_debug.d_un.d_ptr = info_addr; - - FakeMemory M(&MC, sizeof(MC), phdr_addr); - EXPECT_CALL(process, ReadMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); - - lldb::addr_t elf_info_addr = process.GetELFImageInfoAddress< - llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>(); - - // Read the address at the elf_info_addr location to make sure we're reading - // the correct one. - lldb::offset_t info_addr_offset = elf_info_addr - phdr_addr; - DataExtractor mem_extractor(&MC, sizeof(MC), process.GetByteOrder(), - process.GetAddressByteSize()); - ASSERT_EQ(mem_extractor.GetAddress(&info_addr_offset), info_addr); -} - -TEST(NativeProcessELFTest, GetELFImageInfoAddress_NoDebugEntry) { - NiceMock DummyDelegate; - MockProcessELF process(DummyDelegate, ArchSpec("i386-pc-linux")); - - uint32_t phdr_addr = sizeof(llvm::ELF::Elf32_Ehdr); - - auto auxv_buffer = CreateAuxvData( - process, - {std::make_pair(AuxVector::AUXV_AT_PHDR, phdr_addr), - std::make_pair(AuxVector::AUXV_AT_PHENT, sizeof(llvm::ELF::Elf32_Phdr)), - std::make_pair(AuxVector::AUXV_AT_PHNUM, 2)}); - EXPECT_CALL(process, GetAuxvData()) - .WillOnce(Return(ByMove(std::move(auxv_buffer)))); - - // We're going to set up a fake memory with 2 program headers and 1 entry in - // the dynamic section. For simplicity sake they will be contiguous in memory. - struct MemoryContents { - llvm::ELF::Elf32_Phdr phdr_load; - llvm::ELF::Elf32_Phdr phdr_dynamic; - llvm::ELF::Elf32_Dyn dyn_notdebug; - } MC; - // Setup the 2 program header entries - MC.phdr_load.p_type = llvm::ELF::PT_PHDR; - MC.phdr_load.p_vaddr = phdr_addr; - - MC.phdr_dynamic.p_type = llvm::ELF::PT_DYNAMIC; - MC.phdr_dynamic.p_vaddr = (phdr_addr + 2 * sizeof(llvm::ELF::Elf32_Phdr)); - MC.phdr_dynamic.p_memsz = sizeof(llvm::ELF::Elf32_Dyn); - - // Setup the single entry in the .dynamic section - MC.dyn_notdebug.d_tag = llvm::ELF::DT_NULL; - - FakeMemory M(&MC, sizeof(MC), phdr_addr); - EXPECT_CALL(process, ReadMemory(_, _)) - .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); - - lldb::addr_t elf_info_addr = process.GetELFImageInfoAddress< - llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>(); - - ASSERT_EQ(elf_info_addr, LLDB_INVALID_ADDRESS); -} diff --git a/gnu/llvm/lldb/unittests/Process/ProcessEventDataTest.cpp b/gnu/llvm/lldb/unittests/Process/ProcessEventDataTest.cpp deleted file mode 100644 index 8827384ed0a..00000000000 --- a/gnu/llvm/lldb/unittests/Process/ProcessEventDataTest.cpp +++ /dev/null @@ -1,252 +0,0 @@ -//===-- ProcessEventDataTest.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 "Plugins/Platform/MacOSX/PlatformMacOSX.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Event.h" -#include "lldb/Utility/Reproducer.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace lldb; - -namespace { -class ProcessEventDataTest : public ::testing::Test { -public: - void SetUp() override { - llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); - FileSystem::Initialize(); - HostInfo::Initialize(); - PlatformMacOSX::Initialize(); - } - void TearDown() override { - PlatformMacOSX::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - Reproducer::Terminate(); - } -}; - -class DummyProcess : public Process { -public: - using Process::Process; - - bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override { - return true; - } - Status DoDestroy() override { return {}; } - void RefreshStateAfterStop() override {} - size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - Status &error) override { - return 0; - } - bool DoUpdateThreadList(ThreadList &old_thread_list, - ThreadList &new_thread_list) override { - return false; - } - ConstString GetPluginName() override { return ConstString("Dummy"); } - uint32_t GetPluginVersion() override { return 0; } - - ProcessModID &GetModIDNonConstRef() { return m_mod_id; } -}; - -class DummyThread : public Thread { -public: - using Thread::Thread; - - ~DummyThread() override { DestroyThread(); } - - void RefreshStateAfterStop() override {} - - lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } - - lldb::RegisterContextSP - CreateRegisterContextForFrame(StackFrame *frame) override { - return nullptr; - } - - bool CalculateStopInfo() override { return false; } -}; - -class DummyStopInfo : public StopInfo { -public: - DummyStopInfo(Thread &thread, uint64_t value) - : StopInfo(thread, value), m_should_stop(true), - m_stop_reason(eStopReasonBreakpoint) {} - - bool ShouldStop(Event *event_ptr) override { return m_should_stop; } - - StopReason GetStopReason() const override { return m_stop_reason; } - - bool m_should_stop; - StopReason m_stop_reason; -}; - -class DummyProcessEventData : public Process::ProcessEventData { -public: - DummyProcessEventData(ProcessSP &process_sp, StateType state) - : ProcessEventData(process_sp, state), m_should_stop_hit_count(0) {} - bool ShouldStop(Event *event_ptr, bool &found_valid_stopinfo) override { - m_should_stop_hit_count++; - return false; - } - - int m_should_stop_hit_count; -}; -} // namespace - -typedef std::shared_ptr ProcessEventDataSP; -typedef std::shared_ptr EventSP; - -TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) { - PlatformSP platform_sp; - TargetSP target_sp; - debugger_sp->GetTargetList().CreateTarget( - *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); - - return target_sp; -} - -ThreadSP CreateThread(ProcessSP &process_sp, bool should_stop, - bool has_valid_stopinfo) { - ThreadSP thread_sp = std::make_shared(*process_sp.get(), 0); - if (thread_sp == nullptr) { - return nullptr; - } - - if (has_valid_stopinfo) { - StopInfoSP stopinfo_sp = - std::make_shared(*thread_sp.get(), 0); - static_cast(stopinfo_sp.get())->m_should_stop = - should_stop; - if (stopinfo_sp == nullptr) { - return nullptr; - } - - thread_sp->SetStopInfo(stopinfo_sp); - } - - process_sp->GetThreadList().AddThread(thread_sp); - - return thread_sp; -} - -TEST_F(ProcessEventDataTest, DoOnRemoval) { - ArchSpec arch("x86_64-apple-macosx-"); - - Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch)); - - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - TargetSP target_sp = CreateTarget(debugger_sp, arch); - ASSERT_TRUE(target_sp); - - ListenerSP listener_sp(Listener::MakeListener("dummy")); - ProcessSP process_sp = std::make_shared(target_sp, listener_sp); - ASSERT_TRUE(process_sp); - - /* - Should hit ShouldStop if state is eStateStopped - */ - ProcessEventDataSP event_data_sp = - std::make_shared(process_sp, eStateStopped); - EventSP event_sp = std::make_shared(0, event_data_sp); - event_data_sp->SetUpdateStateOnRemoval(event_sp.get()); - event_data_sp->DoOnRemoval(event_sp.get()); - bool result = static_cast(event_data_sp.get()) - ->m_should_stop_hit_count == 1; - ASSERT_TRUE(result); - - /* - Should not hit ShouldStop if state is not eStateStopped - */ - event_data_sp = - std::make_shared(process_sp, eStateStepping); - event_sp = std::make_shared(0, event_data_sp); - event_data_sp->SetUpdateStateOnRemoval(event_sp.get()); - event_data_sp->DoOnRemoval(event_sp.get()); - result = static_cast(event_data_sp.get()) - ->m_should_stop_hit_count == 0; - ASSERT_TRUE(result); -} - -TEST_F(ProcessEventDataTest, ShouldStop) { - ArchSpec arch("x86_64-apple-macosx-"); - - Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch)); - - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - TargetSP target_sp = CreateTarget(debugger_sp, arch); - ASSERT_TRUE(target_sp); - - ListenerSP listener_sp(Listener::MakeListener("dummy")); - ProcessSP process_sp = std::make_shared(target_sp, listener_sp); - ASSERT_TRUE(process_sp); - - // wants to stop and has valid StopInfo - ThreadSP thread_sp = CreateThread(process_sp, true, true); - - ProcessEventDataSP event_data_sp = - std::make_shared(process_sp, eStateStopped); - EventSP event_sp = std::make_shared(0, event_data_sp); - /* - Should stop if thread has valid StopInfo and not suspended - */ - bool found_valid_stopinfo = false; - bool should_stop = - event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo); - ASSERT_TRUE(should_stop == true && found_valid_stopinfo == true); - - /* - Should not stop if thread has valid StopInfo but was suspended - */ - found_valid_stopinfo = false; - thread_sp->SetResumeState(eStateSuspended); - should_stop = event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo); - ASSERT_TRUE(should_stop == false && found_valid_stopinfo == false); - - /* - Should not stop, thread-reason of stop does not want to stop in its - callback and suspended thread who wants to (from previous stop) - must be ignored. - */ - event_data_sp = - std::make_shared(process_sp, eStateStopped); - event_sp = std::make_shared(0, event_data_sp); - process_sp->GetThreadList().Clear(); - - for (int i = 0; i < 6; i++) { - if (i == 2) { - // Does not want to stop but has valid StopInfo - thread_sp = CreateThread(process_sp, false, true); - } else if (i == 5) { - // Wants to stop and has valid StopInfo - thread_sp = CreateThread(process_sp, true, true); - thread_sp->SetResumeState(eStateSuspended); - } else { - // Thread has no StopInfo i.e is not the reason of stop - thread_sp = CreateThread(process_sp, false, false); - } - } - ASSERT_TRUE(process_sp->GetThreadList().GetSize() == 6); - - found_valid_stopinfo = false; - should_stop = event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo); - ASSERT_TRUE(should_stop == false && found_valid_stopinfo == true); -} diff --git a/gnu/llvm/lldb/unittests/Process/Utility/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/Utility/CMakeLists.txt deleted file mode 100644 index 95b65cef6a4..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(FREEBSD_SOURCES - RegisterContextFreeBSDTest.cpp) -set(NETBSD_SOURCES - RegisterContextNetBSDTest_i386.cpp - RegisterContextNetBSDTest_x86_64.cpp) - -if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - list(APPEND PLATFORM_SOURCES ${FREEBSD_SOURCES}) -elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") - list(APPEND PLATFORM_SOURCES ${NETBSD_SOURCES}) -endif() - -set(LLVM_OPTIONAL_SOURCES - ${FREEBSD_SOURCES} - ${NETBSD_SOURCES}) - -add_lldb_unittest(ProcessUtilityTests - RegisterContextTest.cpp - LinuxProcMapsTest.cpp - MemoryTagManagerAArch64MTETest.cpp - ${PLATFORM_SOURCES} - - LINK_LIBS - lldbPluginProcessUtility - LLVMTestingSupport) diff --git a/gnu/llvm/lldb/unittests/Process/Utility/LinuxProcMapsTest.cpp b/gnu/llvm/lldb/unittests/Process/Utility/LinuxProcMapsTest.cpp deleted file mode 100644 index 66db61ff659..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/LinuxProcMapsTest.cpp +++ /dev/null @@ -1,262 +0,0 @@ -//===-- LinuxProcMapsTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "Plugins/Process/Utility/LinuxProcMaps.h" -#include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Utility/Status.h" -#include - -using namespace lldb_private; - -typedef std::tuple - LinuxProcMapsTestParams; - -// Wrapper for convenience because Range is usually begin, size -static MemoryRegionInfo::RangeType make_range(lldb::addr_t begin, - lldb::addr_t end) { - MemoryRegionInfo::RangeType range(begin, 0); - range.SetRangeEnd(end); - return range; -} - -class LinuxProcMapsTestFixture - : public ::testing::TestWithParam { -protected: - Status error; - std::string err_str; - MemoryRegionInfos regions; - LinuxMapCallback callback; - - void SetUp() override { - callback = [this](llvm::Expected Info) { - if (Info) { - err_str.clear(); - regions.push_back(*Info); - return true; - } - - err_str = toString(Info.takeError()); - return false; - }; - } - - void check_regions(LinuxProcMapsTestParams params) { - EXPECT_THAT(std::get<1>(params), testing::ContainerEq(regions)); - ASSERT_EQ(std::get<2>(params), err_str); - } -}; - -TEST_P(LinuxProcMapsTestFixture, ParseMapRegions) { - auto params = GetParam(); - ParseLinuxMapRegions(std::get<0>(params), callback); - check_regions(params); -} - -// Note: ConstString("") != ConstString(nullptr) -// When a region has no name, it will have the latter in the MemoryRegionInfo -INSTANTIATE_TEST_SUITE_P( - ProcMapTests, LinuxProcMapsTestFixture, - ::testing::Values( - // Nothing in nothing out - std::make_tuple("", MemoryRegionInfos{}, ""), - // Various formatting error conditions - std::make_tuple("55a4512f7000/55a451b68000 rw-p 00000000 00:00 0", - MemoryRegionInfos{}, - "malformed /proc/{pid}/maps entry, missing dash " - "between address range"), - std::make_tuple("0-0 rw", MemoryRegionInfos{}, - "malformed /proc/{pid}/maps entry, missing some " - "portion of permissions"), - std::make_tuple("0-0 z--p 00000000 00:00 0", MemoryRegionInfos{}, - "unexpected /proc/{pid}/maps read permission char"), - std::make_tuple("0-0 rz-p 00000000 00:00 0", MemoryRegionInfos{}, - "unexpected /proc/{pid}/maps write permission char"), - std::make_tuple("0-0 rwzp 00000000 00:00 0", MemoryRegionInfos{}, - "unexpected /proc/{pid}/maps exec permission char"), - // Stops at first parsing error - std::make_tuple( - "0-1 rw-p 00000000 00:00 0 [abc]\n" - "0-0 rwzp 00000000 00:00 0\n" - "2-3 r-xp 00000000 00:00 0 [def]\n", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0, 1), MemoryRegionInfo::eYes, - MemoryRegionInfo::eYes, MemoryRegionInfo::eNo, - MemoryRegionInfo::eYes, ConstString("[abc]"), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - }, - "unexpected /proc/{pid}/maps exec permission char"), - // Single entry - std::make_tuple( - "55a4512f7000-55a451b68000 rw-p 00000000 00:00 0 [heap]", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0x55a4512f7000, 0x55a451b68000), - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - ConstString("[heap]"), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - }, - ""), - // Multiple entries - std::make_tuple( - "7fc090021000-7fc094000000 ---p 00000000 00:00 0\n" - "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 " - "[vsyscall]", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0x7fc090021000, 0x7fc094000000), - MemoryRegionInfo::eNo, MemoryRegionInfo::eNo, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - ConstString(nullptr), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - MemoryRegionInfo( - make_range(0xffffffffff600000, 0xffffffffff601000), - MemoryRegionInfo::eYes, MemoryRegionInfo::eNo, - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - ConstString("[vsyscall]"), MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - }, - ""))); - -class LinuxProcSMapsTestFixture : public LinuxProcMapsTestFixture {}; - -INSTANTIATE_TEST_SUITE_P( - ProcSMapTests, LinuxProcSMapsTestFixture, - ::testing::Values( - // Nothing in nothing out - std::make_tuple("", MemoryRegionInfos{}, ""), - // Uses the same parsing for first line, so same errors but referring to - // smaps - std::make_tuple("0/0 rw-p 00000000 00:00 0", MemoryRegionInfos{}, - "malformed /proc/{pid}/smaps entry, missing dash " - "between address range"), - // Stop parsing at first error - std::make_tuple( - "1111-2222 rw-p 00000000 00:00 0 [foo]\n" - "0/0 rw-p 00000000 00:00 0", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0x1111, 0x2222), - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - ConstString("[foo]"), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - }, - "malformed /proc/{pid}/smaps entry, missing dash between address " - "range"), - // Property line without a region is an error - std::make_tuple("Referenced: 2188 kB\n" - "1111-2222 rw-p 00000000 00:00 0 [foo]\n" - "3333-4444 rw-p 00000000 00:00 0 [bar]\n", - MemoryRegionInfos{}, - "Found a property line without a corresponding mapping " - "in /proc/{pid}/smaps"), - // Single region parses, has no flags - std::make_tuple( - "1111-2222 rw-p 00000000 00:00 0 [foo]", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0x1111, 0x2222), - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - ConstString("[foo]"), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - }, - ""), - // Single region with flags, other lines ignored - std::make_tuple( - "1111-2222 rw-p 00000000 00:00 0 [foo]\n" - "Referenced: 2188 kB\n" - "AnonHugePages: 0 kB\n" - "VmFlags: mt", - MemoryRegionInfos{ - MemoryRegionInfo( - make_range(0x1111, 0x2222), MemoryRegionInfo::eYes, - MemoryRegionInfo::eYes, MemoryRegionInfo::eNo, - MemoryRegionInfo::eYes, ConstString("[foo]"), - MemoryRegionInfo::eDontKnow, 0, MemoryRegionInfo::eYes), - }, - ""), - // Whitespace ignored - std::make_tuple( - "0-0 rw-p 00000000 00:00 0\n" - "VmFlags: mt ", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0, 0), MemoryRegionInfo::eYes, - MemoryRegionInfo::eYes, MemoryRegionInfo::eNo, - MemoryRegionInfo::eYes, ConstString(nullptr), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eYes), - }, - ""), - // VmFlags line means it has flag info, but nothing is set - std::make_tuple( - "0-0 rw-p 00000000 00:00 0\n" - "VmFlags: ", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0, 0), MemoryRegionInfo::eYes, - MemoryRegionInfo::eYes, MemoryRegionInfo::eNo, - MemoryRegionInfo::eYes, ConstString(nullptr), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eNo), - }, - ""), - // Handle some pages not having a flags line - std::make_tuple( - "1111-2222 rw-p 00000000 00:00 0 [foo]\n" - "Referenced: 2188 kB\n" - "AnonHugePages: 0 kB\n" - "3333-4444 r-xp 00000000 00:00 0 [bar]\n" - "VmFlags: mt", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0x1111, 0x2222), - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - ConstString("[foo]"), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - MemoryRegionInfo( - make_range(0x3333, 0x4444), MemoryRegionInfo::eYes, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - MemoryRegionInfo::eYes, ConstString("[bar]"), - MemoryRegionInfo::eDontKnow, 0, MemoryRegionInfo::eYes), - }, - ""), - // Handle no pages having a flags line (older kernels) - std::make_tuple( - "1111-2222 rw-p 00000000 00:00 0\n" - "Referenced: 2188 kB\n" - "AnonHugePages: 0 kB\n" - "3333-4444 r-xp 00000000 00:00 0\n" - "KernelPageSize: 4 kB\n" - "MMUPageSize: 4 kB\n", - MemoryRegionInfos{ - MemoryRegionInfo(make_range(0x1111, 0x2222), - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - MemoryRegionInfo::eNo, MemoryRegionInfo::eYes, - ConstString(nullptr), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - MemoryRegionInfo(make_range(0x3333, 0x4444), - MemoryRegionInfo::eYes, MemoryRegionInfo::eNo, - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - ConstString(nullptr), - MemoryRegionInfo::eDontKnow, 0, - MemoryRegionInfo::eDontKnow), - }, - ""))); - -TEST_P(LinuxProcSMapsTestFixture, ParseSMapRegions) { - auto params = GetParam(); - ParseLinuxSMapRegions(std::get<0>(params), callback); - check_regions(params); -} diff --git a/gnu/llvm/lldb/unittests/Process/Utility/MemoryTagManagerAArch64MTETest.cpp b/gnu/llvm/lldb/unittests/Process/Utility/MemoryTagManagerAArch64MTETest.cpp deleted file mode 100644 index 128dac7a21c..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/MemoryTagManagerAArch64MTETest.cpp +++ /dev/null @@ -1,322 +0,0 @@ -//===-- MemoryTagManagerAArch64MTETest.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 "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(MemoryTagManagerAArch64MTETest, UnpackTagsData) { - MemoryTagManagerAArch64MTE manager; - - // Error for insufficient tag data - std::vector input; - ASSERT_THAT_EXPECTED( - manager.UnpackTagsData(input, 2), - llvm::FailedWithMessage( - "Packed tag data size does not match expected number of tags. " - "Expected 2 tag(s) for 2 granule(s), got 0 tag(s).")); - - // This is out of the valid tag range - input.push_back(0x1f); - ASSERT_THAT_EXPECTED( - manager.UnpackTagsData(input, 1), - llvm::FailedWithMessage( - "Found tag 0x1f which is > max MTE tag value of 0xf.")); - - // MTE tags are 1 per byte - input.pop_back(); - input.push_back(0xe); - input.push_back(0xf); - - std::vector expected{0xe, 0xf}; - - llvm::Expected> got = - manager.UnpackTagsData(input, 2); - ASSERT_THAT_EXPECTED(got, llvm::Succeeded()); - ASSERT_THAT(expected, testing::ContainerEq(*got)); - - // Error for too much tag data - ASSERT_THAT_EXPECTED( - manager.UnpackTagsData(input, 1), - llvm::FailedWithMessage( - "Packed tag data size does not match expected number of tags. " - "Expected 1 tag(s) for 1 granule(s), got 2 tag(s).")); - - // By default, we don't check number of tags - llvm::Expected> got_zero = - manager.UnpackTagsData(input); - ASSERT_THAT_EXPECTED(got_zero, llvm::Succeeded()); - ASSERT_THAT(expected, testing::ContainerEq(*got)); - - // Which is the same as granules=0 - got_zero = manager.UnpackTagsData(input, 0); - ASSERT_THAT_EXPECTED(got_zero, llvm::Succeeded()); - ASSERT_THAT(expected, testing::ContainerEq(*got)); -} - -TEST(MemoryTagManagerAArch64MTETest, PackTags) { - MemoryTagManagerAArch64MTE manager; - - // Error for tag out of range - llvm::Expected> invalid_tag_err = - manager.PackTags({0x10}); - ASSERT_THAT_EXPECTED( - invalid_tag_err, - llvm::FailedWithMessage( - "Found tag 0x10 which is > max MTE tag value of 0xf.")); - - // 0xf here is the max tag value that we can pack - std::vector tags{0, 1, 0xf}; - std::vector expected{0, 1, 0xf}; - llvm::Expected> packed = manager.PackTags(tags); - ASSERT_THAT_EXPECTED(packed, llvm::Succeeded()); - ASSERT_THAT(expected, testing::ContainerEq(*packed)); -} - -TEST(MemoryTagManagerAArch64MTETest, GetLogicalTag) { - MemoryTagManagerAArch64MTE manager; - - // Set surrounding bits to check shift is correct - ASSERT_EQ((lldb::addr_t)0, manager.GetLogicalTag(0xe0e00000ffffffff)); - // Max tag value - ASSERT_EQ((lldb::addr_t)0xf, manager.GetLogicalTag(0x0f000000ffffffff)); - ASSERT_EQ((lldb::addr_t)2, manager.GetLogicalTag(0x02000000ffffffff)); -} - -TEST(MemoryTagManagerAArch64MTETest, ExpandToGranule) { - MemoryTagManagerAArch64MTE manager; - // Reading nothing, no alignment needed - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(0, 0), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(0, 0))); - - // Ranges with 0 size are unchanged even if address is non 0 - // (normally 0x1234 would be aligned to 0x1230) - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(0x1234, 0), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(0x1234, 0))); - - // Ranges already aligned don't change - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(0x100, 64), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(0x100, 64))); - - // Any read of less than 1 granule is rounded up to reading 1 granule - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(0, 16), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(0, 1))); - - // Start address is aligned down, and length modified accordingly - // Here bytes 8 through 24 straddle 2 granules. So the resulting range starts - // at 0 and covers 32 bytes. - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(0, 32), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(8, 16))); - - // Here only the size of the range needs aligning - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(16, 32), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(16, 24))); - - // Start and size need aligning here but we only need 1 granule to cover it - ASSERT_EQ( - MemoryTagManagerAArch64MTE::TagRange(16, 16), - manager.ExpandToGranule(MemoryTagManagerAArch64MTE::TagRange(18, 4))); -} - -static MemoryRegionInfo MakeRegionInfo(lldb::addr_t base, lldb::addr_t size, - bool tagged) { - return MemoryRegionInfo( - MemoryRegionInfo::RangeType(base, size), MemoryRegionInfo::eYes, - MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, MemoryRegionInfo::eYes, - ConstString(), MemoryRegionInfo::eNo, 0, - /*memory_tagged=*/ - tagged ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); -} - -TEST(MemoryTagManagerAArch64MTETest, MakeTaggedRange) { - MemoryTagManagerAArch64MTE manager; - MemoryRegionInfos memory_regions; - - // No regions means no tagged regions, error - ASSERT_THAT_EXPECTED( - manager.MakeTaggedRange(0, 0x10, memory_regions), - llvm::FailedWithMessage( - "Address range 0x0:0x10 is not in a memory tagged region")); - - // Alignment is done before checking regions. - // Here 1 is rounded up to the granule size of 0x10. - ASSERT_THAT_EXPECTED( - manager.MakeTaggedRange(0, 1, memory_regions), - llvm::FailedWithMessage( - "Address range 0x0:0x10 is not in a memory tagged region")); - - // Range must not be inverted - ASSERT_THAT_EXPECTED( - manager.MakeTaggedRange(1, 0, memory_regions), - llvm::FailedWithMessage( - "End address (0x0) must be greater than the start address (0x1)")); - - // Adding a single region to cover the whole range - memory_regions.push_back(MakeRegionInfo(0, 0x1000, true)); - - // Range can have different tags for begin and end - // (which would make it look inverted if we didn't remove them) - // Note that range comes back with an untagged base and alginment - // applied. - MemoryTagManagerAArch64MTE::TagRange expected_range(0x0, 0x10); - llvm::Expected got = - manager.MakeTaggedRange(0x0f00000000000000, 0x0e00000000000001, - memory_regions); - ASSERT_THAT_EXPECTED(got, llvm::Succeeded()); - ASSERT_EQ(*got, expected_range); - - // Error if the range isn't within any region - ASSERT_THAT_EXPECTED( - manager.MakeTaggedRange(0x1000, 0x1010, memory_regions), - llvm::FailedWithMessage( - "Address range 0x1000:0x1010 is not in a memory tagged region")); - - // Error if the first part of a range isn't tagged - memory_regions.clear(); - const char *err_msg = - "Address range 0x0:0x1000 is not in a memory tagged region"; - - // First because it has no region entry - memory_regions.push_back(MakeRegionInfo(0x10, 0x1000, true)); - ASSERT_THAT_EXPECTED(manager.MakeTaggedRange(0, 0x1000, memory_regions), - llvm::FailedWithMessage(err_msg)); - - // Then because the first region is untagged - memory_regions.push_back(MakeRegionInfo(0, 0x10, false)); - ASSERT_THAT_EXPECTED(manager.MakeTaggedRange(0, 0x1000, memory_regions), - llvm::FailedWithMessage(err_msg)); - - // If we tag that first part it succeeds - memory_regions.back().SetMemoryTagged(MemoryRegionInfo::eYes); - expected_range = MemoryTagManagerAArch64MTE::TagRange(0x0, 0x1000); - got = manager.MakeTaggedRange(0, 0x1000, memory_regions); - ASSERT_THAT_EXPECTED(got, llvm::Succeeded()); - ASSERT_EQ(*got, expected_range); - - // Error if the end of a range is untagged - memory_regions.clear(); - - // First because it has no region entry - memory_regions.push_back(MakeRegionInfo(0, 0xF00, true)); - ASSERT_THAT_EXPECTED(manager.MakeTaggedRange(0, 0x1000, memory_regions), - llvm::FailedWithMessage(err_msg)); - - // Then because the last region is untagged - memory_regions.push_back(MakeRegionInfo(0xF00, 0x100, false)); - ASSERT_THAT_EXPECTED(manager.MakeTaggedRange(0, 0x1000, memory_regions), - llvm::FailedWithMessage(err_msg)); - - // If we tag the last part it succeeds - memory_regions.back().SetMemoryTagged(MemoryRegionInfo::eYes); - got = manager.MakeTaggedRange(0, 0x1000, memory_regions); - ASSERT_THAT_EXPECTED(got, llvm::Succeeded()); - ASSERT_EQ(*got, expected_range); - - // Error if the middle of a range is untagged - memory_regions.clear(); - - // First because it has no entry - memory_regions.push_back(MakeRegionInfo(0, 0x500, true)); - memory_regions.push_back(MakeRegionInfo(0x900, 0x700, true)); - ASSERT_THAT_EXPECTED(manager.MakeTaggedRange(0, 0x1000, memory_regions), - llvm::FailedWithMessage(err_msg)); - - // Then because it's untagged - memory_regions.push_back(MakeRegionInfo(0x500, 0x400, false)); - ASSERT_THAT_EXPECTED(manager.MakeTaggedRange(0, 0x1000, memory_regions), - llvm::FailedWithMessage(err_msg)); - - // If we tag the middle part it succeeds - memory_regions.back().SetMemoryTagged(MemoryRegionInfo::eYes); - got = manager.MakeTaggedRange(0, 0x1000, memory_regions); - ASSERT_THAT_EXPECTED(got, llvm::Succeeded()); - ASSERT_EQ(*got, expected_range); -} - -TEST(MemoryTagManagerAArch64MTETest, RemoveNonAddressBits) { - MemoryTagManagerAArch64MTE manager; - - ASSERT_EQ(0, 0); - ASSERT_EQ((lldb::addr_t)0x00ffeedd11223344, - manager.RemoveNonAddressBits(0x00ffeedd11223344)); - ASSERT_EQ((lldb::addr_t)0x0000000000000000, - manager.RemoveNonAddressBits(0xFF00000000000000)); - ASSERT_EQ((lldb::addr_t)0x0055555566666666, - manager.RemoveNonAddressBits(0xee55555566666666)); -} - -TEST(MemoryTagManagerAArch64MTETest, AddressDiff) { - MemoryTagManagerAArch64MTE manager; - - ASSERT_EQ(0, manager.AddressDiff(0, 0)); - // Result is signed - ASSERT_EQ(10, manager.AddressDiff(10, 0)); - ASSERT_EQ(-10, manager.AddressDiff(0, 10)); - // Anything in the top byte is ignored - ASSERT_EQ(0, manager.AddressDiff(0x2211222233334444, 0x3311222233334444)); - ASSERT_EQ(-32, manager.AddressDiff(0x5511222233334400, 0x4411222233334420)); - ASSERT_EQ(65, manager.AddressDiff(0x9911222233334441, 0x6611222233334400)); -} - -// Helper to check that repeating "tags" over "range" gives you -// "expected_tags". -static void -test_repeating_tags(const std::vector &tags, - MemoryTagManagerAArch64MTE::TagRange range, - const std::vector &expected_tags) { - MemoryTagManagerAArch64MTE manager; - llvm::Expected> tags_or_err = - manager.RepeatTagsForRange(tags, range); - ASSERT_THAT_EXPECTED(tags_or_err, llvm::Succeeded()); - ASSERT_THAT(expected_tags, testing::ContainerEq(*tags_or_err)); -} - -TEST(MemoryTagManagerAArch64MTETest, RepeatTagsForRange) { - MemoryTagManagerAArch64MTE manager; - - // Must have some tags if your range is not empty - llvm::Expected> no_tags_err = - manager.RepeatTagsForRange({}, - MemoryTagManagerAArch64MTE::TagRange{0, 16}); - ASSERT_THAT_EXPECTED( - no_tags_err, llvm::FailedWithMessage( - "Expected some tags to cover given range, got zero.")); - - // If the range is empty, you get no tags back - test_repeating_tags({1, 2, 3}, MemoryTagManagerAArch64MTE::TagRange{0, 0}, - {}); - // And you don't need tags for an empty range - test_repeating_tags({}, MemoryTagManagerAArch64MTE::TagRange{0, 0}, {}); - - // A single tag will just be multiplied as many times as needed - test_repeating_tags({5}, MemoryTagManagerAArch64MTE::TagRange{0, 16}, {5}); - test_repeating_tags({6}, MemoryTagManagerAArch64MTE::TagRange{0, 32}, {6, 6}); - - // If you've got as many tags as granules, it's a roundtrip - test_repeating_tags({7, 8}, MemoryTagManagerAArch64MTE::TagRange{0, 32}, - {7, 8}); - - // If you've got fewer tags than granules, they repeat. Exactly or partially - // as needed. - test_repeating_tags({7, 8}, MemoryTagManagerAArch64MTE::TagRange{0, 64}, - {7, 8, 7, 8}); - test_repeating_tags({7, 8}, MemoryTagManagerAArch64MTE::TagRange{0, 48}, - {7, 8, 7}); - - // If you've got more tags than granules you get back only those needed - test_repeating_tags({1, 2, 3, 4}, MemoryTagManagerAArch64MTE::TagRange{0, 32}, - {1, 2}); -} diff --git a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp b/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp deleted file mode 100644 index f14dc8faaea..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp +++ /dev/null @@ -1,553 +0,0 @@ -//===-- RegisterContextFreeBSDTests.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 -// -//===----------------------------------------------------------------------===// - -// clang-format off -#include -#include -#if defined(__arm__) -#include -#endif -// clang-format on - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" -#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" -#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" -#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" -#include "Plugins/Process/Utility/lldb-arm-register-enums.h" -#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" -#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h" -#include "Plugins/Process/Utility/lldb-x86-register-enums.h" - -using namespace lldb; -using namespace lldb_private; - -std::pair GetRegParams(RegisterInfoInterface &ctx, - uint32_t reg) { - const RegisterInfo &info = ctx.GetRegisterInfo()[reg]; - return {info.byte_offset, info.byte_size}; -} - -#define EXPECT_OFF(regname, offset, size) \ - EXPECT_THAT(GetRegParams(reg_ctx, lldb_##regname), \ - ::testing::Pair(offset + base_offset, size)) - -#if defined(__x86_64__) - -#define EXPECT_GPR_X86_64(regname) \ - EXPECT_THAT( \ - GetRegParams(reg_ctx, lldb_##regname##_x86_64), \ - ::testing::Pair(offsetof(reg, r_##regname), sizeof(reg::r_##regname))) -#define EXPECT_DBR_X86_64(num) \ - EXPECT_OFF(dr##num##_x86_64, offsetof(dbreg, dr[num]), sizeof(dbreg::dr[num])) - -TEST(RegisterContextFreeBSDTest, x86_64) { - ArchSpec arch{"x86_64-unknown-freebsd"}; - RegisterContextFreeBSD_x86_64 reg_ctx{arch}; - - EXPECT_GPR_X86_64(r15); - EXPECT_GPR_X86_64(r14); - EXPECT_GPR_X86_64(r13); - EXPECT_GPR_X86_64(r12); - EXPECT_GPR_X86_64(r11); - EXPECT_GPR_X86_64(r10); - EXPECT_GPR_X86_64(r9); - EXPECT_GPR_X86_64(r8); - EXPECT_GPR_X86_64(rdi); - EXPECT_GPR_X86_64(rsi); - EXPECT_GPR_X86_64(rbp); - EXPECT_GPR_X86_64(rbx); - EXPECT_GPR_X86_64(rdx); - EXPECT_GPR_X86_64(rcx); - EXPECT_GPR_X86_64(rax); - EXPECT_GPR_X86_64(fs); - EXPECT_GPR_X86_64(gs); - EXPECT_GPR_X86_64(es); - EXPECT_GPR_X86_64(ds); - EXPECT_GPR_X86_64(rip); - EXPECT_GPR_X86_64(cs); - EXPECT_GPR_X86_64(rflags); - EXPECT_GPR_X86_64(rsp); - EXPECT_GPR_X86_64(ss); - - // fctrl is the first FPR field, it is used to determine offset of the whole - // FPR struct - size_t base_offset = reg_ctx.GetRegisterInfo()[lldb_fctrl_x86_64].byte_offset; - - // assert against FXSAVE struct - EXPECT_OFF(fctrl_x86_64, 0x00, 2); - EXPECT_OFF(fstat_x86_64, 0x02, 2); - // TODO: This is a known bug, abridged ftag should is 8 bits in length. - EXPECT_OFF(ftag_x86_64, 0x04, 2); - EXPECT_OFF(fop_x86_64, 0x06, 2); - // NB: Technically fiseg/foseg are 16-bit long and the higher 16 bits - // are reserved. However, LLDB defines them to be 32-bit long for backwards - // compatibility, as they were used to reconstruct FIP/FDP before explicit - // register entries for them were added. Also, this is still how GDB does it. - EXPECT_OFF(fioff_x86_64, 0x08, 4); - EXPECT_OFF(fiseg_x86_64, 0x0C, 4); - EXPECT_OFF(fip_x86_64, 0x08, 8); - EXPECT_OFF(fooff_x86_64, 0x10, 4); - EXPECT_OFF(foseg_x86_64, 0x14, 4); - EXPECT_OFF(fdp_x86_64, 0x10, 8); - EXPECT_OFF(mxcsr_x86_64, 0x18, 4); - EXPECT_OFF(mxcsrmask_x86_64, 0x1C, 4); - EXPECT_OFF(st0_x86_64, 0x20, 10); - EXPECT_OFF(st1_x86_64, 0x30, 10); - EXPECT_OFF(st2_x86_64, 0x40, 10); - EXPECT_OFF(st3_x86_64, 0x50, 10); - EXPECT_OFF(st4_x86_64, 0x60, 10); - EXPECT_OFF(st5_x86_64, 0x70, 10); - EXPECT_OFF(st6_x86_64, 0x80, 10); - EXPECT_OFF(st7_x86_64, 0x90, 10); - EXPECT_OFF(mm0_x86_64, 0x20, 8); - EXPECT_OFF(mm1_x86_64, 0x30, 8); - EXPECT_OFF(mm2_x86_64, 0x40, 8); - EXPECT_OFF(mm3_x86_64, 0x50, 8); - EXPECT_OFF(mm4_x86_64, 0x60, 8); - EXPECT_OFF(mm5_x86_64, 0x70, 8); - EXPECT_OFF(mm6_x86_64, 0x80, 8); - EXPECT_OFF(mm7_x86_64, 0x90, 8); - EXPECT_OFF(xmm0_x86_64, 0xA0, 16); - EXPECT_OFF(xmm1_x86_64, 0xB0, 16); - EXPECT_OFF(xmm2_x86_64, 0xC0, 16); - EXPECT_OFF(xmm3_x86_64, 0xD0, 16); - EXPECT_OFF(xmm4_x86_64, 0xE0, 16); - EXPECT_OFF(xmm5_x86_64, 0xF0, 16); - EXPECT_OFF(xmm6_x86_64, 0x100, 16); - EXPECT_OFF(xmm7_x86_64, 0x110, 16); - EXPECT_OFF(xmm8_x86_64, 0x120, 16); - EXPECT_OFF(xmm9_x86_64, 0x130, 16); - EXPECT_OFF(xmm10_x86_64, 0x140, 16); - EXPECT_OFF(xmm11_x86_64, 0x150, 16); - EXPECT_OFF(xmm12_x86_64, 0x160, 16); - EXPECT_OFF(xmm13_x86_64, 0x170, 16); - EXPECT_OFF(xmm14_x86_64, 0x180, 16); - EXPECT_OFF(xmm15_x86_64, 0x190, 16); - - base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_x86_64].byte_offset; - EXPECT_DBR_X86_64(0); - EXPECT_DBR_X86_64(1); - EXPECT_DBR_X86_64(2); - EXPECT_DBR_X86_64(3); - EXPECT_DBR_X86_64(4); - EXPECT_DBR_X86_64(5); - EXPECT_DBR_X86_64(6); - EXPECT_DBR_X86_64(7); -} - -#endif // defined(__x86_64__) - -#if defined(__i386__) || defined(__x86_64__) - -#define EXPECT_GPR_I386(regname) \ - EXPECT_THAT(GetRegParams(reg_ctx, lldb_##regname##_i386), \ - ::testing::Pair(offsetof(native_i386_regs, r_##regname), \ - sizeof(native_i386_regs::r_##regname))) -#define EXPECT_DBR_I386(num) \ - EXPECT_OFF(dr##num##_i386, offsetof(native_i386_dbregs, dr[num]), \ - sizeof(native_i386_dbregs::dr[num])) - -TEST(RegisterContextFreeBSDTest, i386) { - ArchSpec arch{"i686-unknown-freebsd"}; - RegisterContextFreeBSD_i386 reg_ctx{arch}; - -#if defined(__i386__) - using native_i386_regs = ::reg; - using native_i386_dbregs = ::dbreg; -#else - using native_i386_regs = ::reg32; - using native_i386_dbregs = ::dbreg32; -#endif - - EXPECT_GPR_I386(fs); - EXPECT_GPR_I386(es); - EXPECT_GPR_I386(ds); - EXPECT_GPR_I386(edi); - EXPECT_GPR_I386(esi); - EXPECT_GPR_I386(ebp); - EXPECT_GPR_I386(ebx); - EXPECT_GPR_I386(edx); - EXPECT_GPR_I386(ecx); - EXPECT_GPR_I386(eax); - EXPECT_GPR_I386(eip); - EXPECT_GPR_I386(cs); - EXPECT_GPR_I386(eflags); - EXPECT_GPR_I386(esp); - EXPECT_GPR_I386(ss); - EXPECT_GPR_I386(gs); - - // fctrl is the first FPR field, it is used to determine offset of the whole - // FPR struct - size_t base_offset = reg_ctx.GetRegisterInfo()[lldb_fctrl_i386].byte_offset; - - // assert against FXSAVE struct - EXPECT_OFF(fctrl_i386, 0x00, 2); - EXPECT_OFF(fstat_i386, 0x02, 2); - // TODO: This is a known bug, abridged ftag should is 8 bits in length. - EXPECT_OFF(ftag_i386, 0x04, 2); - EXPECT_OFF(fop_i386, 0x06, 2); - // NB: Technically fiseg/foseg are 16-bit long and the higher 16 bits - // are reserved. However, we use them to access/recombine 64-bit FIP/FDP. - EXPECT_OFF(fioff_i386, 0x08, 4); - EXPECT_OFF(fiseg_i386, 0x0C, 4); - EXPECT_OFF(fooff_i386, 0x10, 4); - EXPECT_OFF(foseg_i386, 0x14, 4); - EXPECT_OFF(mxcsr_i386, 0x18, 4); - EXPECT_OFF(mxcsrmask_i386, 0x1C, 4); - EXPECT_OFF(st0_i386, 0x20, 10); - EXPECT_OFF(st1_i386, 0x30, 10); - EXPECT_OFF(st2_i386, 0x40, 10); - EXPECT_OFF(st3_i386, 0x50, 10); - EXPECT_OFF(st4_i386, 0x60, 10); - EXPECT_OFF(st5_i386, 0x70, 10); - EXPECT_OFF(st6_i386, 0x80, 10); - EXPECT_OFF(st7_i386, 0x90, 10); - EXPECT_OFF(mm0_i386, 0x20, 8); - EXPECT_OFF(mm1_i386, 0x30, 8); - EXPECT_OFF(mm2_i386, 0x40, 8); - EXPECT_OFF(mm3_i386, 0x50, 8); - EXPECT_OFF(mm4_i386, 0x60, 8); - EXPECT_OFF(mm5_i386, 0x70, 8); - EXPECT_OFF(mm6_i386, 0x80, 8); - EXPECT_OFF(mm7_i386, 0x90, 8); - EXPECT_OFF(xmm0_i386, 0xA0, 16); - EXPECT_OFF(xmm1_i386, 0xB0, 16); - EXPECT_OFF(xmm2_i386, 0xC0, 16); - EXPECT_OFF(xmm3_i386, 0xD0, 16); - EXPECT_OFF(xmm4_i386, 0xE0, 16); - EXPECT_OFF(xmm5_i386, 0xF0, 16); - EXPECT_OFF(xmm6_i386, 0x100, 16); - EXPECT_OFF(xmm7_i386, 0x110, 16); - - base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_i386].byte_offset; - EXPECT_DBR_I386(0); - EXPECT_DBR_I386(1); - EXPECT_DBR_I386(2); - EXPECT_DBR_I386(3); - EXPECT_DBR_I386(4); - EXPECT_DBR_I386(5); - EXPECT_DBR_I386(6); - EXPECT_DBR_I386(7); -} - -#endif // defined(__i386__) || defined(__x86_64__) - -#if defined(__arm__) - -#define EXPECT_GPR_ARM(lldb_reg, fbsd_reg) \ - EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_arm), \ - ::testing::Pair(offsetof(reg, fbsd_reg), sizeof(reg::fbsd_reg))) -#define EXPECT_FPU_ARM(lldb_reg, fbsd_reg) \ - EXPECT_THAT(GetRegParams(reg_ctx, fpu_##lldb_reg##_arm), \ - ::testing::Pair(offsetof(vfp_state, fbsd_reg) + base_offset, \ - sizeof(vfp_state::fbsd_reg))) - -TEST(RegisterContextFreeBSDTest, arm) { - ArchSpec arch{"arm-unknown-freebsd"}; - RegisterInfoPOSIX_arm reg_ctx{arch}; - - EXPECT_GPR_ARM(r0, r[0]); - EXPECT_GPR_ARM(r1, r[1]); - EXPECT_GPR_ARM(r2, r[2]); - EXPECT_GPR_ARM(r3, r[3]); - EXPECT_GPR_ARM(r4, r[4]); - EXPECT_GPR_ARM(r5, r[5]); - EXPECT_GPR_ARM(r6, r[6]); - EXPECT_GPR_ARM(r7, r[7]); - EXPECT_GPR_ARM(r8, r[8]); - EXPECT_GPR_ARM(r9, r[9]); - EXPECT_GPR_ARM(r10, r[10]); - EXPECT_GPR_ARM(r11, r[11]); - EXPECT_GPR_ARM(r12, r[12]); - EXPECT_GPR_ARM(sp, r_sp); - EXPECT_GPR_ARM(lr, r_lr); - EXPECT_GPR_ARM(pc, r_pc); - EXPECT_GPR_ARM(cpsr, r_cpsr); - - size_t base_offset = reg_ctx.GetRegisterInfo()[fpu_d0_arm].byte_offset; - - EXPECT_FPU_ARM(d0, reg[0]); - EXPECT_FPU_ARM(d1, reg[1]); - EXPECT_FPU_ARM(d2, reg[2]); - EXPECT_FPU_ARM(d3, reg[3]); - EXPECT_FPU_ARM(d4, reg[4]); - EXPECT_FPU_ARM(d5, reg[5]); - EXPECT_FPU_ARM(d6, reg[6]); - EXPECT_FPU_ARM(d7, reg[7]); - EXPECT_FPU_ARM(d8, reg[8]); - EXPECT_FPU_ARM(d9, reg[9]); - EXPECT_FPU_ARM(d10, reg[10]); - EXPECT_FPU_ARM(d11, reg[11]); - EXPECT_FPU_ARM(d12, reg[12]); - EXPECT_FPU_ARM(d13, reg[13]); - EXPECT_FPU_ARM(d14, reg[14]); - EXPECT_FPU_ARM(d15, reg[15]); - EXPECT_FPU_ARM(d16, reg[16]); - EXPECT_FPU_ARM(d17, reg[17]); - EXPECT_FPU_ARM(d18, reg[18]); - EXPECT_FPU_ARM(d19, reg[19]); - EXPECT_FPU_ARM(d20, reg[20]); - EXPECT_FPU_ARM(d21, reg[21]); - EXPECT_FPU_ARM(d22, reg[22]); - EXPECT_FPU_ARM(d23, reg[23]); - EXPECT_FPU_ARM(d24, reg[24]); - EXPECT_FPU_ARM(d25, reg[25]); - EXPECT_FPU_ARM(d26, reg[26]); - EXPECT_FPU_ARM(d27, reg[27]); - EXPECT_FPU_ARM(d28, reg[28]); - EXPECT_FPU_ARM(d29, reg[29]); - EXPECT_FPU_ARM(d30, reg[30]); - EXPECT_FPU_ARM(d31, reg[31]); - EXPECT_FPU_ARM(fpscr, fpscr); -} - -#endif // defined(__arm__) - -#if defined(__aarch64__) - -#define EXPECT_GPR_ARM64(lldb_reg, fbsd_reg) \ - EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_arm64), \ - ::testing::Pair(offsetof(reg, fbsd_reg), sizeof(reg::fbsd_reg))) -#define EXPECT_FPU_ARM64(lldb_reg, fbsd_reg) \ - EXPECT_THAT(GetRegParams(reg_ctx, fpu_##lldb_reg##_arm64), \ - ::testing::Pair(offsetof(fpreg, fbsd_reg) + base_offset, \ - sizeof(fpreg::fbsd_reg))) - -TEST(RegisterContextFreeBSDTest, arm64) { - ArchSpec arch{"aarch64-unknown-freebsd"}; - RegisterInfoPOSIX_arm64 reg_ctx{arch}; - - EXPECT_GPR_ARM64(x0, x[0]); - EXPECT_GPR_ARM64(x1, x[1]); - EXPECT_GPR_ARM64(x2, x[2]); - EXPECT_GPR_ARM64(x3, x[3]); - EXPECT_GPR_ARM64(x4, x[4]); - EXPECT_GPR_ARM64(x5, x[5]); - EXPECT_GPR_ARM64(x6, x[6]); - EXPECT_GPR_ARM64(x7, x[7]); - EXPECT_GPR_ARM64(x8, x[8]); - EXPECT_GPR_ARM64(x9, x[9]); - EXPECT_GPR_ARM64(x10, x[10]); - EXPECT_GPR_ARM64(x11, x[11]); - EXPECT_GPR_ARM64(x12, x[12]); - EXPECT_GPR_ARM64(x13, x[13]); - EXPECT_GPR_ARM64(x14, x[14]); - EXPECT_GPR_ARM64(x15, x[15]); - EXPECT_GPR_ARM64(x16, x[16]); - EXPECT_GPR_ARM64(x17, x[17]); - EXPECT_GPR_ARM64(x18, x[18]); - EXPECT_GPR_ARM64(x19, x[19]); - EXPECT_GPR_ARM64(x20, x[20]); - EXPECT_GPR_ARM64(x21, x[21]); - EXPECT_GPR_ARM64(x22, x[22]); - EXPECT_GPR_ARM64(x23, x[23]); - EXPECT_GPR_ARM64(x24, x[24]); - EXPECT_GPR_ARM64(x25, x[25]); - EXPECT_GPR_ARM64(x26, x[26]); - EXPECT_GPR_ARM64(x27, x[27]); - EXPECT_GPR_ARM64(x28, x[28]); - EXPECT_GPR_ARM64(fp, x[29]); - EXPECT_GPR_ARM64(lr, lr); - EXPECT_GPR_ARM64(sp, sp); - EXPECT_GPR_ARM64(pc, elr); - EXPECT_GPR_ARM64(cpsr, spsr); - - size_t base_offset = reg_ctx.GetRegisterInfo()[fpu_v0_arm64].byte_offset; - - EXPECT_FPU_ARM64(v0, fp_q[0]); - EXPECT_FPU_ARM64(v1, fp_q[1]); - EXPECT_FPU_ARM64(v2, fp_q[2]); - EXPECT_FPU_ARM64(v3, fp_q[3]); - EXPECT_FPU_ARM64(v4, fp_q[4]); - EXPECT_FPU_ARM64(v5, fp_q[5]); - EXPECT_FPU_ARM64(v6, fp_q[6]); - EXPECT_FPU_ARM64(v7, fp_q[7]); - EXPECT_FPU_ARM64(v8, fp_q[8]); - EXPECT_FPU_ARM64(v9, fp_q[9]); - EXPECT_FPU_ARM64(v10, fp_q[10]); - EXPECT_FPU_ARM64(v11, fp_q[11]); - EXPECT_FPU_ARM64(v12, fp_q[12]); - EXPECT_FPU_ARM64(v13, fp_q[13]); - EXPECT_FPU_ARM64(v14, fp_q[14]); - EXPECT_FPU_ARM64(v15, fp_q[15]); - EXPECT_FPU_ARM64(v16, fp_q[16]); - EXPECT_FPU_ARM64(v17, fp_q[17]); - EXPECT_FPU_ARM64(v18, fp_q[18]); - EXPECT_FPU_ARM64(v19, fp_q[19]); - EXPECT_FPU_ARM64(v20, fp_q[20]); - EXPECT_FPU_ARM64(v21, fp_q[21]); - EXPECT_FPU_ARM64(v22, fp_q[22]); - EXPECT_FPU_ARM64(v23, fp_q[23]); - EXPECT_FPU_ARM64(v24, fp_q[24]); - EXPECT_FPU_ARM64(v25, fp_q[25]); - EXPECT_FPU_ARM64(v26, fp_q[26]); - EXPECT_FPU_ARM64(v27, fp_q[27]); - EXPECT_FPU_ARM64(v28, fp_q[28]); - EXPECT_FPU_ARM64(v29, fp_q[29]); - EXPECT_FPU_ARM64(v30, fp_q[30]); - EXPECT_FPU_ARM64(v31, fp_q[31]); - EXPECT_FPU_ARM64(fpsr, fp_sr); - EXPECT_FPU_ARM64(fpcr, fp_cr); -} - -#endif // defined(__aarch64__) - -#if defined(__mips64__) - -#define EXPECT_GPR_MIPS64(lldb_reg, fbsd_regno) \ - EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_mips64), \ - ::testing::Pair(offsetof(reg, r_regs[fbsd_regno]), \ - sizeof(reg::r_regs[fbsd_regno]))) - -TEST(RegisterContextFreeBSDTest, mips64) { - ArchSpec arch{"mips64-unknown-freebsd"}; - RegisterContextFreeBSD_mips64 reg_ctx{arch}; - - // we can not use aliases from because macros defined - // there are not namespaced and collide a lot, e.g. 'A1' - - EXPECT_GPR_MIPS64(zero, 0); - EXPECT_GPR_MIPS64(r1, 1); - EXPECT_GPR_MIPS64(r2, 2); - EXPECT_GPR_MIPS64(r3, 3); - EXPECT_GPR_MIPS64(r4, 4); - EXPECT_GPR_MIPS64(r5, 5); - EXPECT_GPR_MIPS64(r6, 6); - EXPECT_GPR_MIPS64(r7, 7); - EXPECT_GPR_MIPS64(r8, 8); - EXPECT_GPR_MIPS64(r9, 9); - EXPECT_GPR_MIPS64(r10, 10); - EXPECT_GPR_MIPS64(r11, 11); - EXPECT_GPR_MIPS64(r12, 12); - EXPECT_GPR_MIPS64(r13, 13); - EXPECT_GPR_MIPS64(r14, 14); - EXPECT_GPR_MIPS64(r15, 15); - EXPECT_GPR_MIPS64(r16, 16); - EXPECT_GPR_MIPS64(r17, 17); - EXPECT_GPR_MIPS64(r18, 18); - EXPECT_GPR_MIPS64(r19, 19); - EXPECT_GPR_MIPS64(r20, 20); - EXPECT_GPR_MIPS64(r21, 21); - EXPECT_GPR_MIPS64(r22, 22); - EXPECT_GPR_MIPS64(r23, 23); - EXPECT_GPR_MIPS64(r24, 24); - EXPECT_GPR_MIPS64(r25, 25); - EXPECT_GPR_MIPS64(r26, 26); - EXPECT_GPR_MIPS64(r27, 27); - EXPECT_GPR_MIPS64(gp, 28); - EXPECT_GPR_MIPS64(sp, 29); - EXPECT_GPR_MIPS64(r30, 30); - EXPECT_GPR_MIPS64(ra, 31); - EXPECT_GPR_MIPS64(sr, 32); - EXPECT_GPR_MIPS64(mullo, 33); - EXPECT_GPR_MIPS64(mulhi, 34); - EXPECT_GPR_MIPS64(badvaddr, 35); - EXPECT_GPR_MIPS64(cause, 36); - EXPECT_GPR_MIPS64(pc, 37); - EXPECT_GPR_MIPS64(ic, 38); - EXPECT_GPR_MIPS64(dummy, 39); -} - -#endif // defined(__mips64__) - -#if defined(__powerpc__) - -#define EXPECT_GPR_PPC(lldb_reg, fbsd_reg) \ - EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_powerpc), \ - ::testing::Pair(offsetof(reg, fbsd_reg), sizeof(reg::fbsd_reg))) -#define EXPECT_FPU_PPC(lldb_reg, fbsd_reg) \ - EXPECT_THAT(GetRegParams(reg_ctx, fpr_##lldb_reg##_powerpc), \ - ::testing::Pair(offsetof(fpreg, fbsd_reg) + base_offset, \ - sizeof(fpreg::fbsd_reg))) - -TEST(RegisterContextFreeBSDTest, powerpc32) { - ArchSpec arch{"powerpc-unknown-freebsd"}; - RegisterContextFreeBSD_powerpc32 reg_ctx{arch}; - - EXPECT_GPR_PPC(r0, fixreg[0]); - EXPECT_GPR_PPC(r1, fixreg[1]); - EXPECT_GPR_PPC(r2, fixreg[2]); - EXPECT_GPR_PPC(r3, fixreg[3]); - EXPECT_GPR_PPC(r4, fixreg[4]); - EXPECT_GPR_PPC(r5, fixreg[5]); - EXPECT_GPR_PPC(r6, fixreg[6]); - EXPECT_GPR_PPC(r7, fixreg[7]); - EXPECT_GPR_PPC(r8, fixreg[8]); - EXPECT_GPR_PPC(r9, fixreg[9]); - EXPECT_GPR_PPC(r10, fixreg[10]); - EXPECT_GPR_PPC(r11, fixreg[11]); - EXPECT_GPR_PPC(r12, fixreg[12]); - EXPECT_GPR_PPC(r13, fixreg[13]); - EXPECT_GPR_PPC(r14, fixreg[14]); - EXPECT_GPR_PPC(r15, fixreg[15]); - EXPECT_GPR_PPC(r16, fixreg[16]); - EXPECT_GPR_PPC(r17, fixreg[17]); - EXPECT_GPR_PPC(r18, fixreg[18]); - EXPECT_GPR_PPC(r19, fixreg[19]); - EXPECT_GPR_PPC(r20, fixreg[20]); - EXPECT_GPR_PPC(r21, fixreg[21]); - EXPECT_GPR_PPC(r22, fixreg[22]); - EXPECT_GPR_PPC(r23, fixreg[23]); - EXPECT_GPR_PPC(r24, fixreg[24]); - EXPECT_GPR_PPC(r25, fixreg[25]); - EXPECT_GPR_PPC(r26, fixreg[26]); - EXPECT_GPR_PPC(r27, fixreg[27]); - EXPECT_GPR_PPC(r28, fixreg[28]); - EXPECT_GPR_PPC(r29, fixreg[29]); - EXPECT_GPR_PPC(r30, fixreg[30]); - EXPECT_GPR_PPC(r31, fixreg[31]); - EXPECT_GPR_PPC(lr, lr); - EXPECT_GPR_PPC(cr, cr); - EXPECT_GPR_PPC(xer, xer); - EXPECT_GPR_PPC(ctr, ctr); - EXPECT_GPR_PPC(pc, pc); - - size_t base_offset = reg_ctx.GetRegisterInfo()[fpr_f0_powerpc].byte_offset; - - EXPECT_FPU_PPC(f0, fpreg[0]); - EXPECT_FPU_PPC(f1, fpreg[1]); - EXPECT_FPU_PPC(f2, fpreg[2]); - EXPECT_FPU_PPC(f3, fpreg[3]); - EXPECT_FPU_PPC(f4, fpreg[4]); - EXPECT_FPU_PPC(f5, fpreg[5]); - EXPECT_FPU_PPC(f6, fpreg[6]); - EXPECT_FPU_PPC(f7, fpreg[7]); - EXPECT_FPU_PPC(f8, fpreg[8]); - EXPECT_FPU_PPC(f9, fpreg[9]); - EXPECT_FPU_PPC(f10, fpreg[10]); - EXPECT_FPU_PPC(f11, fpreg[11]); - EXPECT_FPU_PPC(f12, fpreg[12]); - EXPECT_FPU_PPC(f13, fpreg[13]); - EXPECT_FPU_PPC(f14, fpreg[14]); - EXPECT_FPU_PPC(f15, fpreg[15]); - EXPECT_FPU_PPC(f16, fpreg[16]); - EXPECT_FPU_PPC(f17, fpreg[17]); - EXPECT_FPU_PPC(f18, fpreg[18]); - EXPECT_FPU_PPC(f19, fpreg[19]); - EXPECT_FPU_PPC(f20, fpreg[20]); - EXPECT_FPU_PPC(f21, fpreg[21]); - EXPECT_FPU_PPC(f22, fpreg[22]); - EXPECT_FPU_PPC(f23, fpreg[23]); - EXPECT_FPU_PPC(f24, fpreg[24]); - EXPECT_FPU_PPC(f25, fpreg[25]); - EXPECT_FPU_PPC(f26, fpreg[26]); - EXPECT_FPU_PPC(f27, fpreg[27]); - EXPECT_FPU_PPC(f28, fpreg[28]); - EXPECT_FPU_PPC(f29, fpreg[29]); - EXPECT_FPU_PPC(f30, fpreg[30]); - EXPECT_FPU_PPC(f31, fpreg[31]); - EXPECT_FPU_PPC(fpscr, fpscr); -} - -#endif // defined(__powerpc__) diff --git a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextNetBSDTest_i386.cpp b/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextNetBSDTest_i386.cpp deleted file mode 100644 index 07e09d34d19..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextNetBSDTest_i386.cpp +++ /dev/null @@ -1,118 +0,0 @@ -//===-- RegisterContextNetBSDTest_i386.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 -// -//===----------------------------------------------------------------------===// - -#if defined(__i386__) || defined(__x86_64__) - -// clang-format off -#include -#include -// clang-format on - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "Plugins/Process/Utility/lldb-x86-register-enums.h" -#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" - -using namespace lldb; -using namespace lldb_private; - -static std::pair GetRegParams(RegisterInfoInterface &ctx, - uint32_t reg) { - const RegisterInfo &info = ctx.GetRegisterInfo()[reg]; - return {info.byte_offset, info.byte_size}; -} - -#define EXPECT_OFF(regname, offset, size) \ - EXPECT_THAT(GetRegParams(reg_ctx, lldb_##regname), \ - ::testing::Pair(offset + base_offset, size)) - -#define EXPECT_GPR_I386(regname) \ - EXPECT_THAT(GetRegParams(reg_ctx, lldb_##regname##_i386), \ - ::testing::Pair(offsetof(reg, r_##regname), \ - sizeof(reg::r_##regname))) -#define EXPECT_DBR_I386(num) \ - EXPECT_OFF(dr##num##_i386, offsetof(dbreg, dr[num]), \ - sizeof(dbreg::dr[num])) - -TEST(RegisterContextNetBSDTest, i386) { - ArchSpec arch{"i686-unknown-netbsd"}; - RegisterContextNetBSD_i386 reg_ctx{arch}; - - EXPECT_GPR_I386(eax); - EXPECT_GPR_I386(ecx); - EXPECT_GPR_I386(edx); - EXPECT_GPR_I386(ebx); - EXPECT_GPR_I386(esp); - EXPECT_GPR_I386(ebp); - EXPECT_GPR_I386(esi); - EXPECT_GPR_I386(edi); - EXPECT_GPR_I386(eip); - EXPECT_GPR_I386(eflags); - EXPECT_GPR_I386(cs); - EXPECT_GPR_I386(ss); - EXPECT_GPR_I386(ds); - EXPECT_GPR_I386(es); - EXPECT_GPR_I386(fs); - EXPECT_GPR_I386(gs); - - // fctrl is the first FPR field, it is used to determine offset of the whole - // FPR struct - size_t base_offset = reg_ctx.GetRegisterInfo()[lldb_fctrl_i386].byte_offset; - - // assert against FXSAVE struct - EXPECT_OFF(fctrl_i386, 0x00, 2); - EXPECT_OFF(fstat_i386, 0x02, 2); - // TODO: This is a known bug, abridged ftag should is 8 bits in length. - EXPECT_OFF(ftag_i386, 0x04, 2); - EXPECT_OFF(fop_i386, 0x06, 2); - // NB: Technically fiseg/foseg are 16-bit long and the higher 16 bits - // are reserved. However, we use them to access/recombine 64-bit FIP/FDP. - EXPECT_OFF(fioff_i386, 0x08, 4); - EXPECT_OFF(fiseg_i386, 0x0C, 4); - EXPECT_OFF(fooff_i386, 0x10, 4); - EXPECT_OFF(foseg_i386, 0x14, 4); - EXPECT_OFF(mxcsr_i386, 0x18, 4); - EXPECT_OFF(mxcsrmask_i386, 0x1C, 4); - EXPECT_OFF(st0_i386, 0x20, 10); - EXPECT_OFF(st1_i386, 0x30, 10); - EXPECT_OFF(st2_i386, 0x40, 10); - EXPECT_OFF(st3_i386, 0x50, 10); - EXPECT_OFF(st4_i386, 0x60, 10); - EXPECT_OFF(st5_i386, 0x70, 10); - EXPECT_OFF(st6_i386, 0x80, 10); - EXPECT_OFF(st7_i386, 0x90, 10); - EXPECT_OFF(mm0_i386, 0x20, 8); - EXPECT_OFF(mm1_i386, 0x30, 8); - EXPECT_OFF(mm2_i386, 0x40, 8); - EXPECT_OFF(mm3_i386, 0x50, 8); - EXPECT_OFF(mm4_i386, 0x60, 8); - EXPECT_OFF(mm5_i386, 0x70, 8); - EXPECT_OFF(mm6_i386, 0x80, 8); - EXPECT_OFF(mm7_i386, 0x90, 8); - EXPECT_OFF(xmm0_i386, 0xA0, 16); - EXPECT_OFF(xmm1_i386, 0xB0, 16); - EXPECT_OFF(xmm2_i386, 0xC0, 16); - EXPECT_OFF(xmm3_i386, 0xD0, 16); - EXPECT_OFF(xmm4_i386, 0xE0, 16); - EXPECT_OFF(xmm5_i386, 0xF0, 16); - EXPECT_OFF(xmm6_i386, 0x100, 16); - EXPECT_OFF(xmm7_i386, 0x110, 16); - - base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_i386].byte_offset; - EXPECT_DBR_I386(0); - EXPECT_DBR_I386(1); - EXPECT_DBR_I386(2); - EXPECT_DBR_I386(3); - EXPECT_DBR_I386(4); - EXPECT_DBR_I386(5); - EXPECT_DBR_I386(6); - EXPECT_DBR_I386(7); -} - -#endif // defined(__i386__) || defined(__x86_64__) diff --git a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextNetBSDTest_x86_64.cpp b/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextNetBSDTest_x86_64.cpp deleted file mode 100644 index ac24c32b0d0..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextNetBSDTest_x86_64.cpp +++ /dev/null @@ -1,139 +0,0 @@ -//===-- RegisterContextNetBSDTest_x86_64.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 -// -//===----------------------------------------------------------------------===// - -#if defined(__x86_64__) - -// clang-format off -#include -#include -// clang-format on - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "Plugins/Process/Utility/lldb-x86-register-enums.h" -#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" -#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" - -using namespace lldb; -using namespace lldb_private; - -static std::pair GetRegParams(RegisterInfoInterface &ctx, - uint32_t reg) { - const RegisterInfo &info = ctx.GetRegisterInfo()[reg]; - return {info.byte_offset, info.byte_size}; -} - -#define EXPECT_OFF(regname, offset, size) \ - EXPECT_THAT(GetRegParams(reg_ctx, lldb_##regname), \ - ::testing::Pair(offset + base_offset, size)) - -#define EXPECT_GPR_X86_64(regname, regconst) \ - EXPECT_THAT( \ - GetRegParams(reg_ctx, lldb_##regname##_x86_64), \ - ::testing::Pair(offsetof(reg, regs[regconst]), \ - sizeof(reg::regs[regconst]))) -#define EXPECT_DBR_X86_64(num) \ - EXPECT_OFF(dr##num##_x86_64, offsetof(dbreg, dr[num]), sizeof(dbreg::dr[num])) - -TEST(RegisterContextNetBSDTest, x86_64) { - ArchSpec arch{"x86_64-unknown-netbsd"}; - RegisterContextNetBSD_x86_64 reg_ctx{arch}; - - EXPECT_GPR_X86_64(rdi, _REG_RDI); - EXPECT_GPR_X86_64(rsi, _REG_RSI); - EXPECT_GPR_X86_64(rdx, _REG_RDX); - EXPECT_GPR_X86_64(rcx, _REG_RCX); - EXPECT_GPR_X86_64(r8, _REG_R8); - EXPECT_GPR_X86_64(r9, _REG_R9); - EXPECT_GPR_X86_64(r10, _REG_R10); - EXPECT_GPR_X86_64(r11, _REG_R11); - EXPECT_GPR_X86_64(r12, _REG_R12); - EXPECT_GPR_X86_64(r13, _REG_R13); - EXPECT_GPR_X86_64(r14, _REG_R14); - EXPECT_GPR_X86_64(r15, _REG_R15); - EXPECT_GPR_X86_64(rbp, _REG_RBP); - EXPECT_GPR_X86_64(rbx, _REG_RBX); - EXPECT_GPR_X86_64(rax, _REG_RAX); - EXPECT_GPR_X86_64(gs, _REG_GS); - EXPECT_GPR_X86_64(fs, _REG_FS); - EXPECT_GPR_X86_64(es, _REG_ES); - EXPECT_GPR_X86_64(ds, _REG_DS); - EXPECT_GPR_X86_64(rip, _REG_RIP); - EXPECT_GPR_X86_64(cs, _REG_CS); - EXPECT_GPR_X86_64(rflags, _REG_RFLAGS); - EXPECT_GPR_X86_64(rsp, _REG_RSP); - EXPECT_GPR_X86_64(ss, _REG_SS); - - // fctrl is the first FPR field, it is used to determine offset of the whole - // FPR struct - size_t base_offset = reg_ctx.GetRegisterInfo()[lldb_fctrl_x86_64].byte_offset; - - // assert against FXSAVE struct - EXPECT_OFF(fctrl_x86_64, 0x00, 2); - EXPECT_OFF(fstat_x86_64, 0x02, 2); - // TODO: This is a known bug, abridged ftag should is 8 bits in length. - EXPECT_OFF(ftag_x86_64, 0x04, 2); - EXPECT_OFF(fop_x86_64, 0x06, 2); - // NB: Technically fiseg/foseg are 16-bit long and the higher 16 bits - // are reserved. However, LLDB defines them to be 32-bit long for backwards - // compatibility, as they were used to reconstruct FIP/FDP before explicit - // register entries for them were added. Also, this is still how GDB does it. - EXPECT_OFF(fioff_x86_64, 0x08, 4); - EXPECT_OFF(fiseg_x86_64, 0x0C, 4); - EXPECT_OFF(fip_x86_64, 0x08, 8); - EXPECT_OFF(fooff_x86_64, 0x10, 4); - EXPECT_OFF(foseg_x86_64, 0x14, 4); - EXPECT_OFF(fdp_x86_64, 0x10, 8); - EXPECT_OFF(mxcsr_x86_64, 0x18, 4); - EXPECT_OFF(mxcsrmask_x86_64, 0x1C, 4); - EXPECT_OFF(st0_x86_64, 0x20, 10); - EXPECT_OFF(st1_x86_64, 0x30, 10); - EXPECT_OFF(st2_x86_64, 0x40, 10); - EXPECT_OFF(st3_x86_64, 0x50, 10); - EXPECT_OFF(st4_x86_64, 0x60, 10); - EXPECT_OFF(st5_x86_64, 0x70, 10); - EXPECT_OFF(st6_x86_64, 0x80, 10); - EXPECT_OFF(st7_x86_64, 0x90, 10); - EXPECT_OFF(mm0_x86_64, 0x20, 8); - EXPECT_OFF(mm1_x86_64, 0x30, 8); - EXPECT_OFF(mm2_x86_64, 0x40, 8); - EXPECT_OFF(mm3_x86_64, 0x50, 8); - EXPECT_OFF(mm4_x86_64, 0x60, 8); - EXPECT_OFF(mm5_x86_64, 0x70, 8); - EXPECT_OFF(mm6_x86_64, 0x80, 8); - EXPECT_OFF(mm7_x86_64, 0x90, 8); - EXPECT_OFF(xmm0_x86_64, 0xA0, 16); - EXPECT_OFF(xmm1_x86_64, 0xB0, 16); - EXPECT_OFF(xmm2_x86_64, 0xC0, 16); - EXPECT_OFF(xmm3_x86_64, 0xD0, 16); - EXPECT_OFF(xmm4_x86_64, 0xE0, 16); - EXPECT_OFF(xmm5_x86_64, 0xF0, 16); - EXPECT_OFF(xmm6_x86_64, 0x100, 16); - EXPECT_OFF(xmm7_x86_64, 0x110, 16); - EXPECT_OFF(xmm8_x86_64, 0x120, 16); - EXPECT_OFF(xmm9_x86_64, 0x130, 16); - EXPECT_OFF(xmm10_x86_64, 0x140, 16); - EXPECT_OFF(xmm11_x86_64, 0x150, 16); - EXPECT_OFF(xmm12_x86_64, 0x160, 16); - EXPECT_OFF(xmm13_x86_64, 0x170, 16); - EXPECT_OFF(xmm14_x86_64, 0x180, 16); - EXPECT_OFF(xmm15_x86_64, 0x190, 16); - - base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_x86_64].byte_offset; - EXPECT_DBR_X86_64(0); - EXPECT_DBR_X86_64(1); - EXPECT_DBR_X86_64(2); - EXPECT_DBR_X86_64(3); - EXPECT_DBR_X86_64(4); - EXPECT_DBR_X86_64(5); - EXPECT_DBR_X86_64(6); - EXPECT_DBR_X86_64(7); -} - -#endif // defined(__x86_64__) diff --git a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextTest.cpp b/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextTest.cpp deleted file mode 100644 index f0aa6076d8f..00000000000 --- a/gnu/llvm/lldb/unittests/Process/Utility/RegisterContextTest.cpp +++ /dev/null @@ -1,73 +0,0 @@ -//===-- RegisterContextTest.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 "gtest/gtest.h" - -#include "Plugins/Process/Utility/RegisterContext_x86.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/FormatVariadic.h" - -#include - -using namespace lldb_private; - -struct TagWordTestVector { - uint16_t sw; - uint16_t tw; - uint8_t tw_abridged; - int st_reg_num; -}; - -constexpr MMSReg st_from_comp(uint64_t mantissa, uint16_t sign_exp) { - MMSReg ret = {}; - ret.comp.mantissa = mantissa; - ret.comp.sign_exp = sign_exp; - return ret; -} - -const std::array st_regs = { - st_from_comp(0x8000000000000000, 0x4000), // +2.0 - st_from_comp(0x3f00000000000000, 0x0000), // 1.654785e-4932 - st_from_comp(0x0000000000000000, 0x0000), // +0 - st_from_comp(0x0000000000000000, 0x8000), // -0 - st_from_comp(0x8000000000000000, 0x7fff), // +inf - st_from_comp(0x8000000000000000, 0xffff), // -inf - st_from_comp(0xc000000000000000, 0xffff), // nan - st_from_comp(0x8000000000000000, 0xc000), // -2.0 -}; - -const std::array tag_word_test_vectors{ - TagWordTestVector{0x3800, 0x3fff, 0x80, 1}, - TagWordTestVector{0x3000, 0x2fff, 0xc0, 2}, - TagWordTestVector{0x2800, 0x27ff, 0xe0, 3}, - TagWordTestVector{0x2000, 0x25ff, 0xf0, 4}, - TagWordTestVector{0x1800, 0x25bf, 0xf8, 5}, - TagWordTestVector{0x1000, 0x25af, 0xfc, 6}, - TagWordTestVector{0x0800, 0x25ab, 0xfe, 7}, - TagWordTestVector{0x0000, 0x25a8, 0xff, 8}, -}; - -TEST(RegisterContext_x86Test, AbridgedToFullTagWord) { - for (const auto &x : llvm::enumerate(tag_word_test_vectors)) { - SCOPED_TRACE(llvm::formatv("tag_word_test_vectors[{0}]", x.index())); - std::array test_regs; - for (int i = 0; i < x.value().st_reg_num; ++i) - test_regs[i] = st_regs[x.value().st_reg_num - i - 1]; - EXPECT_EQ( - AbridgedToFullTagWord(x.value().tw_abridged, x.value().sw, test_regs), - x.value().tw); - } -} - -TEST(RegisterContext_x86Test, FullToAbridgedTagWord) { - for (const auto &x : llvm::enumerate(tag_word_test_vectors)) { - SCOPED_TRACE(llvm::formatv("tag_word_test_vectors[{0}]", x.index())); - EXPECT_EQ(FullToAbridgedTagWord(x.value().tw), x.value().tw_abridged); - } -} diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/gdb-remote/CMakeLists.txt deleted file mode 100644 index 7988fff3e70..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -add_lldb_unittest(ProcessGdbRemoteTests - GDBRemoteClientBaseTest.cpp - GDBRemoteCommunicationClientTest.cpp - GDBRemoteCommunicationServerTest.cpp - GDBRemoteCommunicationTest.cpp - GDBRemoteTestUtils.cpp - PortMapTest.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbPluginPlatformMacOSX - lldbPluginProcessUtility - lldbPluginProcessGDBRemote - - LLVMTestingSupport - - LINK_COMPONENTS - Support - ) diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp deleted file mode 100644 index eb4fd29b4df..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp +++ /dev/null @@ -1,363 +0,0 @@ -//===-- GDBRemoteClientBaseTest.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 - -#include "GDBRemoteTestUtils.h" - -#include "Plugins/Process/Utility/LinuxSignals.h" -#include "Plugins/Process/gdb-remote/GDBRemoteClientBase.h" -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h" -#include "lldb/Utility/GDBRemote.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private::process_gdb_remote; -using namespace lldb_private; -using namespace lldb; -typedef GDBRemoteCommunication::PacketResult PacketResult; - -namespace { - -struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate { - std::string output; - std::string misc_data; - unsigned stop_reply_called = 0; - std::vector structured_data_packets; - - void HandleAsyncStdout(llvm::StringRef out) override { output += out; } - void HandleAsyncMisc(llvm::StringRef data) override { misc_data += data; } - void HandleStopReply() override { ++stop_reply_called; } - - void HandleAsyncStructuredDataPacket(llvm::StringRef data) override { - structured_data_packets.push_back(std::string(data)); - } -}; - -struct TestClient : public GDBRemoteClientBase { - TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") { - m_send_acks = false; - } -}; - -class GDBRemoteClientBaseTest : public GDBRemoteTest { -public: - void SetUp() override { - ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(client, server), - llvm::Succeeded()); - ASSERT_EQ(TestClient::eBroadcastBitRunPacketSent, - listener_sp->StartListeningForEvents( - &client, TestClient::eBroadcastBitRunPacketSent)); - } - -protected: - // We don't have a process to get the interrupt timeout from, so make one up. - static std::chrono::seconds g_timeout; - TestClient client; - MockServer server; - MockDelegate delegate; - ListenerSP listener_sp = Listener::MakeListener("listener"); - - StateType SendCPacket(StringExtractorGDBRemote &response) { - return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(), - "c", g_timeout, - response); - } - - void WaitForRunEvent() { - EventSP event_sp; - listener_sp->GetEventForBroadcasterWithType( - &client, TestClient::eBroadcastBitRunPacketSent, event_sp, llvm::None); - } -}; - -std::chrono::seconds GDBRemoteClientBaseTest::g_timeout(10); - -} // end anonymous namespace - -TEST_F(GDBRemoteClientBaseTest, SendContinueAndWait) { - StringExtractorGDBRemote response; - - // Continue. The inferior will stop with a signal. - ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); - ASSERT_EQ(eStateStopped, SendCPacket(response)); - ASSERT_EQ("T01", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - - // Continue. The inferior will exit. - ASSERT_EQ(PacketResult::Success, server.SendPacket("W01")); - ASSERT_EQ(eStateExited, SendCPacket(response)); - ASSERT_EQ("W01", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - - // Continue. The inferior will get killed. - ASSERT_EQ(PacketResult::Success, server.SendPacket("X01")); - ASSERT_EQ(eStateExited, SendCPacket(response)); - ASSERT_EQ("X01", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal) { - StringExtractorGDBRemote continue_response, response; - - // SendAsyncSignal should do nothing when we are not running. - ASSERT_FALSE(client.SendAsyncSignal(0x47, g_timeout)); - - // Continue. After the run packet is sent, send an async signal. - std::future continue_state = std::async( - std::launch::async, [&] { return SendCPacket(continue_response); }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - WaitForRunEvent(); - - std::future async_result = std::async(std::launch::async, [&] { - return client.SendAsyncSignal(0x47, g_timeout); - }); - - // First we'll get interrupted. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("\x03", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T13")); - - // Then we get the signal packet. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("C47", response.GetStringRef()); - ASSERT_TRUE(async_result.get()); - - // And we report back a signal stop. - ASSERT_EQ(PacketResult::Success, server.SendPacket("T47")); - ASSERT_EQ(eStateStopped, continue_state.get()); - ASSERT_EQ("T47", continue_response.GetStringRef()); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket) { - StringExtractorGDBRemote continue_response, async_response, response; - - // Continue. After the run packet is sent, send an async packet. - std::future continue_state = std::async( - std::launch::async, [&] { return SendCPacket(continue_response); }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - WaitForRunEvent(); - - // Sending without async enabled should fail. - ASSERT_EQ(PacketResult::ErrorSendFailed, - client.SendPacketAndWaitForResponse("qTest1", response)); - - std::future async_result = std::async(std::launch::async, [&] { - return client.SendPacketAndWaitForResponse("qTest2", async_response, - g_timeout); - }); - - // First we'll get interrupted. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("\x03", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T13")); - - // Then we get the async packet. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("qTest2", response.GetStringRef()); - - // Send the response and receive it. - ASSERT_EQ(PacketResult::Success, server.SendPacket("QTest2")); - ASSERT_EQ(PacketResult::Success, async_result.get()); - ASSERT_EQ("QTest2", async_response.GetStringRef()); - - // And we get resumed again. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); - ASSERT_EQ(eStateStopped, continue_state.get()); - ASSERT_EQ("T01", continue_response.GetStringRef()); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt) { - StringExtractorGDBRemote continue_response, response; - - // Interrupt should do nothing when we're not running. - ASSERT_FALSE(client.Interrupt(g_timeout)); - - // Continue. After the run packet is sent, send an interrupt. - std::future continue_state = std::async( - std::launch::async, [&] { return SendCPacket(continue_response); }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - WaitForRunEvent(); - - std::future async_result = std::async( - std::launch::async, [&] { return client.Interrupt(g_timeout); }); - - // We get interrupted. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("\x03", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T13")); - - // And that's it. - ASSERT_EQ(eStateStopped, continue_state.get()); - ASSERT_EQ("T13", continue_response.GetStringRef()); - ASSERT_TRUE(async_result.get()); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt) { - StringExtractorGDBRemote continue_response, response; - - // Continue. After the run packet is sent, send an interrupt. - std::future continue_state = std::async( - std::launch::async, [&] { return SendCPacket(continue_response); }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - WaitForRunEvent(); - - std::future async_result = std::async( - std::launch::async, [&] { return client.Interrupt(g_timeout); }); - - // However, the target stops due to a different reason than the original - // interrupt. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("\x03", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); - ASSERT_EQ(eStateStopped, continue_state.get()); - ASSERT_EQ("T01", continue_response.GetStringRef()); - ASSERT_TRUE(async_result.get()); - - // The subsequent continue packet should work normally. - ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); - ASSERT_EQ(eStateStopped, SendCPacket(response)); - ASSERT_EQ("T01", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug) { - StringExtractorGDBRemote continue_response, async_response, response; - - // Interrupt should do nothing when we're not running. - ASSERT_FALSE(client.Interrupt(g_timeout)); - - // Continue. After the run packet is sent, send an async signal. - std::future continue_state = std::async( - std::launch::async, [&] { return SendCPacket(continue_response); }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - WaitForRunEvent(); - - std::future interrupt_result = std::async( - std::launch::async, [&] { return client.Interrupt(g_timeout); }); - - // We get interrupted. We'll send two packets to simulate a buggy stub. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("\x03", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T13")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T13")); - - // We should stop. - ASSERT_EQ(eStateStopped, continue_state.get()); - ASSERT_EQ("T13", continue_response.GetStringRef()); - ASSERT_TRUE(interrupt_result.get()); - - // Packet stream should remain synchronized. - std::future send_result = std::async(std::launch::async, [&] { - return client.SendPacketAndWaitForResponse("qTest", async_response); - }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("qTest", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.SendPacket("QTest")); - ASSERT_EQ(PacketResult::Success, send_result.get()); - ASSERT_EQ("QTest", async_response.GetStringRef()); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface) { - StringExtractorGDBRemote response; - - // Continue. We'll have the server send a bunch of async packets before it - // stops. - ASSERT_EQ(PacketResult::Success, server.SendPacket("O4142")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("Apro")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("O4344")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("Afile")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); - ASSERT_EQ(eStateStopped, SendCPacket(response)); - ASSERT_EQ("T01", response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - - EXPECT_EQ("ABCD", delegate.output); - EXPECT_EQ("profile", delegate.misc_data); - EXPECT_EQ(1u, delegate.stop_reply_called); -} - -TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateStructuredDataReceipt) { - // Build the plain-text version of the JSON data we will have the - // server send. - const std::string json_payload = - "{ \"type\": \"MyFeatureType\", " - " \"elements\": [ \"entry1\", \"entry2\" ] }"; - const std::string json_packet = "JSON-async:" + json_payload; - - // Escape it properly for transit. - StreamGDBRemote stream; - stream.PutEscapedBytes(json_packet.c_str(), json_packet.length()); - stream.Flush(); - - StringExtractorGDBRemote response; - - // Send async structured data packet, then stop. - ASSERT_EQ(PacketResult::Success, server.SendPacket(stream.GetData())); - ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); - ASSERT_EQ(eStateStopped, SendCPacket(response)); - ASSERT_EQ("T01", response.GetStringRef()); - ASSERT_EQ(1ul, delegate.structured_data_packets.size()); - - // Verify the packet contents. It should have been unescaped upon packet - // reception. - ASSERT_EQ(json_packet, delegate.structured_data_packets[0]); -} - -TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse) { - StringExtractorGDBRemote continue_response, response; - - // Continue. After the run packet is sent, send an interrupt. - std::future continue_state = std::async( - std::launch::async, [&] { return SendCPacket(continue_response); }); - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("c", response.GetStringRef()); - WaitForRunEvent(); - - std::future async_result = std::async( - std::launch::async, [&] { return client.Interrupt(g_timeout); }); - - // We get interrupted, but we don't send a stop packet. - ASSERT_EQ(PacketResult::Success, server.GetPacket(response)); - ASSERT_EQ("\x03", response.GetStringRef()); - - // The functions should still terminate (after a timeout). - ASSERT_TRUE(async_result.get()); - ASSERT_EQ(eStateInvalid, continue_state.get()); -} - -TEST_F(GDBRemoteClientBaseTest, SendPacketAndReceiveResponseWithOutputSupport) { - StringExtractorGDBRemote response; - StreamString command_output; - - ASSERT_EQ(PacketResult::Success, server.SendPacket("O")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("O48656c6c6f2c")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("O20")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("O")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("O776f726c64")); - ASSERT_EQ(PacketResult::Success, server.SendPacket("OK")); - - PacketResult result = client.SendPacketAndReceiveResponseWithOutputSupport( - "qRcmd,test", response, g_timeout, - [&command_output](llvm::StringRef output) { command_output << output; }); - - ASSERT_EQ(PacketResult::Success, result); - ASSERT_EQ("OK", response.GetStringRef()); - ASSERT_EQ("Hello, world", command_output.GetString().str()); -} diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp deleted file mode 100644 index d15b85204b5..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ /dev/null @@ -1,593 +0,0 @@ -//===-- GDBRemoteCommunicationClientTest.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 "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" -#include "GDBRemoteTestUtils.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/XML.h" -#include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Utility/DataBuffer.h" -#include "lldb/Utility/StructuredData.h" -#include "lldb/lldb-enumerations.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" -#include -#include - -using namespace lldb_private::process_gdb_remote; -using namespace lldb_private; -using namespace lldb; -using namespace llvm; - -namespace { - -typedef GDBRemoteCommunication::PacketResult PacketResult; - -struct TestClient : public GDBRemoteCommunicationClient { - TestClient() { m_send_acks = false; } -}; - -void Handle_QThreadSuffixSupported(MockServer &server, bool supported) { - StringExtractorGDBRemote request; - ASSERT_EQ(PacketResult::Success, server.GetPacket(request)); - ASSERT_EQ("QThreadSuffixSupported", request.GetStringRef()); - if (supported) - ASSERT_EQ(PacketResult::Success, server.SendOKResponse()); - else - ASSERT_EQ(PacketResult::Success, server.SendUnimplementedResponse(nullptr)); -} - -void HandlePacket(MockServer &server, - const testing::Matcher &expected, - StringRef response) { - StringExtractorGDBRemote request; - ASSERT_EQ(PacketResult::Success, server.GetPacket(request)); - ASSERT_THAT(std::string(request.GetStringRef()), expected); - ASSERT_EQ(PacketResult::Success, server.SendPacket(response)); -} - -uint8_t all_registers[] = {'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'}; -std::string all_registers_hex = "404142434445464748494a4b4c4d4e4f"; -uint8_t one_register[] = {'A', 'B', 'C', 'D'}; -std::string one_register_hex = "41424344"; - -} // end anonymous namespace - -class GDBRemoteCommunicationClientTest : public GDBRemoteTest { -public: - void SetUp() override { - ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(client, server), - llvm::Succeeded()); - } - -protected: - TestClient client; - MockServer server; -}; - -TEST_F(GDBRemoteCommunicationClientTest, WriteRegister) { - const lldb::tid_t tid = 0x47; - const uint32_t reg_num = 4; - std::future write_result = std::async(std::launch::async, [&] { - return client.WriteRegister(tid, reg_num, one_register); - }); - - Handle_QThreadSuffixSupported(server, true); - - HandlePacket(server, "P4=" + one_register_hex + ";thread:0047;", "OK"); - ASSERT_TRUE(write_result.get()); - - write_result = std::async(std::launch::async, [&] { - return client.WriteAllRegisters(tid, all_registers); - }); - - HandlePacket(server, "G" + all_registers_hex + ";thread:0047;", "OK"); - ASSERT_TRUE(write_result.get()); -} - -TEST_F(GDBRemoteCommunicationClientTest, WriteRegisterNoSuffix) { - const lldb::tid_t tid = 0x47; - const uint32_t reg_num = 4; - std::future write_result = std::async(std::launch::async, [&] { - return client.WriteRegister(tid, reg_num, one_register); - }); - - Handle_QThreadSuffixSupported(server, false); - HandlePacket(server, "Hg47", "OK"); - HandlePacket(server, "P4=" + one_register_hex, "OK"); - ASSERT_TRUE(write_result.get()); - - write_result = std::async(std::launch::async, [&] { - return client.WriteAllRegisters(tid, all_registers); - }); - - HandlePacket(server, "G" + all_registers_hex, "OK"); - ASSERT_TRUE(write_result.get()); -} - -TEST_F(GDBRemoteCommunicationClientTest, ReadRegister) { - const lldb::tid_t tid = 0x47; - const uint32_t reg_num = 4; - std::future async_result = std::async( - std::launch::async, [&] { return client.GetpPacketSupported(tid); }); - Handle_QThreadSuffixSupported(server, true); - HandlePacket(server, "p0;thread:0047;", one_register_hex); - ASSERT_TRUE(async_result.get()); - - std::future read_result = std::async( - std::launch::async, [&] { return client.ReadRegister(tid, reg_num); }); - HandlePacket(server, "p4;thread:0047;", "41424344"); - auto buffer_sp = read_result.get(); - ASSERT_TRUE(bool(buffer_sp)); - ASSERT_EQ(0, - memcmp(buffer_sp->GetBytes(), one_register, sizeof one_register)); - - read_result = std::async(std::launch::async, - [&] { return client.ReadAllRegisters(tid); }); - HandlePacket(server, "g;thread:0047;", all_registers_hex); - buffer_sp = read_result.get(); - ASSERT_TRUE(bool(buffer_sp)); - ASSERT_EQ(0, - memcmp(buffer_sp->GetBytes(), all_registers, sizeof all_registers)); -} - -TEST_F(GDBRemoteCommunicationClientTest, SaveRestoreRegistersNoSuffix) { - const lldb::tid_t tid = 0x47; - uint32_t save_id; - std::future async_result = std::async(std::launch::async, [&] { - return client.SaveRegisterState(tid, save_id); - }); - Handle_QThreadSuffixSupported(server, false); - HandlePacket(server, "Hg47", "OK"); - HandlePacket(server, "QSaveRegisterState", "1"); - ASSERT_TRUE(async_result.get()); - EXPECT_EQ(1u, save_id); - - async_result = std::async(std::launch::async, [&] { - return client.RestoreRegisterState(tid, save_id); - }); - HandlePacket(server, "QRestoreRegisterState:1", "OK"); - ASSERT_TRUE(async_result.get()); -} - -TEST_F(GDBRemoteCommunicationClientTest, SyncThreadState) { - const lldb::tid_t tid = 0x47; - std::future async_result = std::async( - std::launch::async, [&] { return client.SyncThreadState(tid); }); - HandlePacket(server, "qSyncThreadStateSupported", "OK"); - HandlePacket(server, "QSyncThreadState:0047;", "OK"); - ASSERT_TRUE(async_result.get()); -} - -TEST_F(GDBRemoteCommunicationClientTest, GetModulesInfo) { - llvm::Triple triple("i386-pc-linux"); - - FileSpec file_specs[] = { - FileSpec("/foo/bar.so", FileSpec::Style::posix), - FileSpec("/foo/baz.so", FileSpec::Style::posix), - - // This is a bit dodgy but we currently depend on GetModulesInfo not - // performing denormalization. It can go away once the users - // (DynamicLoaderPOSIXDYLD, at least) correctly set the path syntax for - // the FileSpecs they create. - FileSpec("/foo/baw.so", FileSpec::Style::windows), - }; - std::future>> async_result = - std::async(std::launch::async, - [&] { return client.GetModulesInfo(file_specs, triple); }); - HandlePacket( - server, "jModulesInfo:[" - R"({"file":"/foo/bar.so","triple":"i386-pc-linux"},)" - R"({"file":"/foo/baz.so","triple":"i386-pc-linux"},)" - R"({"file":"/foo/baw.so","triple":"i386-pc-linux"}])", - R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)" - R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])"); - - auto result = async_result.get(); - ASSERT_TRUE(result.hasValue()); - ASSERT_EQ(1u, result->size()); - EXPECT_EQ("/foo/bar.so", result.getValue()[0].GetFileSpec().GetPath()); - EXPECT_EQ(triple, result.getValue()[0].GetArchitecture().GetTriple()); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), - result.getValue()[0].GetUUID()); - EXPECT_EQ(0u, result.getValue()[0].GetObjectOffset()); - EXPECT_EQ(1234u, result.getValue()[0].GetObjectSize()); -} - -TEST_F(GDBRemoteCommunicationClientTest, GetModulesInfo_UUID20) { - llvm::Triple triple("i386-pc-linux"); - - FileSpec file_spec("/foo/bar.so", FileSpec::Style::posix); - std::future>> async_result = - std::async(std::launch::async, - [&] { return client.GetModulesInfo(file_spec, triple); }); - HandlePacket( - server, - "jModulesInfo:[" - R"({"file":"/foo/bar.so","triple":"i386-pc-linux"}])", - R"([{"uuid":"404142434445464748494a4b4c4d4e4f50515253","triple":"i386-pc-linux",)" - R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])"); - - auto result = async_result.get(); - ASSERT_TRUE(result.hasValue()); - ASSERT_EQ(1u, result->size()); - EXPECT_EQ("/foo/bar.so", result.getValue()[0].GetFileSpec().GetPath()); - EXPECT_EQ(triple, result.getValue()[0].GetArchitecture().GetTriple()); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20), - result.getValue()[0].GetUUID()); - EXPECT_EQ(0u, result.getValue()[0].GetObjectOffset()); - EXPECT_EQ(1234u, result.getValue()[0].GetObjectSize()); -} - -TEST_F(GDBRemoteCommunicationClientTest, GetModulesInfoInvalidResponse) { - llvm::Triple triple("i386-pc-linux"); - FileSpec file_spec("/foo/bar.so", FileSpec::Style::posix); - - const char *invalid_responses[] = { - // no UUID - R"([{"triple":"i386-pc-linux",)" - R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])", - // invalid UUID - R"([{"uuid":"XXXXXX","triple":"i386-pc-linux",)" - R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])", - // no triple - R"([{"uuid":"404142434445464748494a4b4c4d4e4f",)" - R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])", - // no file_path - R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)" - R"("file_offset":0,"file_size":1234}]])", - // no file_offset - R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)" - R"("file_path":"/foo/bar.so","file_size":1234}]])", - // no file_size - R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)" - R"("file_path":"/foo/bar.so","file_offset":0}]])", - }; - - for (const char *response : invalid_responses) { - std::future>> async_result = - std::async(std::launch::async, - [&] { return client.GetModulesInfo(file_spec, triple); }); - HandlePacket( - server, - R"(jModulesInfo:[{"file":"/foo/bar.so","triple":"i386-pc-linux"}])", - response); - - auto result = async_result.get(); - ASSERT_TRUE(result); - ASSERT_EQ(0u, result->size()) << "response was: " << response; - } -} - -TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) { - std::thread server_thread([this] { - for (;;) { - StringExtractorGDBRemote request; - PacketResult result = server.GetPacket(request); - if (result == PacketResult::ErrorDisconnected) - return; - ASSERT_EQ(PacketResult::Success, result); - StringRef ref = request.GetStringRef(); - ASSERT_TRUE(ref.consume_front("qSpeedTest:response_size:")); - int size; - ASSERT_FALSE(ref.consumeInteger(10, size)) << "ref: " << ref; - std::string response(size, 'X'); - ASSERT_EQ(PacketResult::Success, server.SendPacket(response)); - } - }); - - StreamString ss; - client.TestPacketSpeed(10, 32, 32, 4096, true, ss); - client.Disconnect(); - server_thread.join(); - - GTEST_LOG_(INFO) << "Formatted output: " << ss.GetData(); - auto object_sp = StructuredData::ParseJSON(std::string(ss.GetString())); - ASSERT_TRUE(bool(object_sp)); - auto dict_sp = object_sp->GetAsDictionary(); - ASSERT_TRUE(bool(dict_sp)); - - object_sp = dict_sp->GetValueForKey("packet_speeds"); - ASSERT_TRUE(bool(object_sp)); - dict_sp = object_sp->GetAsDictionary(); - ASSERT_TRUE(bool(dict_sp)); - - int num_packets; - ASSERT_TRUE(dict_sp->GetValueForKeyAsInteger("num_packets", num_packets)) - << ss.GetString(); - ASSERT_EQ(10, num_packets); -} - -TEST_F(GDBRemoteCommunicationClientTest, SendSignalsToIgnore) { - std::future result = std::async(std::launch::async, [&] { - return client.SendSignalsToIgnore({2, 3, 5, 7, 0xB, 0xD, 0x11}); - }); - - HandlePacket(server, "QPassSignals:02;03;05;07;0b;0d;11", "OK"); - EXPECT_TRUE(result.get().Success()); - - result = std::async(std::launch::async, [&] { - return client.SendSignalsToIgnore(std::vector()); - }); - - HandlePacket(server, "QPassSignals:", "OK"); - EXPECT_TRUE(result.get().Success()); -} - -TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) { - const lldb::addr_t addr = 0xa000; - MemoryRegionInfo region_info; - std::future result = std::async(std::launch::async, [&] { - return client.GetMemoryRegionInfo(addr, region_info); - }); - - HandlePacket(server, - "qMemoryRegionInfo:a000", - "start:a000;size:2000;permissions:rx;name:2f666f6f2f6261722e736f;"); - if (XMLDocument::XMLEnabled()) { - // In case we have XML support, this will also do a "qXfer:memory-map". - // Preceeded by a query for supported extensions. Pretend we don't support - // that. - HandlePacket(server, testing::StartsWith("qSupported:"), ""); - } - EXPECT_TRUE(result.get().Success()); - EXPECT_EQ(addr, region_info.GetRange().GetRangeBase()); - EXPECT_EQ(0x2000u, region_info.GetRange().GetByteSize()); - EXPECT_EQ(MemoryRegionInfo::eYes, region_info.GetReadable()); - EXPECT_EQ(MemoryRegionInfo::eNo, region_info.GetWritable()); - EXPECT_EQ(MemoryRegionInfo::eYes, region_info.GetExecutable()); - EXPECT_EQ("/foo/bar.so", region_info.GetName().GetStringRef()); - EXPECT_EQ(MemoryRegionInfo::eDontKnow, region_info.GetMemoryTagged()); - - result = std::async(std::launch::async, [&] { - return client.GetMemoryRegionInfo(addr, region_info); - }); - - HandlePacket(server, "qMemoryRegionInfo:a000", - "start:a000;size:2000;flags:;"); - EXPECT_TRUE(result.get().Success()); - EXPECT_EQ(MemoryRegionInfo::eNo, region_info.GetMemoryTagged()); - - result = std::async(std::launch::async, [&] { - return client.GetMemoryRegionInfo(addr, region_info); - }); - - HandlePacket(server, "qMemoryRegionInfo:a000", - "start:a000;size:2000;flags: mt zz mt ;"); - EXPECT_TRUE(result.get().Success()); - EXPECT_EQ(MemoryRegionInfo::eYes, region_info.GetMemoryTagged()); -} - -TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) { - const lldb::addr_t addr = 0x4000; - MemoryRegionInfo region_info; - std::future result = std::async(std::launch::async, [&] { - return client.GetMemoryRegionInfo(addr, region_info); - }); - - HandlePacket(server, "qMemoryRegionInfo:4000", "start:4000;size:0000;"); - if (XMLDocument::XMLEnabled()) { - // In case we have XML support, this will also do a "qXfer:memory-map". - // Preceeded by a query for supported extensions. Pretend we don't support - // that. - HandlePacket(server, testing::StartsWith("qSupported:"), ""); - } - EXPECT_FALSE(result.get().Success()); -} - -TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedPacket) { - TraceSupportedResponse trace_type; - std::string error_message; - auto callback = [&] { - std::chrono::seconds timeout(10); - if (llvm::Expected trace_type_or_err = - client.SendTraceSupported(timeout)) { - trace_type = *trace_type_or_err; - error_message = ""; - return true; - } else { - trace_type = {}; - error_message = llvm::toString(trace_type_or_err.takeError()); - return false; - } - }; - - // Success response - { - std::future result = std::async(std::launch::async, callback); - - HandlePacket( - server, "jLLDBTraceSupported", - R"({"name":"intel-pt","description":"Intel Processor Trace"}])"); - - EXPECT_TRUE(result.get()); - ASSERT_STREQ(trace_type.name.c_str(), "intel-pt"); - ASSERT_STREQ(trace_type.description.c_str(), "Intel Processor Trace"); - } - - // Error response - wrong json - { - std::future result = std::async(std::launch::async, callback); - - HandlePacket(server, "jLLDBTraceSupported", R"({"type":"intel-pt"}])"); - - EXPECT_FALSE(result.get()); - ASSERT_STREQ(error_message.c_str(), "missing value at TraceSupportedResponse.description"); - } - - // Error response - { - std::future result = std::async(std::launch::async, callback); - - HandlePacket(server, "jLLDBTraceSupported", "E23"); - - EXPECT_FALSE(result.get()); - } - - // Error response with error message - { - std::future result = std::async(std::launch::async, callback); - - HandlePacket(server, "jLLDBTraceSupported", - "E23;50726F63657373206E6F742072756E6E696E672E"); - - EXPECT_FALSE(result.get()); - ASSERT_STREQ(error_message.c_str(), "Process not running."); - } -} - -TEST_F(GDBRemoteCommunicationClientTest, GetQOffsets) { - const auto &GetQOffsets = [&](llvm::StringRef response) { - std::future> result = std::async( - std::launch::async, [&] { return client.GetQOffsets(); }); - - HandlePacket(server, "qOffsets", response); - return result.get(); - }; - EXPECT_EQ((QOffsets{false, {0x1234, 0x1234}}), - GetQOffsets("Text=1234;Data=1234")); - EXPECT_EQ((QOffsets{false, {0x1234, 0x1234, 0x1234}}), - GetQOffsets("Text=1234;Data=1234;Bss=1234")); - EXPECT_EQ((QOffsets{true, {0x1234}}), GetQOffsets("TextSeg=1234")); - EXPECT_EQ((QOffsets{true, {0x1234, 0x2345}}), - GetQOffsets("TextSeg=1234;DataSeg=2345")); - - EXPECT_EQ(llvm::None, GetQOffsets("E05")); - EXPECT_EQ(llvm::None, GetQOffsets("Text=bogus")); - EXPECT_EQ(llvm::None, GetQOffsets("Text=1234")); - EXPECT_EQ(llvm::None, GetQOffsets("Text=1234;Data=1234;")); - EXPECT_EQ(llvm::None, GetQOffsets("Text=1234;Data=1234;Bss=1234;")); - EXPECT_EQ(llvm::None, GetQOffsets("TEXTSEG=1234")); - EXPECT_EQ(llvm::None, GetQOffsets("TextSeg=0x1234")); - EXPECT_EQ(llvm::None, GetQOffsets("TextSeg=12345678123456789")); -} - -static void -check_qmemtags(TestClient &client, MockServer &server, size_t read_len, - int32_t type, const char *packet, llvm::StringRef response, - llvm::Optional> expected_tag_data) { - const auto &ReadMemoryTags = [&]() { - std::future result = std::async(std::launch::async, [&] { - return client.ReadMemoryTags(0xDEF0, read_len, type); - }); - - HandlePacket(server, packet, response); - return result.get(); - }; - - auto result = ReadMemoryTags(); - if (expected_tag_data) { - ASSERT_TRUE(result); - llvm::ArrayRef expected(*expected_tag_data); - llvm::ArrayRef got = result->GetData(); - ASSERT_THAT(expected, testing::ContainerEq(got)); - } else { - ASSERT_FALSE(result); - } -} - -TEST_F(GDBRemoteCommunicationClientTest, ReadMemoryTags) { - // Zero length reads are valid - check_qmemtags(client, server, 0, 1, "qMemTags:def0,0:1", "m", - std::vector{}); - - // Type can be negative. Put into the packet as the raw bytes - // (as opposed to a literal -1) - check_qmemtags(client, server, 0, -1, "qMemTags:def0,0:ffffffff", "m", - std::vector{}); - check_qmemtags(client, server, 0, std::numeric_limits::min(), - "qMemTags:def0,0:80000000", "m", std::vector{}); - check_qmemtags(client, server, 0, std::numeric_limits::max(), - "qMemTags:def0,0:7fffffff", "m", std::vector{}); - - // The client layer does not check the length of the received data. - // All we need is the "m" and for the decode to use all of the chars - check_qmemtags(client, server, 32, 2, "qMemTags:def0,20:2", "m09", - std::vector{0x9}); - - // Zero length response is fine as long as the "m" is present - check_qmemtags(client, server, 0, 0x34, "qMemTags:def0,0:34", "m", - std::vector{}); - - // Normal responses - check_qmemtags(client, server, 16, 1, "qMemTags:def0,10:1", "m66", - std::vector{0x66}); - check_qmemtags(client, server, 32, 1, "qMemTags:def0,20:1", "m0102", - std::vector{0x1, 0x2}); - - // Empty response is an error - check_qmemtags(client, server, 17, 1, "qMemTags:def0,11:1", "", llvm::None); - // Usual error response - check_qmemtags(client, server, 17, 1, "qMemTags:def0,11:1", "E01", - llvm::None); - // Leading m missing - check_qmemtags(client, server, 17, 1, "qMemTags:def0,11:1", "01", llvm::None); - // Anything other than m is an error - check_qmemtags(client, server, 17, 1, "qMemTags:def0,11:1", "z01", - llvm::None); - // Decoding tag data doesn't use all the chars in the packet - check_qmemtags(client, server, 32, 1, "qMemTags:def0,20:1", "m09zz", - llvm::None); - // Data that is not hex bytes - check_qmemtags(client, server, 32, 1, "qMemTags:def0,20:1", "mhello", - llvm::None); - // Data is not a complete hex char - check_qmemtags(client, server, 32, 1, "qMemTags:def0,20:1", "m9", llvm::None); - // Data has a trailing hex char - check_qmemtags(client, server, 32, 1, "qMemTags:def0,20:1", "m01020", - llvm::None); -} - -static void check_Qmemtags(TestClient &client, MockServer &server, - lldb::addr_t addr, size_t len, int32_t type, - const std::vector &tags, const char *packet, - llvm::StringRef response, bool should_succeed) { - const auto &WriteMemoryTags = [&]() { - std::future result = std::async(std::launch::async, [&] { - return client.WriteMemoryTags(addr, len, type, tags); - }); - - HandlePacket(server, packet, response); - return result.get(); - }; - - auto result = WriteMemoryTags(); - if (should_succeed) - ASSERT_TRUE(result.Success()); - else - ASSERT_TRUE(result.Fail()); -} - -TEST_F(GDBRemoteCommunicationClientTest, WriteMemoryTags) { - check_Qmemtags(client, server, 0xABCD, 0x20, 1, - std::vector{0x12, 0x34}, "QMemTags:abcd,20:1:1234", - "OK", true); - - // The GDB layer doesn't care that the number of tags != - // the length of the write. - check_Qmemtags(client, server, 0x4321, 0x20, 9, std::vector{}, - "QMemTags:4321,20:9:", "OK", true); - - check_Qmemtags(client, server, 0x8877, 0x123, 0x34, - std::vector{0x55, 0x66, 0x77}, - "QMemTags:8877,123:34:556677", "E01", false); - - // Type is a signed integer but is packed as its raw bytes, - // instead of having a +/-. - check_Qmemtags(client, server, 0x456789, 0, -1, std::vector{0x99}, - "QMemTags:456789,0:ffffffff:99", "E03", false); - check_Qmemtags(client, server, 0x456789, 0, - std::numeric_limits::max(), - std::vector{0x99}, "QMemTags:456789,0:7fffffff:99", - "E03", false); - check_Qmemtags(client, server, 0x456789, 0, - std::numeric_limits::min(), - std::vector{0x99}, "QMemTags:456789,0:80000000:99", - "E03", false); -} diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp deleted file mode 100644 index 6ab37599ae3..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===-- GDBRemoteCommunicationServerTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "GDBRemoteTestUtils.h" -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h" -#include "lldb/Utility/Connection.h" -#include "lldb/Utility/UnimplementedError.h" - -namespace lldb_private { -namespace process_gdb_remote { - -TEST(GDBRemoteCommunicationServerTest, SendErrorResponse_ErrorNumber) { - MockServerWithMockConnection server; - server.SendErrorResponse(0x42); - - EXPECT_THAT(server.GetPackets(), testing::ElementsAre("$E42#ab")); -} - -TEST(GDBRemoteCommunicationServerTest, SendErrorResponse_Status) { - MockServerWithMockConnection server; - Status status; - - status.SetError(0x42, lldb::eErrorTypeGeneric); - status.SetErrorString("Test error message"); - server.SendErrorResponse(status); - - EXPECT_THAT( - server.GetPackets(), - testing::ElementsAre("$E42;54657374206572726f72206d657373616765#ad")); -} - -TEST(GDBRemoteCommunicationServerTest, SendErrorResponse_UnimplementedError) { - MockServerWithMockConnection server; - - auto error = llvm::make_error(); - server.SendErrorResponse(std::move(error)); - - EXPECT_THAT(server.GetPackets(), testing::ElementsAre("$#00")); -} - -TEST(GDBRemoteCommunicationServerTest, SendErrorResponse_StringError) { - MockServerWithMockConnection server; - - auto error = llvm::createStringError(llvm::inconvertibleErrorCode(), - "String error test"); - server.SendErrorResponse(std::move(error)); - - EXPECT_THAT( - server.GetPackets(), - testing::ElementsAre("$Eff;537472696e67206572726f722074657374#b0")); -} - -TEST(GDBRemoteCommunicationServerTest, SendErrorResponse_ErrorList) { - MockServerWithMockConnection server; - - auto error = llvm::joinErrors(llvm::make_error(), - llvm::make_error()); - - server.SendErrorResponse(std::move(error)); - // Make sure only one packet is sent even when there are multiple errors. - EXPECT_EQ(server.GetPackets().size(), 1UL); -} - -} // namespace process_gdb_remote -} // namespace lldb_private diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp deleted file mode 100644 index 3150477c4e9..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//===-- GDBRemoteCommunicationTest.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 "GDBRemoteTestUtils.h" -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private::process_gdb_remote; -using namespace lldb_private; -using namespace lldb; -typedef GDBRemoteCommunication::PacketResult PacketResult; - -namespace { - -class TestClient : public GDBRemoteCommunication { -public: - TestClient() - : GDBRemoteCommunication("test.client", "test.client.listener") {} - - PacketResult ReadPacket(StringExtractorGDBRemote &response) { - return GDBRemoteCommunication::ReadPacket(response, std::chrono::seconds(1), - /*sync_on_timeout*/ false); - } -}; - -class GDBRemoteCommunicationTest : public GDBRemoteTest { -public: - void SetUp() override { - ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(client, server), - llvm::Succeeded()); - } - -protected: - TestClient client; - MockServer server; - - bool Write(llvm::StringRef packet) { - ConnectionStatus status; - return server.Write(packet.data(), packet.size(), status, nullptr) == - packet.size(); - } -}; -} // end anonymous namespace - -TEST_F(GDBRemoteCommunicationTest, ReadPacket_checksum) { - struct TestCase { - llvm::StringLiteral Packet; - llvm::StringLiteral Payload; - }; - static constexpr TestCase Tests[] = { - {{"$#00"}, {""}}, - {{"$foobar#79"}, {"foobar"}}, - {{"$}}#fa"}, {"]"}}, - {{"$x*%#c7"}, {"xxxxxxxxx"}}, - }; - for (const auto &Test : Tests) { - SCOPED_TRACE(Test.Packet + " -> " + Test.Payload); - StringExtractorGDBRemote response; - ASSERT_TRUE(Write(Test.Packet)); - ASSERT_EQ(PacketResult::Success, client.ReadPacket(response)); - ASSERT_EQ(Test.Payload, response.GetStringRef()); - ASSERT_EQ(PacketResult::Success, server.GetAck()); - } -} diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp deleted file mode 100644 index 6718d0c1ed9..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- GDBRemoteTestUtils.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 "GDBRemoteTestUtils.h" -#include "lldb/Host/Socket.h" -#include "llvm/Testing/Support/Error.h" - -namespace lldb_private { -namespace process_gdb_remote { - -void GDBRemoteTest::SetUpTestCase() { - ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded()); -} - -void GDBRemoteTest::TearDownTestCase() { Socket::Terminate(); } - -} // namespace process_gdb_remote -} // namespace lldb_private diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h deleted file mode 100644 index 27ce6b9b26f..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h +++ /dev/null @@ -1,91 +0,0 @@ -//===-- GDBRemoteTestUtils.h ------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// -#ifndef LLDB_UNITTESTS_PROCESS_GDB_REMOTE_GDBREMOTETESTUTILS_H -#define LLDB_UNITTESTS_PROCESS_GDB_REMOTE_GDBREMOTETESTUTILS_H - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h" -#include "lldb/Utility/Connection.h" - -namespace lldb_private { -namespace process_gdb_remote { - -class GDBRemoteTest : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); -}; - -class MockConnection : public lldb_private::Connection { -public: - MockConnection(std::vector &packets) { m_packets = &packets; }; - - MOCK_METHOD2(Connect, - lldb::ConnectionStatus(llvm::StringRef url, Status *error_ptr)); - MOCK_METHOD5(Read, size_t(void *dst, size_t dst_len, - const Timeout &timeout, - lldb::ConnectionStatus &status, Status *error_ptr)); - MOCK_METHOD0(GetURI, std::string()); - MOCK_METHOD0(InterruptRead, bool()); - - lldb::ConnectionStatus Disconnect(Status *error_ptr) { - return lldb::eConnectionStatusSuccess; - }; - - bool IsConnected() const { return true; }; - size_t Write(const void *dst, size_t dst_len, lldb::ConnectionStatus &status, - Status *error_ptr) { - m_packets->emplace_back(static_cast(dst), dst_len); - return dst_len; - }; - - lldb::IOObjectSP GetReadObject() { return lldb::IOObjectSP(); } - - std::vector *m_packets; -}; - -class MockServer : public GDBRemoteCommunicationServer { -public: - MockServer() - : GDBRemoteCommunicationServer("mock-server", "mock-server.listener") { - m_send_acks = false; - m_send_error_strings = true; - } - - PacketResult SendPacket(llvm::StringRef payload) { - return GDBRemoteCommunicationServer::SendPacketNoLock(payload); - } - - PacketResult GetPacket(StringExtractorGDBRemote &response) { - const bool sync_on_timeout = false; - return WaitForPacketNoLock(response, std::chrono::seconds(1), - sync_on_timeout); - } - - using GDBRemoteCommunicationServer::SendErrorResponse; - using GDBRemoteCommunicationServer::SendOKResponse; - using GDBRemoteCommunicationServer::SendUnimplementedResponse; -}; - -class MockServerWithMockConnection : public MockServer { -public: - MockServerWithMockConnection() : MockServer() { - SetConnection(std::make_unique(m_packets)); - } - - llvm::ArrayRef GetPackets() { return m_packets; }; - - std::vector m_packets; -}; - -} // namespace process_gdb_remote -} // namespace lldb_private - -#endif // LLDB_UNITTESTS_PROCESS_GDB_REMOTE_GDBREMOTETESTUTILS_H diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/PortMapTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/PortMapTest.cpp deleted file mode 100644 index 496a55be7ff..00000000000 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/PortMapTest.cpp +++ /dev/null @@ -1,115 +0,0 @@ -//===-- PortMapTest.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 "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" - -using namespace lldb_private::process_gdb_remote; - -TEST(PortMapTest, Constructors) { - // Default construct to empty map - GDBRemoteCommunicationServerPlatform::PortMap p1; - ASSERT_TRUE(p1.empty()); - - // Empty means no restrictions, return 0 and and bind to get a port - llvm::Expected available_port = p1.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(0)); - - // Adding any port makes it not empty - p1.AllowPort(1); - ASSERT_FALSE(p1.empty()); - - // So we will return the added port this time - available_port = p1.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(1)); - - // Construct from a range of ports - GDBRemoteCommunicationServerPlatform::PortMap p2(1, 4); - ASSERT_FALSE(p2.empty()); - - // Use up all the ports - for (uint16_t expected = 1; expected < 4; ++expected) { - available_port = p2.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(expected)); - p2.AssociatePortWithProcess(*available_port, 1); - } - - // Now we fail since we're not an empty port map but all ports are used - available_port = p2.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); -} - -TEST(PortMapTest, FreePort) { - GDBRemoteCommunicationServerPlatform::PortMap p(1, 4); - // Use up all the ports - for (uint16_t port = 1; port < 4; ++port) { - p.AssociatePortWithProcess(port, 1); - } - - llvm::Expected available_port = p.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); - - // Can't free a port that isn't in the map - ASSERT_FALSE(p.FreePort(0)); - ASSERT_FALSE(p.FreePort(4)); - - // After freeing a port it becomes available - ASSERT_TRUE(p.FreePort(2)); - available_port = p.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(2)); -} - -TEST(PortMapTest, FreePortForProcess) { - GDBRemoteCommunicationServerPlatform::PortMap p; - p.AllowPort(1); - p.AllowPort(2); - ASSERT_TRUE(p.AssociatePortWithProcess(1, 11)); - ASSERT_TRUE(p.AssociatePortWithProcess(2, 22)); - - // All ports have been used - llvm::Expected available_port = p.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); - - // Can't free a port for a process that doesn't have any - ASSERT_FALSE(p.FreePortForProcess(33)); - - // You can move a used port to a new pid - ASSERT_TRUE(p.AssociatePortWithProcess(1, 99)); - - ASSERT_TRUE(p.FreePortForProcess(22)); - available_port = p.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::Succeeded()); - ASSERT_EQ(2, *available_port); - - // proces 22 no longer has a port - ASSERT_FALSE(p.FreePortForProcess(22)); -} - -TEST(PortMapTest, AllowPort) { - GDBRemoteCommunicationServerPlatform::PortMap p; - - // Allow port 1 and tie it to process 11 - p.AllowPort(1); - ASSERT_TRUE(p.AssociatePortWithProcess(1, 11)); - - // Allowing it a second time shouldn't change existing mapping - p.AllowPort(1); - llvm::Expected available_port = p.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); - - // A new port is marked as free when allowed - p.AllowPort(2); - available_port = p.GetNextAvailablePort(); - ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(2)); - - // 11 should still be tied to port 1 - ASSERT_TRUE(p.FreePortForProcess(11)); -} diff --git a/gnu/llvm/lldb/unittests/Process/minidump/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/minidump/CMakeLists.txt deleted file mode 100644 index ad5f1883147..00000000000 --- a/gnu/llvm/lldb/unittests/Process/minidump/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -add_lldb_unittest(LLDBMinidumpTests - MinidumpParserTest.cpp - RegisterContextMinidumpTest.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbTarget - lldbPluginProcessUtility - lldbPluginProcessMinidump - lldbUtilityHelpers - LLVMTestingSupport - LINK_COMPONENTS - ObjectYAML - Support - ) - -set(test_inputs - fizzbuzz_no_heap.dmp - fizzbuzz_wow64.dmp - linux-x86_64.dmp - regions-memlist64.dmp - ) - -add_unittest_inputs(LLDBMinidumpTests "${test_inputs}") diff --git a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/fizzbuzz_no_heap.dmp b/gnu/llvm/lldb/unittests/Process/minidump/Inputs/fizzbuzz_no_heap.dmp deleted file mode 100644 index 19008c91fc3..00000000000 Binary files a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/fizzbuzz_no_heap.dmp and /dev/null differ diff --git a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/fizzbuzz_wow64.dmp b/gnu/llvm/lldb/unittests/Process/minidump/Inputs/fizzbuzz_wow64.dmp deleted file mode 100644 index 3d97186f2cd..00000000000 Binary files a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/fizzbuzz_wow64.dmp and /dev/null differ diff --git a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/linux-x86_64.cpp b/gnu/llvm/lldb/unittests/Process/minidump/Inputs/linux-x86_64.cpp deleted file mode 100644 index 827fe67b503..00000000000 --- a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/linux-x86_64.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Example source from breakpad's linux tutorial -// https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/linux_starter_guide.md - -#include -#include -#include - -#include "client/linux/handler/exception_handler.h" - -static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, - void *context, bool succeeded) { - printf("Dump path: %s\n", descriptor.path()); - return succeeded; -} - -void crash() { - volatile int *a = (int *)(NULL); - *a = 1; -} - -int main(int argc, char *argv[]) { - google_breakpad::MinidumpDescriptor descriptor("/tmp"); - google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, - true, -1); - printf("pid: %d\n", getpid()); - crash(); - return 0; -} diff --git a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/linux-x86_64.dmp b/gnu/llvm/lldb/unittests/Process/minidump/Inputs/linux-x86_64.dmp deleted file mode 100644 index 29a12d6a2eb..00000000000 Binary files a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/linux-x86_64.dmp and /dev/null differ diff --git a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/regions-memlist64.dmp b/gnu/llvm/lldb/unittests/Process/minidump/Inputs/regions-memlist64.dmp deleted file mode 100644 index 1bb8db8464d..00000000000 Binary files a/gnu/llvm/lldb/unittests/Process/minidump/Inputs/regions-memlist64.dmp and /dev/null differ diff --git a/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp deleted file mode 100644 index e3f23c5fe33..00000000000 --- a/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ /dev/null @@ -1,910 +0,0 @@ -//===-- MinidumpTypesTest.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 "Plugins/Process/minidump/MinidumpParser.h" -#include "Plugins/Process/minidump/MinidumpTypes.h" -#include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h" -#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/FileSpec.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ObjectYAML/yaml2obj.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/YAMLTraits.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -// C includes - -// C++ includes -#include - -using namespace lldb_private; -using namespace minidump; - -class MinidumpParserTest : public testing::Test { -public: - SubsystemRAII subsystems; - - void SetUpData(const char *minidump_filename) { - std::string filename = GetInputFilePath(minidump_filename); - auto BufferPtr = FileSystem::Instance().CreateDataBuffer(filename, -1, 0); - ASSERT_NE(BufferPtr, nullptr); - llvm::Expected expected_parser = - MinidumpParser::Create(BufferPtr); - ASSERT_THAT_EXPECTED(expected_parser, llvm::Succeeded()); - parser = std::move(*expected_parser); - ASSERT_GT(parser->GetData().size(), 0UL); - } - - llvm::Error SetUpFromYaml(llvm::StringRef yaml) { - std::string data; - llvm::raw_string_ostream os(data); - llvm::yaml::Input YIn(yaml); - if (!llvm::yaml::convertYAML(YIn, os, [](const llvm::Twine &Msg) {})) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "convertYAML() failed"); - - os.flush(); - auto data_buffer_sp = - std::make_shared(data.data(), data.size()); - auto expected_parser = MinidumpParser::Create(std::move(data_buffer_sp)); - if (!expected_parser) - return expected_parser.takeError(); - parser = std::move(*expected_parser); - return llvm::Error::success(); - } - - llvm::Optional parser; -}; - -TEST_F(MinidumpParserTest, InvalidMinidump) { - std::string duplicate_streams; - llvm::raw_string_ostream os(duplicate_streams); - llvm::yaml::Input YIn(R"( ---- !minidump -Streams: - - Type: LinuxAuxv - Content: DEADBEEFBAADF00D - - Type: LinuxAuxv - Content: DEADBEEFBAADF00D - )"); - - ASSERT_TRUE(llvm::yaml::convertYAML(YIn, os, [](const llvm::Twine &Msg){})); - os.flush(); - auto data_buffer_sp = std::make_shared( - duplicate_streams.data(), duplicate_streams.size()); - ASSERT_THAT_EXPECTED(MinidumpParser::Create(data_buffer_sp), llvm::Failed()); -} - -TEST_F(MinidumpParserTest, GetThreadsAndGetThreadContext) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ThreadList - Threads: - - Thread Id: 0x00003E81 - Stack: - Start of Memory Range: 0x00007FFCEB34A000 - Content: C84D04BCE97F00 - Context: 00000000000000 -... -)"), - llvm::Succeeded()); - llvm::ArrayRef thread_list; - - thread_list = parser->GetThreads(); - ASSERT_EQ(1UL, thread_list.size()); - - const minidump::Thread &thread = thread_list[0]; - - EXPECT_EQ(0x3e81u, thread.ThreadId); - - llvm::ArrayRef context = parser->GetThreadContext(thread); - EXPECT_EQ(7u, context.size()); -} - -TEST_F(MinidumpParserTest, GetArchitecture) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: SystemInfo - Processor Arch: AMD64 - Processor Level: 6 - Processor Revision: 16130 - Number of Processors: 1 - Platform ID: Linux - CPU: - Vendor ID: GenuineIntel - Version Info: 0x00000000 - Feature Info: 0x00000000 -... -)"), - llvm::Succeeded()); - ASSERT_EQ(llvm::Triple::ArchType::x86_64, - parser->GetArchitecture().GetMachine()); - ASSERT_EQ(llvm::Triple::OSType::Linux, - parser->GetArchitecture().GetTriple().getOS()); -} - -TEST_F(MinidumpParserTest, GetMiscInfo_no_stream) { - // Test that GetMiscInfo returns nullptr when the minidump does not contain - // this stream. - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: -... -)"), - llvm::Succeeded()); - EXPECT_EQ(nullptr, parser->GetMiscInfo()); -} - -TEST_F(MinidumpParserTest, GetLinuxProcStatus) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: SystemInfo - Processor Arch: AMD64 - Processor Level: 6 - Processor Revision: 16130 - Number of Processors: 1 - Platform ID: Linux - CSD Version: 'Linux 3.13.0-91-generic' - CPU: - Vendor ID: GenuineIntel - Version Info: 0x00000000 - Feature Info: 0x00000000 - - Type: LinuxProcStatus - Text: | - Name: a.out - State: t (tracing stop) - Tgid: 16001 - Ngid: 0 - Pid: 16001 - PPid: 13243 - TracerPid: 16002 - Uid: 404696 404696 404696 404696 - Gid: 5762 5762 5762 5762 -... -)"), - llvm::Succeeded()); - llvm::Optional proc_status = parser->GetLinuxProcStatus(); - ASSERT_TRUE(proc_status.hasValue()); - lldb::pid_t pid = proc_status->GetPid(); - ASSERT_EQ(16001UL, pid); -} - -TEST_F(MinidumpParserTest, GetPid) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: SystemInfo - Processor Arch: AMD64 - Processor Level: 6 - Processor Revision: 16130 - Number of Processors: 1 - Platform ID: Linux - CSD Version: 'Linux 3.13.0-91-generic' - CPU: - Vendor ID: GenuineIntel - Version Info: 0x00000000 - Feature Info: 0x00000000 - - Type: LinuxProcStatus - Text: | - Name: a.out - State: t (tracing stop) - Tgid: 16001 - Ngid: 0 - Pid: 16001 - PPid: 13243 - TracerPid: 16002 - Uid: 404696 404696 404696 404696 - Gid: 5762 5762 5762 5762 -... -)"), - llvm::Succeeded()); - llvm::Optional pid = parser->GetPid(); - ASSERT_TRUE(pid.hasValue()); - ASSERT_EQ(16001UL, pid.getValue()); -} - -TEST_F(MinidumpParserTest, GetFilteredModuleList) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x0000000000400000 - Size of Image: 0x00001000 - Module Name: '/tmp/test/linux-x86_64_not_crashed' - CodeView Record: 4C4570426CCF3F60FFA7CC4B86AE8FF44DB2576A68983611 - - Base of Image: 0x0000000000600000 - Size of Image: 0x00002000 - Module Name: '/tmp/test/linux-x86_64_not_crashed' - CodeView Record: 4C4570426CCF3F60FFA7CC4B86AE8FF44DB2576A68983611 -... -)"), - llvm::Succeeded()); - llvm::ArrayRef modules = parser->GetModuleList(); - std::vector filtered_modules = - parser->GetFilteredModuleList(); - EXPECT_EQ(2u, modules.size()); - ASSERT_EQ(1u, filtered_modules.size()); - const minidump::Module &M = *filtered_modules[0]; - EXPECT_THAT_EXPECTED(parser->GetMinidumpFile().getString(M.ModuleNameRVA), - llvm::HasValue("/tmp/test/linux-x86_64_not_crashed")); -} - -TEST_F(MinidumpParserTest, GetExceptionStream) { - SetUpData("linux-x86_64.dmp"); - const llvm::minidump::ExceptionStream *exception_stream = - parser->GetExceptionStream(); - ASSERT_NE(nullptr, exception_stream); - ASSERT_EQ(11UL, exception_stream->ExceptionRecord.ExceptionCode); -} - -void check_mem_range_exists(MinidumpParser &parser, const uint64_t range_start, - const uint64_t range_size) { - llvm::Optional range = parser.FindMemoryRange(range_start); - ASSERT_TRUE(range.hasValue()) << "There is no range containing this address"; - EXPECT_EQ(range_start, range->start); - EXPECT_EQ(range_start + range_size, range->start + range->range_ref.size()); -} - -TEST_F(MinidumpParserTest, FindMemoryRange) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: MemoryList - Memory Ranges: - - Start of Memory Range: 0x00007FFCEB34A000 - Content: C84D04BCE9 - - Start of Memory Range: 0x0000000000401D46 - Content: 5421 -... -)"), - llvm::Succeeded()); - EXPECT_EQ(llvm::None, parser->FindMemoryRange(0x00)); - EXPECT_EQ(llvm::None, parser->FindMemoryRange(0x2a)); - EXPECT_EQ((minidump::Range{0x401d46, llvm::ArrayRef{0x54, 0x21}}), - parser->FindMemoryRange(0x401d46)); - EXPECT_EQ(llvm::None, parser->FindMemoryRange(0x401d46 + 2)); - - EXPECT_EQ( - (minidump::Range{0x7ffceb34a000, - llvm::ArrayRef{0xc8, 0x4d, 0x04, 0xbc, 0xe9}}), - parser->FindMemoryRange(0x7ffceb34a000 + 2)); - EXPECT_EQ(llvm::None, parser->FindMemoryRange(0x7ffceb34a000 + 5)); -} - -TEST_F(MinidumpParserTest, GetMemory) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: MemoryList - Memory Ranges: - - Start of Memory Range: 0x00007FFCEB34A000 - Content: C84D04BCE9 - - Start of Memory Range: 0x0000000000401D46 - Content: 5421 -... -)"), - llvm::Succeeded()); - - EXPECT_EQ((llvm::ArrayRef{0x54}), parser->GetMemory(0x401d46, 1)); - EXPECT_EQ((llvm::ArrayRef{0x54, 0x21}), - parser->GetMemory(0x401d46, 4)); - - EXPECT_EQ((llvm::ArrayRef{0xc8, 0x4d, 0x04, 0xbc, 0xe9}), - parser->GetMemory(0x7ffceb34a000, 5)); - EXPECT_EQ((llvm::ArrayRef{0xc8, 0x4d, 0x04}), - parser->GetMemory(0x7ffceb34a000, 3)); - - EXPECT_EQ(llvm::ArrayRef(), parser->GetMemory(0x500000, 512)); -} - -TEST_F(MinidumpParserTest, FindMemoryRangeWithFullMemoryMinidump) { - SetUpData("fizzbuzz_wow64.dmp"); - - // There are a lot of ranges in the file, just testing with some of them - EXPECT_FALSE(parser->FindMemoryRange(0x00).hasValue()); - EXPECT_FALSE(parser->FindMemoryRange(0x2a).hasValue()); - check_mem_range_exists(*parser, 0x10000, 65536); // first range - check_mem_range_exists(*parser, 0x40000, 4096); - EXPECT_FALSE(parser->FindMemoryRange(0x40000 + 4096).hasValue()); - check_mem_range_exists(*parser, 0x77c12000, 8192); - check_mem_range_exists(*parser, 0x7ffe0000, 4096); // last range - EXPECT_FALSE(parser->FindMemoryRange(0x7ffe0000 + 4096).hasValue()); -} - -constexpr auto yes = MemoryRegionInfo::eYes; -constexpr auto no = MemoryRegionInfo::eNo; -constexpr auto unknown = MemoryRegionInfo::eDontKnow; - -TEST_F(MinidumpParserTest, GetMemoryRegionInfo) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: MemoryInfoList - Memory Ranges: - - Base Address: 0x0000000000000000 - Allocation Protect: [ ] - Region Size: 0x0000000000010000 - State: [ MEM_FREE ] - Protect: [ PAGE_NO_ACCESS ] - Type: [ ] - - Base Address: 0x0000000000010000 - Allocation Protect: [ PAGE_READ_WRITE ] - Region Size: 0x0000000000021000 - State: [ MEM_COMMIT ] - Type: [ MEM_MAPPED ] - - Base Address: 0x0000000000040000 - Allocation Protect: [ PAGE_EXECUTE_WRITE_COPY ] - Region Size: 0x0000000000001000 - State: [ MEM_COMMIT ] - Protect: [ PAGE_READ_ONLY ] - Type: [ MEM_IMAGE ] - - Base Address: 0x000000007FFE0000 - Allocation Protect: [ PAGE_READ_ONLY ] - Region Size: 0x0000000000001000 - State: [ MEM_COMMIT ] - Type: [ MEM_PRIVATE ] - - Base Address: 0x000000007FFE1000 - Allocation Base: 0x000000007FFE0000 - Allocation Protect: [ PAGE_READ_ONLY ] - Region Size: 0x000000000000F000 - State: [ MEM_RESERVE ] - Protect: [ PAGE_NO_ACCESS ] - Type: [ MEM_PRIVATE ] -... -)"), - llvm::Succeeded()); - - EXPECT_THAT( - parser->BuildMemoryRegions(), - testing::Pair(testing::ElementsAre( - MemoryRegionInfo({0x0, 0x10000}, no, no, no, no, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x10000, 0x21000}, yes, yes, no, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x40000, 0x1000}, yes, no, no, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x7ffe0000, 0x1000}, yes, no, no, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x7ffe1000, 0xf000}, no, no, no, yes, - ConstString(), unknown, 0, unknown)), - true)); -} - -TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemoryList) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: MemoryList - Memory Ranges: - - Start of Memory Range: 0x0000000000001000 - Content: '31313131313131313131313131313131' - - Start of Memory Range: 0x0000000000002000 - Content: '3333333333333333333333333333333333333333333333333333333333333333' -... -)"), - llvm::Succeeded()); - - // Test we can get memory regions from the MINIDUMP_MEMORY_LIST stream when - // we don't have a MemoryInfoListStream. - - EXPECT_THAT( - parser->BuildMemoryRegions(), - testing::Pair( - testing::ElementsAre( - MemoryRegionInfo({0x1000, 0x10}, yes, unknown, unknown, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x2000, 0x20}, yes, unknown, unknown, yes, - ConstString(), unknown, 0, unknown)), - false)); -} - -TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemory64List) { - SetUpData("regions-memlist64.dmp"); - - // Test we can get memory regions from the MINIDUMP_MEMORY64_LIST stream when - // we don't have a MemoryInfoListStream. - EXPECT_THAT( - parser->BuildMemoryRegions(), - testing::Pair( - testing::ElementsAre( - MemoryRegionInfo({0x1000, 0x10}, yes, unknown, unknown, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x2000, 0x20}, yes, unknown, unknown, yes, - ConstString(), unknown, 0, unknown)), - false)); -} - -TEST_F(MinidumpParserTest, GetMemoryRegionInfoLinuxMaps) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: LinuxMaps - Text: | - 400d9000-400db000 r-xp 00000000 b3:04 227 /system/bin/app_process - 400db000-400dc000 r--p 00001000 b3:04 227 /system/bin/app_process - 400dc000-400dd000 rw-p 00000000 00:00 0 - 400ec000-400ed000 r--p 00000000 00:00 0 - 400ee000-400ef000 rw-p 00010000 b3:04 300 /system/bin/linker - 400fc000-400fd000 rwxp 00001000 b3:04 1096 /system/lib/liblog.so - -... -)"), - llvm::Succeeded()); - // Test we can get memory regions from the linux /proc//maps stream when - // we don't have a MemoryInfoListStream. - ConstString app_process("/system/bin/app_process"); - ConstString linker("/system/bin/linker"); - ConstString liblog("/system/lib/liblog.so"); - EXPECT_THAT(parser->BuildMemoryRegions(), - testing::Pair( - testing::ElementsAre( - MemoryRegionInfo({0x400d9000, 0x2000}, yes, no, yes, yes, - app_process, unknown, 0, unknown), - MemoryRegionInfo({0x400db000, 0x1000}, yes, no, no, yes, - app_process, unknown, 0, unknown), - MemoryRegionInfo({0x400dc000, 0x1000}, yes, yes, no, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x400ec000, 0x1000}, yes, no, no, yes, - ConstString(), unknown, 0, unknown), - MemoryRegionInfo({0x400ee000, 0x1000}, yes, yes, no, yes, - linker, unknown, 0, unknown), - MemoryRegionInfo({0x400fc000, 0x1000}, yes, yes, yes, yes, - liblog, unknown, 0, unknown)), - true)); -} - -TEST_F(MinidumpParserTest, GetMemoryRegionInfoLinuxMapsError) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: LinuxMaps - Text: | - 400d9000-400db000 r?xp 00000000 b3:04 227 - 400fc000-400fd000 rwxp 00001000 b3:04 1096 -... -)"), - llvm::Succeeded()); - // Test that when a /proc/maps region fails to parse - // we handle the error and continue with the rest. - EXPECT_THAT(parser->BuildMemoryRegions(), - testing::Pair(testing::ElementsAre(MemoryRegionInfo( - {0x400fc000, 0x1000}, yes, yes, yes, yes, - ConstString(nullptr), unknown, 0, unknown)), - true)); -} - -// Windows Minidump tests -TEST_F(MinidumpParserTest, GetArchitectureWindows) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: SystemInfo - Processor Arch: X86 - Processor Level: 6 - Processor Revision: 15876 - Number of Processors: 32 - Product type: 1 - Major Version: 6 - Minor Version: 1 - Build Number: 7601 - Platform ID: Win32NT - CSD Version: Service Pack 1 - Suite Mask: 0x0100 - CPU: - Vendor ID: GenuineIntel - Version Info: 0x000306E4 - Feature Info: 0xBFEBFBFF - AMD Extended Features: 0x771EEC80 -... -)"), - llvm::Succeeded()); - ASSERT_EQ(llvm::Triple::ArchType::x86, - parser->GetArchitecture().GetMachine()); - ASSERT_EQ(llvm::Triple::OSType::Win32, - parser->GetArchitecture().GetTriple().getOS()); -} - -TEST_F(MinidumpParserTest, GetLinuxProcStatus_no_stream) { - // Test that GetLinuxProcStatus returns nullptr when the minidump does not - // contain this stream. - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: -... -)"), - llvm::Succeeded()); - EXPECT_EQ(llvm::None, parser->GetLinuxProcStatus()); -} - -TEST_F(MinidumpParserTest, GetMiscInfoWindows) { - SetUpData("fizzbuzz_no_heap.dmp"); - const MinidumpMiscInfo *misc_info = parser->GetMiscInfo(); - ASSERT_NE(nullptr, misc_info); - llvm::Optional pid = misc_info->GetPid(); - ASSERT_TRUE(pid.hasValue()); - ASSERT_EQ(4440UL, pid.getValue()); -} - -TEST_F(MinidumpParserTest, GetPidWindows) { - SetUpData("fizzbuzz_no_heap.dmp"); - llvm::Optional pid = parser->GetPid(); - ASSERT_TRUE(pid.hasValue()); - ASSERT_EQ(4440UL, pid.getValue()); -} - -// wow64 -TEST_F(MinidumpParserTest, GetPidWow64) { - SetUpData("fizzbuzz_wow64.dmp"); - llvm::Optional pid = parser->GetPid(); - ASSERT_TRUE(pid.hasValue()); - ASSERT_EQ(7836UL, pid.getValue()); -} - -// Register tests -#define REG_VAL32(x) *(reinterpret_cast(x)) -#define REG_VAL64(x) *(reinterpret_cast(x)) - -TEST_F(MinidumpParserTest, GetThreadContext_x86_32) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ThreadList - Threads: - - Thread Id: 0x00026804 - Stack: - Start of Memory Range: 0x00000000FF9DD000 - Content: 68D39DFF - Context: 0F0001000000000000000000000000000000000000000000000000007F03FFFF0000FFFFFFFFFFFF09DC62F72300000088E36CF72B00FFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000000000000002B0000002B000000A88204085CD59DFF008077F7A3D49DFF01000000000000003CD59DFFA082040823000000820201002CD59DFF2B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -)"), - llvm::Succeeded()); - - llvm::ArrayRef thread_list = parser->GetThreads(); - const minidump::Thread &thread = thread_list[0]; - llvm::ArrayRef registers(parser->GetThreadContext(thread)); - const MinidumpContext_x86_32 *context; - EXPECT_TRUE(consumeObject(registers, context).Success()); - - EXPECT_EQ(MinidumpContext_x86_32_Flags(uint32_t(context->context_flags)), - MinidumpContext_x86_32_Flags::x86_32_Flag | - MinidumpContext_x86_32_Flags::Full | - MinidumpContext_x86_32_Flags::FloatingPoint); - - EXPECT_EQ(0x00000000u, context->eax); - EXPECT_EQ(0xf7778000u, context->ebx); - EXPECT_EQ(0x00000001u, context->ecx); - EXPECT_EQ(0xff9dd4a3u, context->edx); - EXPECT_EQ(0x080482a8u, context->edi); - EXPECT_EQ(0xff9dd55cu, context->esi); - EXPECT_EQ(0xff9dd53cu, context->ebp); - EXPECT_EQ(0xff9dd52cu, context->esp); - EXPECT_EQ(0x080482a0u, context->eip); - EXPECT_EQ(0x00010282u, context->eflags); - EXPECT_EQ(0x0023u, context->cs); - EXPECT_EQ(0x0000u, context->fs); - EXPECT_EQ(0x0063u, context->gs); - EXPECT_EQ(0x002bu, context->ss); - EXPECT_EQ(0x002bu, context->ds); - EXPECT_EQ(0x002bu, context->es); -} - -TEST_F(MinidumpParserTest, GetThreadContext_x86_64) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ThreadList - Threads: - - Thread Id: 0x00003E81 - Stack: - Start of Memory Range: 0x00007FFCEB34A000 - Content: C84D04BCE97F00 - Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -... -)"), - llvm::Succeeded()); - llvm::ArrayRef thread_list = parser->GetThreads(); - const minidump::Thread &thread = thread_list[0]; - llvm::ArrayRef registers(parser->GetThreadContext(thread)); - const MinidumpContext_x86_64 *context; - EXPECT_TRUE(consumeObject(registers, context).Success()); - - EXPECT_EQ(MinidumpContext_x86_64_Flags(uint32_t(context->context_flags)), - MinidumpContext_x86_64_Flags::x86_64_Flag | - MinidumpContext_x86_64_Flags::Control | - MinidumpContext_x86_64_Flags::FloatingPoint | - MinidumpContext_x86_64_Flags::Integer); - EXPECT_EQ(0x0000000000000000u, context->rax); - EXPECT_EQ(0x0000000000000000u, context->rbx); - EXPECT_EQ(0x0000000000000010u, context->rcx); - EXPECT_EQ(0x0000000000000000u, context->rdx); - EXPECT_EQ(0x00007ffceb349cf0u, context->rdi); - EXPECT_EQ(0x0000000000000000u, context->rsi); - EXPECT_EQ(0x00007ffceb34a210u, context->rbp); - EXPECT_EQ(0x00007ffceb34a210u, context->rsp); - EXPECT_EQ(0x00007fe9bc1aa9c0u, context->r8); - EXPECT_EQ(0x0000000000000000u, context->r9); - EXPECT_EQ(0x00007fe9bc3f16a0u, context->r10); - EXPECT_EQ(0x0000000000000246u, context->r11); - EXPECT_EQ(0x0000000000401c92u, context->r12); - EXPECT_EQ(0x00007ffceb34a430u, context->r13); - EXPECT_EQ(0x0000000000000000u, context->r14); - EXPECT_EQ(0x0000000000000000u, context->r15); - EXPECT_EQ(0x0000000000401dc6u, context->rip); - EXPECT_EQ(0x00010206u, context->eflags); - EXPECT_EQ(0x0033u, context->cs); - EXPECT_EQ(0x0000u, context->ss); -} - -TEST_F(MinidumpParserTest, GetThreadContext_x86_32_wow64) { - SetUpData("fizzbuzz_wow64.dmp"); - llvm::ArrayRef thread_list = parser->GetThreads(); - const minidump::Thread &thread = thread_list[0]; - llvm::ArrayRef registers(parser->GetThreadContextWow64(thread)); - const MinidumpContext_x86_32 *context; - EXPECT_TRUE(consumeObject(registers, context).Success()); - - EXPECT_EQ(MinidumpContext_x86_32_Flags(uint32_t(context->context_flags)), - MinidumpContext_x86_32_Flags::x86_32_Flag | - MinidumpContext_x86_32_Flags::Full | - MinidumpContext_x86_32_Flags::FloatingPoint | - MinidumpContext_x86_32_Flags::ExtendedRegisters); - - EXPECT_EQ(0x00000000u, context->eax); - EXPECT_EQ(0x0037f608u, context->ebx); - EXPECT_EQ(0x00e61578u, context->ecx); - EXPECT_EQ(0x00000008u, context->edx); - EXPECT_EQ(0x00000000u, context->edi); - EXPECT_EQ(0x00000002u, context->esi); - EXPECT_EQ(0x0037f654u, context->ebp); - EXPECT_EQ(0x0037f5b8u, context->esp); - EXPECT_EQ(0x77ce01fdu, context->eip); - EXPECT_EQ(0x00000246u, context->eflags); - EXPECT_EQ(0x0023u, context->cs); - EXPECT_EQ(0x0053u, context->fs); - EXPECT_EQ(0x002bu, context->gs); - EXPECT_EQ(0x002bu, context->ss); - EXPECT_EQ(0x002bu, context->ds); - EXPECT_EQ(0x002bu, context->es); -} - -TEST_F(MinidumpParserTest, MinidumpDuplicateModuleMinAddress) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x0000000000002000 - Size of Image: 0x00001000 - Module Name: '/tmp/a' - CodeView Record: '' - - Base of Image: 0x0000000000001000 - Size of Image: 0x00001000 - Module Name: '/tmp/a' - CodeView Record: '' -... -)"), - llvm::Succeeded()); - // If we have a module mentioned twice in the module list, the filtered - // module list should contain the instance with the lowest BaseOfImage. - std::vector filtered_modules = - parser->GetFilteredModuleList(); - ASSERT_EQ(1u, filtered_modules.size()); - EXPECT_EQ(0x0000000000001000u, filtered_modules[0]->BaseOfImage); -} - -TEST_F(MinidumpParserTest, MinidumpDuplicateModuleMappedFirst) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x400d0000 - Size of Image: 0x00002000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Base of Image: 0x400d3000 - Size of Image: 0x00001000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Type: LinuxMaps - Text: | - 400d0000-400d2000 r--p 00000000 b3:04 227 /usr/lib/libc.so - 400d2000-400d3000 rw-p 00000000 00:00 0 - 400d3000-400d4000 r-xp 00010000 b3:04 227 /usr/lib/libc.so - 400d4000-400d5000 rwxp 00001000 b3:04 227 /usr/lib/libc.so -... -)"), - llvm::Succeeded()); - // If we have a module mentioned twice in the module list, and we have full - // linux maps for all of the memory regions, make sure we pick the one that - // has a consecutive region with a matching path that has executable - // permissions. If clients open an object file with mmap, breakpad can create - // multiple mappings for a library errnoneously and the lowest address isn't - // always the right address. In this case we check the consective memory - // regions whose path matches starting at the base of image address and make - // sure one of the regions is executable and prefer that one. - // - // This test will make sure that if the executable is second in the module - // list, that it will become the selected module in the filtered list. - std::vector filtered_modules = - parser->GetFilteredModuleList(); - ASSERT_EQ(1u, filtered_modules.size()); - EXPECT_EQ(0x400d3000u, filtered_modules[0]->BaseOfImage); -} - -TEST_F(MinidumpParserTest, MinidumpDuplicateModuleMappedSecond) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x400d0000 - Size of Image: 0x00002000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Base of Image: 0x400d3000 - Size of Image: 0x00001000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Type: LinuxMaps - Text: | - 400d0000-400d1000 r-xp 00010000 b3:04 227 /usr/lib/libc.so - 400d1000-400d2000 rwxp 00001000 b3:04 227 /usr/lib/libc.so - 400d2000-400d3000 rw-p 00000000 00:00 0 - 400d3000-400d5000 r--p 00000000 b3:04 227 /usr/lib/libc.so -... -)"), - llvm::Succeeded()); - // If we have a module mentioned twice in the module list, and we have full - // linux maps for all of the memory regions, make sure we pick the one that - // has a consecutive region with a matching path that has executable - // permissions. If clients open an object file with mmap, breakpad can create - // multiple mappings for a library errnoneously and the lowest address isn't - // always the right address. In this case we check the consective memory - // regions whose path matches starting at the base of image address and make - // sure one of the regions is executable and prefer that one. - // - // This test will make sure that if the executable is first in the module - // list, that it will remain the correctly selected module in the filtered - // list. - std::vector filtered_modules = - parser->GetFilteredModuleList(); - ASSERT_EQ(1u, filtered_modules.size()); - EXPECT_EQ(0x400d0000u, filtered_modules[0]->BaseOfImage); -} - -TEST_F(MinidumpParserTest, MinidumpDuplicateModuleMappedSecondHigh) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x400d3000 - Size of Image: 0x00002000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Base of Image: 0x400d0000 - Size of Image: 0x00001000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Type: LinuxMaps - Text: | - 400d0000-400d2000 r--p 00000000 b3:04 227 /usr/lib/libc.so - 400d2000-400d3000 rw-p 00000000 00:00 0 - 400d3000-400d4000 r-xp 00010000 b3:04 227 /usr/lib/libc.so - 400d4000-400d5000 rwxp 00001000 b3:04 227 /usr/lib/libc.so -... -)"), - llvm::Succeeded()); - // If we have a module mentioned twice in the module list, and we have full - // linux maps for all of the memory regions, make sure we pick the one that - // has a consecutive region with a matching path that has executable - // permissions. If clients open an object file with mmap, breakpad can create - // multiple mappings for a library errnoneously and the lowest address isn't - // always the right address. In this case we check the consective memory - // regions whose path matches starting at the base of image address and make - // sure one of the regions is executable and prefer that one. - // - // This test will make sure that if the executable is first in the module - // list, that it will remain the correctly selected module in the filtered - // list, even if the non-executable module was loaded at a lower base address. - std::vector filtered_modules = - parser->GetFilteredModuleList(); - ASSERT_EQ(1u, filtered_modules.size()); - EXPECT_EQ(0x400d3000u, filtered_modules[0]->BaseOfImage); -} - -TEST_F(MinidumpParserTest, MinidumpDuplicateModuleSeparateCode) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x400d0000 - Size of Image: 0x00002000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Base of Image: 0x400d5000 - Size of Image: 0x00001000 - Module Name: '/usr/lib/libc.so' - CodeView Record: '' - - Type: LinuxMaps - Text: | - 400d0000-400d3000 r--p 00000000 b3:04 227 /usr/lib/libc.so - 400d3000-400d5000 rw-p 00000000 00:00 0 - 400d5000-400d6000 r--p 00000000 b3:04 227 /usr/lib/libc.so - 400d6000-400d7000 r-xp 00010000 b3:04 227 /usr/lib/libc.so - 400d7000-400d8000 rwxp 00001000 b3:04 227 /usr/lib/libc.so -... -)"), - llvm::Succeeded()); - // If we have a module mentioned twice in the module list, and we have full - // linux maps for all of the memory regions, make sure we pick the one that - // has a consecutive region with a matching path that has executable - // permissions. If clients open an object file with mmap, breakpad can create - // multiple mappings for a library errnoneously and the lowest address isn't - // always the right address. In this case we check the consective memory - // regions whose path matches starting at the base of image address and make - // sure one of the regions is executable and prefer that one. - // - // This test will make sure if binaries are compiled with "-z separate-code", - // where the first region for a binary won't be marked as executable, that - // it gets selected by detecting the second consecutive mapping at 0x400d7000 - // when asked about the a module mamed "/usr/lib/libc.so" at 0x400d5000. - std::vector filtered_modules = - parser->GetFilteredModuleList(); - ASSERT_EQ(1u, filtered_modules.size()); - EXPECT_EQ(0x400d5000u, filtered_modules[0]->BaseOfImage); -} - -TEST_F(MinidumpParserTest, MinidumpModuleOrder) { - ASSERT_THAT_ERROR(SetUpFromYaml(R"( ---- !minidump -Streams: - - Type: ModuleList - Modules: - - Base of Image: 0x0000000000002000 - Size of Image: 0x00001000 - Module Name: '/tmp/a' - CodeView Record: '' - - Base of Image: 0x0000000000001000 - Size of Image: 0x00001000 - Module Name: '/tmp/b' - CodeView Record: '' -... -)"), - llvm::Succeeded()); - // Test module filtering does not affect the overall module order. Previous - // versions of the MinidumpParser::GetFilteredModuleList() function would sort - // all images by address and modify the order of the modules. - std::vector filtered_modules = - parser->GetFilteredModuleList(); - ASSERT_EQ(2u, filtered_modules.size()); - EXPECT_EQ(0x0000000000002000u, filtered_modules[0]->BaseOfImage); - EXPECT_THAT_EXPECTED( - parser->GetMinidumpFile().getString(filtered_modules[0]->ModuleNameRVA), - llvm::HasValue("/tmp/a")); - EXPECT_EQ(0x0000000000001000u, filtered_modules[1]->BaseOfImage); - EXPECT_THAT_EXPECTED( - parser->GetMinidumpFile().getString(filtered_modules[1]->ModuleNameRVA), - llvm::HasValue("/tmp/b")); -} diff --git a/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp b/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp deleted file mode 100644 index b7d25b2d4f0..00000000000 --- a/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp +++ /dev/null @@ -1,201 +0,0 @@ -//===-- RegisterContextMinidumpTest.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 "Plugins/Process/Utility/RegisterContextLinux_i386.h" -#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" -#include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h" -#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" -#include "Plugins/Process/minidump/RegisterContextMinidump_ARM.h" -#include "lldb/Utility/DataBuffer.h" -#include "llvm/ADT/StringRef.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::minidump; - -static uint32_t reg32(const DataBuffer &Buf, const RegisterInfo &Info) { - return *reinterpret_cast(Buf.GetBytes() + Info.byte_offset); -} - -static uint64_t reg64(const DataBuffer &Buf, const RegisterInfo &Info) { - return *reinterpret_cast(Buf.GetBytes() + Info.byte_offset); -} - -TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_32) { - MinidumpContext_x86_32 Context; - Context.context_flags = - static_cast(MinidumpContext_x86_32_Flags::x86_32_Flag | - MinidumpContext_x86_32_Flags::Control | - MinidumpContext_x86_32_Flags::Segments | - MinidumpContext_x86_32_Flags::Integer); - Context.eax = 0x00010203; - Context.ebx = 0x04050607; - Context.ecx = 0x08090a0b; - Context.edx = 0x0c0d0e0f; - Context.edi = 0x10111213; - Context.esi = 0x14151617; - Context.ebp = 0x18191a1b; - Context.esp = 0x1c1d1e1f; - Context.eip = 0x20212223; - Context.eflags = 0x24252627; - Context.cs = 0x2829; - Context.fs = 0x2a2b; - Context.gs = 0x2c2d; - Context.ss = 0x2e2f; - Context.ds = 0x3031; - Context.es = 0x3233; - llvm::ArrayRef ContextRef(reinterpret_cast(&Context), - sizeof(Context)); - - ArchSpec arch("i386-pc-linux"); - auto RegInterface = std::make_unique(arch); - lldb::DataBufferSP Buf = - ConvertMinidumpContext_x86_32(ContextRef, RegInterface.get()); - ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize()); - - const RegisterInfo *Info = RegInterface->GetRegisterInfo(); - ASSERT_NE(nullptr, Info); - - EXPECT_EQ(Context.eax, reg32(*Buf, Info[lldb_eax_i386])); - EXPECT_EQ(Context.ebx, reg32(*Buf, Info[lldb_ebx_i386])); - EXPECT_EQ(Context.ecx, reg32(*Buf, Info[lldb_ecx_i386])); - EXPECT_EQ(Context.edx, reg32(*Buf, Info[lldb_edx_i386])); - EXPECT_EQ(Context.edi, reg32(*Buf, Info[lldb_edi_i386])); - EXPECT_EQ(Context.esi, reg32(*Buf, Info[lldb_esi_i386])); - EXPECT_EQ(Context.ebp, reg32(*Buf, Info[lldb_ebp_i386])); - EXPECT_EQ(Context.esp, reg32(*Buf, Info[lldb_esp_i386])); - EXPECT_EQ(Context.eip, reg32(*Buf, Info[lldb_eip_i386])); - EXPECT_EQ(Context.eflags, reg32(*Buf, Info[lldb_eflags_i386])); - EXPECT_EQ(Context.cs, reg32(*Buf, Info[lldb_cs_i386])); - EXPECT_EQ(Context.fs, reg32(*Buf, Info[lldb_fs_i386])); - EXPECT_EQ(Context.gs, reg32(*Buf, Info[lldb_gs_i386])); - EXPECT_EQ(Context.ss, reg32(*Buf, Info[lldb_ss_i386])); - EXPECT_EQ(Context.ds, reg32(*Buf, Info[lldb_ds_i386])); - EXPECT_EQ(Context.es, reg32(*Buf, Info[lldb_es_i386])); -} - -TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_64) { - MinidumpContext_x86_64 Context; - Context.context_flags = - static_cast(MinidumpContext_x86_64_Flags::x86_64_Flag | - MinidumpContext_x86_64_Flags::Control | - MinidumpContext_x86_64_Flags::Segments | - MinidumpContext_x86_64_Flags::Integer); - Context.rax = 0x0001020304050607; - Context.rbx = 0x08090a0b0c0d0e0f; - Context.rcx = 0x1011121314151617; - Context.rdx = 0x18191a1b1c1d1e1f; - Context.rdi = 0x2021222324252627; - Context.rsi = 0x28292a2b2c2d2e2f; - Context.rbp = 0x3031323334353637; - Context.rsp = 0x38393a3b3c3d3e3f; - Context.r8 = 0x4041424344454647; - Context.r9 = 0x48494a4b4c4d4e4f; - Context.r10 = 0x5051525354555657; - Context.r11 = 0x58595a5b5c5d5e5f; - Context.r12 = 0x6061626364656667; - Context.r13 = 0x68696a6b6c6d6e6f; - Context.r14 = 0x7071727374757677; - Context.r15 = 0x78797a7b7c7d7e7f; - Context.rip = 0x8081828384858687; - Context.eflags = 0x88898a8b; - Context.cs = 0x8c8d; - Context.fs = 0x8e8f; - Context.gs = 0x9091; - Context.ss = 0x9293; - Context.ds = 0x9495; - Context.ss = 0x9697; - llvm::ArrayRef ContextRef(reinterpret_cast(&Context), - sizeof(Context)); - - ArchSpec arch("x86_64-pc-linux"); - auto RegInterface = std::make_unique(arch); - lldb::DataBufferSP Buf = - ConvertMinidumpContext_x86_64(ContextRef, RegInterface.get()); - ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize()); - - const RegisterInfo *Info = RegInterface->GetRegisterInfo(); - EXPECT_EQ(Context.rax, reg64(*Buf, Info[lldb_rax_x86_64])); - EXPECT_EQ(Context.rbx, reg64(*Buf, Info[lldb_rbx_x86_64])); - EXPECT_EQ(Context.rcx, reg64(*Buf, Info[lldb_rcx_x86_64])); - EXPECT_EQ(Context.rdx, reg64(*Buf, Info[lldb_rdx_x86_64])); - EXPECT_EQ(Context.rdi, reg64(*Buf, Info[lldb_rdi_x86_64])); - EXPECT_EQ(Context.rsi, reg64(*Buf, Info[lldb_rsi_x86_64])); - EXPECT_EQ(Context.rbp, reg64(*Buf, Info[lldb_rbp_x86_64])); - EXPECT_EQ(Context.rsp, reg64(*Buf, Info[lldb_rsp_x86_64])); - EXPECT_EQ(Context.r8, reg64(*Buf, Info[lldb_r8_x86_64])); - EXPECT_EQ(Context.r9, reg64(*Buf, Info[lldb_r9_x86_64])); - EXPECT_EQ(Context.r10, reg64(*Buf, Info[lldb_r10_x86_64])); - EXPECT_EQ(Context.r11, reg64(*Buf, Info[lldb_r11_x86_64])); - EXPECT_EQ(Context.r12, reg64(*Buf, Info[lldb_r12_x86_64])); - EXPECT_EQ(Context.r13, reg64(*Buf, Info[lldb_r13_x86_64])); - EXPECT_EQ(Context.r14, reg64(*Buf, Info[lldb_r14_x86_64])); - EXPECT_EQ(Context.r15, reg64(*Buf, Info[lldb_r15_x86_64])); - EXPECT_EQ(Context.rip, reg64(*Buf, Info[lldb_rip_x86_64])); - EXPECT_EQ(Context.eflags, reg64(*Buf, Info[lldb_rflags_x86_64])); - EXPECT_EQ(Context.cs, reg64(*Buf, Info[lldb_cs_x86_64])); - EXPECT_EQ(Context.fs, reg64(*Buf, Info[lldb_fs_x86_64])); - EXPECT_EQ(Context.gs, reg64(*Buf, Info[lldb_gs_x86_64])); - EXPECT_EQ(Context.ss, reg64(*Buf, Info[lldb_ss_x86_64])); - EXPECT_EQ(Context.ds, reg64(*Buf, Info[lldb_ds_x86_64])); - EXPECT_EQ(Context.es, reg64(*Buf, Info[lldb_es_x86_64])); -} - -static void TestARMRegInfo(const lldb_private::RegisterInfo *info) { - // Make sure we have valid register numbers for eRegisterKindEHFrame and - // eRegisterKindDWARF for GPR registers r0-r15 so that we can unwind - // correctly when using this information. - llvm::StringRef name(info->name); - llvm::StringRef alt_name(info->alt_name); - if (name.startswith("r") || alt_name.startswith("r")) { - EXPECT_NE(info->kinds[lldb::eRegisterKindEHFrame], LLDB_INVALID_REGNUM); - EXPECT_NE(info->kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM); - } - // Verify generic register are set correctly - if (name == "r0") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_ARG1); - } else if (name == "r1") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_ARG2); - } else if (name == "r2") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_ARG3); - } else if (name == "r3") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_ARG4); - } else if (name == "sp") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_SP); - } else if (name == "fp") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_FP); - } else if (name == "lr") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_RA); - } else if (name == "pc") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_PC); - } else if (name == "cpsr") { - EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric], - (uint32_t)LLDB_REGNUM_GENERIC_FLAGS); - } -} - -TEST(RegisterContextMinidump, CheckRegisterContextMinidump_ARM) { - size_t num_regs = RegisterContextMinidump_ARM::GetRegisterCountStatic(); - const lldb_private::RegisterInfo *reg_info; - for (size_t reg=0; reg' which is -// incompatible with C -#if _MSC_VER -#pragma warning (push) -#pragma warning (disable : 4190) -#endif - -extern "C" llvm::Expected LLDBSwigLuaBreakpointCallbackFunction( - lua_State *L, lldb::StackFrameSP stop_frame_sp, - lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl) { - return false; -} - -extern "C" llvm::Expected LLDBSwigLuaWatchpointCallbackFunction( - lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp) { - return false; -} - -#if _MSC_VER -#pragma warning (pop) -#endif - -#pragma clang diagnostic pop - -TEST(LuaTest, RunValid) { - Lua lua; - llvm::Error error = lua.Run("foo = 1"); - EXPECT_FALSE(static_cast(error)); -} - -TEST(LuaTest, RunInvalid) { - Lua lua; - llvm::Error error = lua.Run("nil = foo"); - EXPECT_TRUE(static_cast(error)); - EXPECT_EQ(llvm::toString(std::move(error)), - "[string \"buffer\"]:1: unexpected symbol near 'nil'\n"); -} diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp b/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp deleted file mode 100644 index e4aebfb650c..00000000000 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//===-- LuaTests.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 "Plugins/Platform/Linux/PlatformLinux.h" -#include "Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Target/Platform.h" -#include "lldb/Utility/Reproducer.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace lldb; - -namespace { -class ScriptInterpreterTest : public ::testing::Test { -public: - void SetUp() override { - llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); - FileSystem::Initialize(); - HostInfo::Initialize(); - - // Pretend Linux is the host platform. - platform_linux::PlatformLinux::Initialize(); - ArchSpec arch("powerpc64-pc-linux"); - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - } - void TearDown() override { - platform_linux::PlatformLinux::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - Reproducer::Terminate(); - } -}; -} // namespace - -TEST_F(ScriptInterpreterTest, ExecuteOneLine) { - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - ScriptInterpreterLua script_interpreter(*debugger_sp); - CommandReturnObject result(/*colors*/ false); - EXPECT_TRUE(script_interpreter.ExecuteOneLine("foo = 1", &result)); - EXPECT_FALSE(script_interpreter.ExecuteOneLine("nil = foo", &result)); - EXPECT_TRUE(result.GetErrorData().startswith( - "error: lua failed attempting to evaluate 'nil = foo'")); -} diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt deleted file mode 100644 index 90a53bf1751..00000000000 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_lldb_unittest(ScriptInterpreterPythonTests - PythonDataObjectsTests.cpp - PythonTestSuite.cpp - - LINK_LIBS - lldbHost - lldbPluginScriptInterpreterPython - LLVMTestingSupport - LINK_COMPONENTS - Support - ) - -if(Python3_RPATH) - set_property(TARGET ScriptInterpreterPythonTests APPEND PROPERTY BUILD_RPATH "${Python3_RPATH}") -endif() diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp deleted file mode 100644 index 75a1f5e67d3..00000000000 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp +++ /dev/null @@ -1,861 +0,0 @@ -//===-- PythonDataObjectsTests.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 "Plugins/ScriptInterpreter/Python/lldb-python.h" -#include "gtest/gtest.h" - -#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h" -#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" -#include "lldb/Host/File.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/lldb-enumerations.h" -#include "llvm/Testing/Support/Error.h" - -#include "PythonTestSuite.h" - -using namespace lldb_private; -using namespace lldb_private::python; -using llvm::Error; -using llvm::Expected; - -class PythonDataObjectsTest : public PythonTestSuite { -public: - void SetUp() override { - PythonTestSuite::SetUp(); - - m_sys_module = unwrapIgnoringErrors(PythonModule::Import("sys")); - m_main_module = PythonModule::MainModule(); - m_builtins_module = PythonModule::BuiltinsModule(); - } - - void TearDown() override { - m_sys_module.Reset(); - m_main_module.Reset(); - m_builtins_module.Reset(); - - PythonTestSuite::TearDown(); - } - -protected: - PythonModule m_sys_module; - PythonModule m_main_module; - PythonModule m_builtins_module; -}; - -TEST_F(PythonDataObjectsTest, TestOwnedReferences) { - // After creating a new object, the refcount should be >= 1 - PyObject *obj = PyLong_FromLong(3); - Py_ssize_t original_refcnt = obj->ob_refcnt; - EXPECT_LE(1, original_refcnt); - - // If we take an owned reference, the refcount should be the same - PythonObject owned_long(PyRefType::Owned, obj); - EXPECT_EQ(original_refcnt, owned_long.get()->ob_refcnt); - - // Take another reference and verify that the refcount increases by 1 - PythonObject strong_ref(owned_long); - EXPECT_EQ(original_refcnt + 1, strong_ref.get()->ob_refcnt); - - // If we reset the first one, the refcount should be the original value. - owned_long.Reset(); - EXPECT_EQ(original_refcnt, strong_ref.get()->ob_refcnt); -} - -TEST_F(PythonDataObjectsTest, TestResetting) { - PythonDictionary dict(PyInitialValue::Empty); - - PyObject *new_dict = PyDict_New(); - dict = Take(new_dict); - EXPECT_EQ(new_dict, dict.get()); - - dict = Take(PyDict_New()); - EXPECT_NE(nullptr, dict.get()); - dict.Reset(); - EXPECT_EQ(nullptr, dict.get()); -} - -TEST_F(PythonDataObjectsTest, TestBorrowedReferences) { - PythonInteger long_value(PyRefType::Owned, PyLong_FromLong(3)); - Py_ssize_t original_refcnt = long_value.get()->ob_refcnt; - EXPECT_LE(1, original_refcnt); - - PythonInteger borrowed_long(PyRefType::Borrowed, long_value.get()); - EXPECT_EQ(original_refcnt + 1, borrowed_long.get()->ob_refcnt); -} - -TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionNoDot) { - PythonObject sys_module = m_main_module.ResolveName("sys"); - EXPECT_EQ(m_sys_module.get(), sys_module.get()); - EXPECT_TRUE(sys_module.IsAllocated()); - EXPECT_TRUE(PythonModule::Check(sys_module.get())); -} - -TEST_F(PythonDataObjectsTest, TestModuleNameResolutionNoDot) { - PythonObject sys_path = m_sys_module.ResolveName("path"); - PythonObject sys_version_info = m_sys_module.ResolveName("version_info"); - EXPECT_TRUE(sys_path.IsAllocated()); - EXPECT_TRUE(sys_version_info.IsAllocated()); - - EXPECT_TRUE(PythonList::Check(sys_path.get())); -} - -TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) { - PythonObject sys_version_info = m_sys_module.ResolveName("version_info"); - - PythonObject version_info_type(PyRefType::Owned, - PyObject_Type(sys_version_info.get())); - EXPECT_TRUE(version_info_type.IsAllocated()); - PythonObject major_version_field = version_info_type.ResolveName("major"); - EXPECT_TRUE(major_version_field.IsAllocated()); -} - -TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) { - PythonObject sys_version_info = m_sys_module.ResolveName("version_info"); - PythonObject major_version_field = sys_version_info.ResolveName("major"); - PythonObject minor_version_field = sys_version_info.ResolveName("minor"); - - EXPECT_TRUE(major_version_field.IsAllocated()); - EXPECT_TRUE(minor_version_field.IsAllocated()); - - auto major_version_value = As(major_version_field); - auto minor_version_value = As(minor_version_field); - - EXPECT_THAT_EXPECTED(major_version_value, llvm::HasValue(PY_MAJOR_VERSION)); - EXPECT_THAT_EXPECTED(minor_version_value, llvm::HasValue(PY_MINOR_VERSION)); -} - -TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) { - PythonObject sys_path = m_main_module.ResolveName("sys.path"); - EXPECT_TRUE(sys_path.IsAllocated()); - EXPECT_TRUE(PythonList::Check(sys_path.get())); - - auto version_major = - As(m_main_module.ResolveName("sys.version_info.major")); - - auto version_minor = - As(m_main_module.ResolveName("sys.version_info.minor")); - - EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION)); - EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION)); -} - -TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) { - // Make up a custom dictionary with "sys" pointing to the `sys` module. - PythonDictionary dict(PyInitialValue::Empty); - dict.SetItemForKey(PythonString("sys"), m_sys_module); - - // Now use that dictionary to resolve `sys.version_info.major` - auto version_major = As( - PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict)); - - auto version_minor = As( - PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict)); - - EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION)); - EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION)); -} - -TEST_F(PythonDataObjectsTest, TestPythonInteger) { - // Test that integers behave correctly when wrapped by a PythonInteger. - -#if PY_MAJOR_VERSION < 3 - // Verify that `PythonInt` works correctly when given a PyInt object. - // Note that PyInt doesn't exist in Python 3.x, so this is only for 2.x - PyObject *py_int = PyInt_FromLong(12); - EXPECT_TRUE(PythonInteger::Check(py_int)); - PythonInteger python_int(PyRefType::Owned, py_int); - - EXPECT_EQ(PyObjectType::Integer, python_int.GetObjectType()); - auto python_int_value = As(python_int); - EXPECT_THAT_EXPECTED(python_int_value, llvm::HasValue(12)); -#endif - - // Verify that `PythonInteger` works correctly when given a PyLong object. - PyObject *py_long = PyLong_FromLong(12); - EXPECT_TRUE(PythonInteger::Check(py_long)); - PythonInteger python_long(PyRefType::Owned, py_long); - EXPECT_EQ(PyObjectType::Integer, python_long.GetObjectType()); - - // Verify that you can reset the value and that it is reflected properly. - python_long.SetInteger(40); - auto e = As(python_long); - EXPECT_THAT_EXPECTED(e, llvm::HasValue(40)); - - // Test that creating a `PythonInteger` object works correctly with the - // int constructor. - PythonInteger constructed_int(7); - auto value = As(constructed_int); - EXPECT_THAT_EXPECTED(value, llvm::HasValue(7)); -} - -TEST_F(PythonDataObjectsTest, TestPythonBoolean) { - // Test PythonBoolean constructed from Py_True - EXPECT_TRUE(PythonBoolean::Check(Py_True)); - PythonBoolean python_true(PyRefType::Owned, Py_True); - EXPECT_EQ(PyObjectType::Boolean, python_true.GetObjectType()); - - // Test PythonBoolean constructed from Py_False - EXPECT_TRUE(PythonBoolean::Check(Py_False)); - PythonBoolean python_false(PyRefType::Owned, Py_False); - EXPECT_EQ(PyObjectType::Boolean, python_false.GetObjectType()); - - auto test_from_long = [](long value) { - PyObject *py_bool = PyBool_FromLong(value); - EXPECT_TRUE(PythonBoolean::Check(py_bool)); - PythonBoolean python_boolean(PyRefType::Owned, py_bool); - EXPECT_EQ(PyObjectType::Boolean, python_boolean.GetObjectType()); - EXPECT_EQ(bool(value), python_boolean.GetValue()); - }; - - // Test PythonBoolean constructed from long integer values. - test_from_long(0); // Test 'false' value. - test_from_long(1); // Test 'true' value. - test_from_long(~0); // Any value != 0 is 'true'. -} - -TEST_F(PythonDataObjectsTest, TestPythonBytes) { - static const char *test_bytes = "PythonDataObjectsTest::TestPythonBytes"; - PyObject *py_bytes = PyBytes_FromString(test_bytes); - EXPECT_TRUE(PythonBytes::Check(py_bytes)); - PythonBytes python_bytes(PyRefType::Owned, py_bytes); - -#if PY_MAJOR_VERSION < 3 - EXPECT_TRUE(PythonString::Check(py_bytes)); - EXPECT_EQ(PyObjectType::String, python_bytes.GetObjectType()); -#else - EXPECT_FALSE(PythonString::Check(py_bytes)); - EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType()); -#endif - - llvm::ArrayRef bytes = python_bytes.GetBytes(); - EXPECT_EQ(bytes.size(), strlen(test_bytes)); - EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size())); -} - -TEST_F(PythonDataObjectsTest, TestPythonByteArray) { - static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray"; - llvm::StringRef orig_bytes(test_bytes); - PyObject *py_bytes = - PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size()); - EXPECT_TRUE(PythonByteArray::Check(py_bytes)); - PythonByteArray python_bytes(PyRefType::Owned, py_bytes); - EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType()); - - llvm::ArrayRef after_bytes = python_bytes.GetBytes(); - EXPECT_EQ(after_bytes.size(), orig_bytes.size()); - EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size())); -} - -TEST_F(PythonDataObjectsTest, TestPythonString) { - // Test that strings behave correctly when wrapped by a PythonString. - - static const char *test_string = "PythonDataObjectsTest::TestPythonString1"; - static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2"; - -#if PY_MAJOR_VERSION < 3 - // Verify that `PythonString` works correctly when given a PyString object. - // Note that PyString doesn't exist in Python 3.x, so this is only for 2.x - PyObject *py_string = PyString_FromString(test_string); - EXPECT_TRUE(PythonString::Check(py_string)); - PythonString python_string(PyRefType::Owned, py_string); - - EXPECT_EQ(PyObjectType::String, python_string.GetObjectType()); - EXPECT_STREQ(test_string, python_string.GetString().data()); -#else - // Verify that `PythonString` works correctly when given a PyUnicode object. - PyObject *py_unicode = PyUnicode_FromString(test_string); - EXPECT_TRUE(PythonString::Check(py_unicode)); - PythonString python_unicode(PyRefType::Owned, py_unicode); - EXPECT_EQ(PyObjectType::String, python_unicode.GetObjectType()); - EXPECT_STREQ(test_string, python_unicode.GetString().data()); -#endif - - // Test that creating a `PythonString` object works correctly with the - // string constructor - PythonString constructed_string(test_string2); - EXPECT_EQ(test_string2, constructed_string.GetString()); -} - -TEST_F(PythonDataObjectsTest, TestPythonStringToStr) { - const char *GetString = "PythonDataObjectsTest::TestPythonStringToStr"; - - PythonString str(GetString); - EXPECT_EQ(GetString, str.GetString()); - - PythonString str_str = str.Str(); - EXPECT_EQ(GetString, str_str.GetString()); -} - -TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {} - -TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredInteger) { - PythonInteger integer(7); - auto int_sp = integer.CreateStructuredInteger(); - EXPECT_EQ(7U, int_sp->GetValue()); -} - -TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) { - static const char *test_string = - "PythonDataObjectsTest::TestPythonStringToStructuredString"; - PythonString constructed_string(test_string); - auto string_sp = constructed_string.CreateStructuredString(); - EXPECT_EQ(test_string, string_sp->GetStringValue()); -} - -TEST_F(PythonDataObjectsTest, TestPythonListValueEquality) { - // Test that a list which is built through the native - // Python API behaves correctly when wrapped by a PythonList. - static const unsigned list_size = 2; - static const long long_value0 = 5; - static const char *const string_value1 = "String Index 1"; - - PyObject *py_list = PyList_New(2); - EXPECT_TRUE(PythonList::Check(py_list)); - PythonList list(PyRefType::Owned, py_list); - - PythonObject list_items[list_size]; - list_items[0] = PythonInteger(long_value0); - list_items[1] = PythonString(string_value1); - - for (unsigned i = 0; i < list_size; ++i) - list.SetItemAtIndex(i, list_items[i]); - - EXPECT_EQ(list_size, list.GetSize()); - EXPECT_EQ(PyObjectType::List, list.GetObjectType()); - - // Verify that the values match - PythonObject chk_value1 = list.GetItemAtIndex(0); - PythonObject chk_value2 = list.GetItemAtIndex(1); - EXPECT_TRUE(PythonInteger::Check(chk_value1.get())); - EXPECT_TRUE(PythonString::Check(chk_value2.get())); - - PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get()); - PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - - auto chkint = As(chk_value1); - ASSERT_THAT_EXPECTED(chkint, llvm::HasValue(long_value0)); - EXPECT_EQ(string_value1, chk_str.GetString()); -} - -TEST_F(PythonDataObjectsTest, TestPythonListManipulation) { - // Test that manipulation of a PythonList behaves correctly when - // wrapped by a PythonDictionary. - - static const long long_value0 = 5; - static const char *const string_value1 = "String Index 1"; - - PythonList list(PyInitialValue::Empty); - PythonInteger integer(long_value0); - PythonString string(string_value1); - - list.AppendItem(integer); - list.AppendItem(string); - EXPECT_EQ(2U, list.GetSize()); - - // Verify that the values match - PythonObject chk_value1 = list.GetItemAtIndex(0); - PythonObject chk_value2 = list.GetItemAtIndex(1); - EXPECT_TRUE(PythonInteger::Check(chk_value1.get())); - EXPECT_TRUE(PythonString::Check(chk_value2.get())); - - PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get()); - PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - - auto e = As(chk_int); - EXPECT_THAT_EXPECTED(e, llvm::HasValue(long_value0)); - EXPECT_EQ(string_value1, chk_str.GetString()); -} - -TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) { - static const long long_value0 = 5; - static const char *const string_value1 = "String Index 1"; - - PythonList list(PyInitialValue::Empty); - list.AppendItem(PythonInteger(long_value0)); - list.AppendItem(PythonString(string_value1)); - - auto array_sp = list.CreateStructuredArray(); - EXPECT_EQ(lldb::eStructuredDataTypeInteger, - array_sp->GetItemAtIndex(0)->GetType()); - EXPECT_EQ(lldb::eStructuredDataTypeString, - array_sp->GetItemAtIndex(1)->GetType()); - - auto int_sp = array_sp->GetItemAtIndex(0)->GetAsInteger(); - auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString(); - - EXPECT_EQ(long_value0, long(int_sp->GetValue())); - EXPECT_EQ(string_value1, string_sp->GetValue()); -} - -TEST_F(PythonDataObjectsTest, TestPythonTupleSize) { - PythonTuple tuple(PyInitialValue::Empty); - EXPECT_EQ(0U, tuple.GetSize()); - - tuple = PythonTuple(3); - EXPECT_EQ(3U, tuple.GetSize()); -} - -TEST_F(PythonDataObjectsTest, TestPythonTupleValues) { - PythonTuple tuple(3); - - PythonInteger int_value(1); - PythonString string_value("Test"); - PythonObject none_value(PyRefType::Borrowed, Py_None); - - tuple.SetItemAtIndex(0, int_value); - tuple.SetItemAtIndex(1, string_value); - tuple.SetItemAtIndex(2, none_value); - - EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get()); - EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get()); - EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get()); -} - -TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList) { - PythonInteger int_value(1); - PythonString string_value("Test"); - PythonObject none_value(PyRefType::Borrowed, Py_None); - PythonTuple tuple{int_value, string_value, none_value}; - EXPECT_EQ(3U, tuple.GetSize()); - - EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get()); - EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get()); - EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get()); -} - -TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2) { - PythonInteger int_value(1); - PythonString string_value("Test"); - PythonObject none_value(PyRefType::Borrowed, Py_None); - - PythonTuple tuple{int_value.get(), string_value.get(), none_value.get()}; - EXPECT_EQ(3U, tuple.GetSize()); - - EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get()); - EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get()); - EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get()); -} - -TEST_F(PythonDataObjectsTest, TestPythonTupleToStructuredList) { - PythonInteger int_value(1); - PythonString string_value("Test"); - - PythonTuple tuple{int_value.get(), string_value.get()}; - - auto array_sp = tuple.CreateStructuredArray(); - EXPECT_EQ(tuple.GetSize(), array_sp->GetSize()); - EXPECT_EQ(lldb::eStructuredDataTypeInteger, - array_sp->GetItemAtIndex(0)->GetType()); - EXPECT_EQ(lldb::eStructuredDataTypeString, - array_sp->GetItemAtIndex(1)->GetType()); -} - -TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality) { - // Test that a dictionary which is built through the native - // Python API behaves correctly when wrapped by a PythonDictionary. - static const unsigned dict_entries = 2; - const char *key_0 = "Key 0"; - int key_1 = 1; - const int value_0 = 0; - const char *value_1 = "Value 1"; - - PythonObject py_keys[dict_entries]; - PythonObject py_values[dict_entries]; - - py_keys[0] = PythonString(key_0); - py_keys[1] = PythonInteger(key_1); - py_values[0] = PythonInteger(value_0); - py_values[1] = PythonString(value_1); - - PyObject *py_dict = PyDict_New(); - EXPECT_TRUE(PythonDictionary::Check(py_dict)); - PythonDictionary dict(PyRefType::Owned, py_dict); - - for (unsigned i = 0; i < dict_entries; ++i) - PyDict_SetItem(py_dict, py_keys[i].get(), py_values[i].get()); - EXPECT_EQ(dict.GetSize(), dict_entries); - EXPECT_EQ(PyObjectType::Dictionary, dict.GetObjectType()); - - // Verify that the values match - PythonObject chk_value1 = dict.GetItemForKey(py_keys[0]); - PythonObject chk_value2 = dict.GetItemForKey(py_keys[1]); - EXPECT_TRUE(PythonInteger::Check(chk_value1.get())); - EXPECT_TRUE(PythonString::Check(chk_value2.get())); - - PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - auto chkint = As(chk_value1); - - EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0)); - EXPECT_EQ(value_1, chk_str.GetString()); -} - -TEST_F(PythonDataObjectsTest, TestPythonDictionaryManipulation) { - // Test that manipulation of a dictionary behaves correctly when wrapped - // by a PythonDictionary. - static const unsigned dict_entries = 2; - - const char *const key_0 = "Key 0"; - const char *const key_1 = "Key 1"; - const long value_0 = 1; - const char *const value_1 = "Value 1"; - - PythonString keys[dict_entries]; - PythonObject values[dict_entries]; - - keys[0] = PythonString(key_0); - keys[1] = PythonString(key_1); - values[0] = PythonInteger(value_0); - values[1] = PythonString(value_1); - - PythonDictionary dict(PyInitialValue::Empty); - for (int i = 0; i < 2; ++i) - dict.SetItemForKey(keys[i], values[i]); - - EXPECT_EQ(dict_entries, dict.GetSize()); - - // Verify that the keys and values match - PythonObject chk_value1 = dict.GetItemForKey(keys[0]); - PythonObject chk_value2 = dict.GetItemForKey(keys[1]); - EXPECT_TRUE(PythonInteger::Check(chk_value1.get())); - EXPECT_TRUE(PythonString::Check(chk_value2.get())); - - auto chkint = As(chk_value1); - PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - - EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0)); - EXPECT_EQ(value_1, chk_str.GetString()); -} - -TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) { - static const char *const string_key0 = "String Key 0"; - static const char *const string_key1 = "String Key 1"; - - static const char *const string_value0 = "String Value 0"; - static const long int_value1 = 7; - - PythonDictionary dict(PyInitialValue::Empty); - dict.SetItemForKey(PythonString(string_key0), PythonString(string_value0)); - dict.SetItemForKey(PythonString(string_key1), PythonInteger(int_value1)); - - auto dict_sp = dict.CreateStructuredDictionary(); - EXPECT_EQ(2U, dict_sp->GetSize()); - - EXPECT_TRUE(dict_sp->HasKey(string_key0)); - EXPECT_TRUE(dict_sp->HasKey(string_key1)); - - auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString(); - auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsInteger(); - - EXPECT_EQ(string_value0, string_sp->GetValue()); - EXPECT_EQ(int_value1, long(int_sp->GetValue())); -} - -TEST_F(PythonDataObjectsTest, TestPythonCallableCheck) { - PythonObject sys_exc_info = m_sys_module.ResolveName("exc_info"); - PythonObject none(PyRefType::Borrowed, Py_None); - - EXPECT_TRUE(PythonCallable::Check(sys_exc_info.get())); - EXPECT_FALSE(PythonCallable::Check(none.get())); -} - -TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke) { - auto list = m_builtins_module.ResolveName("list").AsType(); - PythonInteger one(1); - PythonString two("two"); - PythonTuple three = {one, two}; - - PythonTuple tuple_to_convert = {one, two, three}; - PythonObject result = list({tuple_to_convert}); - - EXPECT_TRUE(PythonList::Check(result.get())); - auto list_result = result.AsType(); - EXPECT_EQ(3U, list_result.GetSize()); - EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get()); - EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get()); - EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get()); -} - -TEST_F(PythonDataObjectsTest, TestPythonFile) { - auto file = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL), - File::eOpenOptionRead); - ASSERT_THAT_EXPECTED(file, llvm::Succeeded()); - auto py_file = PythonFile::FromFile(*file.get(), "r"); - ASSERT_THAT_EXPECTED(py_file, llvm::Succeeded()); - EXPECT_TRUE(PythonFile::Check(py_file.get().get())); -} - -TEST_F(PythonDataObjectsTest, TestObjectAttributes) { - PythonInteger py_int(42); - EXPECT_TRUE(py_int.HasAttribute("numerator")); - EXPECT_FALSE(py_int.HasAttribute("this_should_not_exist")); - - auto numerator_attr = As(py_int.GetAttributeValue("numerator")); - - EXPECT_THAT_EXPECTED(numerator_attr, llvm::HasValue(42)); -} - -TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) { - // Make up a custom dictionary with "sys" pointing to the `sys` module. - const char *key_name = "addr"; - const uint64_t value = 0xf000000000000000ull; - PythonDictionary python_dict(PyInitialValue::Empty); - PythonInteger python_ull_value(PyRefType::Owned, - PyLong_FromUnsignedLongLong(value)); - python_dict.SetItemForKey(PythonString(key_name), python_ull_value); - StructuredData::ObjectSP structured_data_sp = - python_dict.CreateStructuredObject(); - EXPECT_TRUE((bool)structured_data_sp); - if (structured_data_sp) { - StructuredData::Dictionary *structured_dict_ptr = - structured_data_sp->GetAsDictionary(); - EXPECT_TRUE(structured_dict_ptr != nullptr); - if (structured_dict_ptr) { - StructuredData::ObjectSP structured_addr_value_sp = - structured_dict_ptr->GetValueForKey(key_name); - EXPECT_TRUE((bool)structured_addr_value_sp); - const uint64_t extracted_value = - structured_addr_value_sp->GetIntegerValue(123); - EXPECT_TRUE(extracted_value == value); - } - } -} - -TEST_F(PythonDataObjectsTest, TestCallable) { - - PythonDictionary globals(PyInitialValue::Empty); - auto builtins = PythonModule::BuiltinsModule(); - llvm::Error error = globals.SetItem("__builtins__", builtins); - ASSERT_FALSE(error); - - { - PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(), - globals.get()); - ASSERT_FALSE(o == NULL); - auto lambda = Take(o); - auto arginfo = lambda.GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 1u); - } - - { - PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(), - globals.get()); - ASSERT_FALSE(o == NULL); - auto lambda = Take(o); - auto arginfo = lambda.GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 2u); - } - - { - PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input, - globals.get(), globals.get()); - ASSERT_FALSE(o == NULL); - auto lambda = Take(o); - auto arginfo = lambda.GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 2u); - } - - { - PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, globals.get(), - globals.get()); - ASSERT_FALSE(o == NULL); - auto lambda = Take(o); - auto arginfo = lambda.GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, - PythonCallable::ArgInfo::UNBOUNDED); - } - - { - PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input, - globals.get(), globals.get()); - ASSERT_FALSE(o == NULL); - auto lambda = Take(o); - auto arginfo = lambda.GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, - PythonCallable::ArgInfo::UNBOUNDED); - } - - { - const char *script = R"( -class Foo: - def bar(self, x): - return x - @classmethod - def classbar(cls, x): - return x - @staticmethod - def staticbar(x): - return x - def __call__(self, x): - return x -obj = Foo() -bar_bound = Foo().bar -bar_class = Foo().classbar -bar_static = Foo().staticbar -bar_unbound = Foo.bar - - -class OldStyle: - def __init__(self, one, two, three): - pass - -class NewStyle(object): - def __init__(self, one, two, three): - pass - -)"; - PyObject *o = - PyRun_String(script, Py_file_input, globals.get(), globals.get()); - ASSERT_FALSE(o == NULL); - Take(o); - - auto bar_bound = As(globals.GetItem("bar_bound")); - ASSERT_THAT_EXPECTED(bar_bound, llvm::Succeeded()); - auto arginfo = bar_bound.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 1u); - - auto bar_unbound = As(globals.GetItem("bar_unbound")); - ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded()); - arginfo = bar_unbound.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 2u); - - auto bar_class = As(globals.GetItem("bar_class")); - ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded()); - arginfo = bar_class.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 1u); - - auto bar_static = As(globals.GetItem("bar_static")); - ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded()); - arginfo = bar_static.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 1u); - - auto obj = As(globals.GetItem("obj")); - ASSERT_THAT_EXPECTED(obj, llvm::Succeeded()); - arginfo = obj.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 1u); - - auto oldstyle = As(globals.GetItem("OldStyle")); - ASSERT_THAT_EXPECTED(oldstyle, llvm::Succeeded()); - arginfo = oldstyle.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 3u); - - auto newstyle = As(globals.GetItem("NewStyle")); - ASSERT_THAT_EXPECTED(newstyle, llvm::Succeeded()); - arginfo = newstyle.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 3u); - } - -#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 - - // the old implementation of GetArgInfo just doesn't work on builtins. - - { - auto builtins = PythonModule::BuiltinsModule(); - auto hex = As(builtins.GetAttribute("hex")); - ASSERT_THAT_EXPECTED(hex, llvm::Succeeded()); - auto arginfo = hex.get().GetArgInfo(); - ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded()); - EXPECT_EQ(arginfo.get().max_positional_args, 1u); - } - -#endif -} - -TEST_F(PythonDataObjectsTest, TestScript) { - - static const char script[] = R"( -def factorial(n): - if n > 1: - return n * factorial(n-1) - else: - return 1; -main = factorial -)"; - - PythonScript factorial(script); - - EXPECT_THAT_EXPECTED(As(factorial(5ll)), llvm::HasValue(120)); -} - -TEST_F(PythonDataObjectsTest, TestExceptions) { - - static const char script[] = R"( -def foo(): - return bar() -def bar(): - return baz() -def baz(): - return 1 / 0 -main = foo -)"; - - PythonScript foo(script); - - EXPECT_THAT_EXPECTED( - foo(), llvm::Failed(testing::Property( - &PythonException::ReadBacktrace, - testing::AllOf(testing::ContainsRegex("line 3, in foo"), - testing::ContainsRegex("line 5, in bar"), - testing::ContainsRegex("line 7, in baz"), - testing::ContainsRegex("ZeroDivisionError"))))); - - static const char script2[] = R"( -class MyError(Exception): - def __str__(self): - return self.my_message - -def main(): - raise MyError("lol") - -)"; - - PythonScript lol(script2); - - EXPECT_THAT_EXPECTED(lol(), - llvm::Failed(testing::Property( - &PythonException::ReadBacktrace, - testing::ContainsRegex("unprintable MyError")))); -} - -TEST_F(PythonDataObjectsTest, TestRun) { - - PythonDictionary globals(PyInitialValue::Empty); - - auto x = As(runStringOneLine("40 + 2", globals, globals)); - ASSERT_THAT_EXPECTED(x, llvm::Succeeded()); - EXPECT_EQ(x.get(), 42l); - - Expected r = runStringOneLine("n = 42", globals, globals); - ASSERT_THAT_EXPECTED(r, llvm::Succeeded()); - auto y = As(globals.GetItem("n")); - ASSERT_THAT_EXPECTED(y, llvm::Succeeded()); - EXPECT_EQ(y.get(), 42l); - - const char script[] = R"( -def foobar(): - return "foo" + "bar" + "baz" -g = foobar() -)"; - - r = runStringMultiLine(script, globals, globals); - ASSERT_THAT_EXPECTED(r, llvm::Succeeded()); - auto g = As(globals.GetItem("g")); - ASSERT_THAT_EXPECTED(g, llvm::HasValue("foobarbaz")); -} \ No newline at end of file diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp deleted file mode 100644 index f93733b3a5b..00000000000 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ /dev/null @@ -1,286 +0,0 @@ -//===-- PythonTestSuite.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 "gtest/gtest.h" - -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" - -#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" -#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h" -#include "lldb/API/SBError.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" - -#include "PythonTestSuite.h" - -using namespace lldb_private; -class TestScriptInterpreterPython : public ScriptInterpreterPythonImpl { -public: - using ScriptInterpreterPythonImpl::Initialize; - using ScriptInterpreterPythonImpl::InitializePrivate; -}; - -void PythonTestSuite::SetUp() { - FileSystem::Initialize(); - HostInfoBase::Initialize(); - // ScriptInterpreterPython::Initialize() depends on HostInfo being - // initializedso it can compute the python directory etc. - TestScriptInterpreterPython::Initialize(); - TestScriptInterpreterPython::InitializePrivate(); - - // Although we don't care about concurrency for the purposes of running - // this test suite, Python requires the GIL to be locked even for - // deallocating memory, which can happen when you call Py_DECREF or - // Py_INCREF. So acquire the GIL for the entire duration of this - // test suite. - m_gil_state = PyGILState_Ensure(); -} - -void PythonTestSuite::TearDown() { - PyGILState_Release(m_gil_state); - - TestScriptInterpreterPython::Terminate(); - HostInfoBase::Terminate(); - FileSystem::Terminate(); -} - -// The following functions are the Pythonic implementations of the required -// callbacks. Because they're defined in libLLDB which we cannot link for the -// unit test, we have a 'default' implementation here. - -#if PY_MAJOR_VERSION >= 3 -extern "C" PyObject *PyInit__lldb(void) { return nullptr; } -#define LLDBSwigPyInit PyInit__lldb -#else -extern "C" void init_lldb(void) {} -#define LLDBSwigPyInit init_lldb -#endif - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" - -// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has -// C-linkage specified, but returns UDT 'llvm::Expected' which is -// incompatible with C -#if _MSC_VER -#pragma warning (push) -#pragma warning (disable : 4190) -#endif - -extern "C" llvm::Expected LLDBSwigPythonBreakpointCallbackFunction( - const char *python_function_name, const char *session_dictionary_name, - const lldb::StackFrameSP &sb_frame, - const lldb::BreakpointLocationSP &sb_bp_loc, - StructuredDataImpl *args_impl) { - return false; -} - -#if _MSC_VER -#pragma warning (pop) -#endif - -#pragma clang diagnostic pop - -extern "C" bool LLDBSwigPythonWatchpointCallbackFunction( - const char *python_function_name, const char *session_dictionary_name, - const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp) { - return false; -} - -extern "C" bool LLDBSwigPythonCallTypeScript( - const char *python_function_name, void *session_dictionary, - const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, - const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval) { - return false; -} - -extern "C" void * -LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, - const char *session_dictionary_name, - const lldb::ValueObjectSP &valobj_sp) { - return nullptr; -} - -extern "C" void * -LLDBSwigPythonCreateCommandObject(const char *python_class_name, - const char *session_dictionary_name, - const lldb::DebuggerSP debugger_sp) { - return nullptr; -} - -extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan( - const char *python_class_name, const char *session_dictionary_name, - StructuredDataImpl *args_data, - std::string &error_string, - const lldb::ThreadPlanSP &thread_plan_sp) { - return nullptr; -} - -extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor, - const char *method_name, - Event *event_sp, bool &got_error) { - return false; -} - -extern "C" void *LLDBSwigPythonCreateScriptedBreakpointResolver( - const char *python_class_name, const char *session_dictionary_name, - lldb_private::StructuredDataImpl *args, lldb::BreakpointSP &bkpt_sp) { - return nullptr; -} - -extern "C" unsigned int -LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name, - lldb_private::SymbolContext *sym_ctx) { - return 0; -} - -extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor, - uint32_t max) { - return 0; -} - -extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor, - uint32_t idx) { - return nullptr; -} - -extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor, - const char *child_name) { - return 0; -} - -extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data) { - return nullptr; -} - -extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data) { - return nullptr; -} - -extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data) { - return nullptr; -} - -extern lldb::ValueObjectSP -LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data) { - return nullptr; -} - -extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance(void *implementor) { - return false; -} - -extern "C" bool -LLDBSwigPython_MightHaveChildrenSynthProviderInstance(void *implementor) { - return false; -} - -extern "C" void * -LLDBSwigPython_GetValueSynthProviderInstance(void *implementor) { - return nullptr; -} - -extern "C" bool -LLDBSwigPythonCallCommand(const char *python_function_name, - const char *session_dictionary_name, - lldb::DebuggerSP &debugger, const char *args, - lldb_private::CommandReturnObject &cmd_retobj, - lldb::ExecutionContextRefSP exe_ctx_ref_sp) { - return false; -} - -extern "C" bool -LLDBSwigPythonCallCommandObject(void *implementor, lldb::DebuggerSP &debugger, - const char *args, - lldb_private::CommandReturnObject &cmd_retobj, - lldb::ExecutionContextRefSP exe_ctx_ref_sp) { - return false; -} - -extern "C" bool -LLDBSwigPythonCallModuleInit(const char *python_module_name, - const char *session_dictionary_name, - lldb::DebuggerSP &debugger) { - return false; -} - -extern "C" void * -LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, - const char *session_dictionary_name, - const lldb::ProcessSP &process_sp) { - return nullptr; -} - -extern "C" void *LLDBSwigPythonCreateScriptedProcess( - const char *python_class_name, const char *session_dictionary_name, - const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl, - std::string &error_string) { - return nullptr; -} - -extern "C" void * -LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, - const char *session_dictionary_name) { - return nullptr; -} - -extern "C" void * -LLDBSwigPython_GetRecognizedArguments(void *implementor, - const lldb::StackFrameSP &frame_sp) { - return nullptr; -} - -extern "C" bool LLDBSWIGPythonRunScriptKeywordProcess( - const char *python_function_name, const char *session_dictionary_name, - lldb::ProcessSP &process, std::string &output) { - return false; -} - -extern "C" bool LLDBSWIGPythonRunScriptKeywordThread( - const char *python_function_name, const char *session_dictionary_name, - lldb::ThreadSP &thread, std::string &output) { - return false; -} - -extern "C" bool LLDBSWIGPythonRunScriptKeywordTarget( - const char *python_function_name, const char *session_dictionary_name, - lldb::TargetSP &target, std::string &output) { - return false; -} - -extern "C" bool LLDBSWIGPythonRunScriptKeywordFrame( - const char *python_function_name, const char *session_dictionary_name, - lldb::StackFrameSP &frame, std::string &output) { - return false; -} - -extern "C" bool LLDBSWIGPythonRunScriptKeywordValue( - const char *python_function_name, const char *session_dictionary_name, - lldb::ValueObjectSP &value, std::string &output) { - return false; -} - -extern "C" void * -LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, - const lldb::TargetSP &target_sp) { - return nullptr; -} - -extern "C" void *LLDBSwigPythonCreateScriptedStopHook( - lldb::TargetSP target_sp, const char *python_class_name, - const char *session_dictionary_name, - lldb_private::StructuredDataImpl *args_impl, Status &error) { - return nullptr; -} - -extern "C" bool -LLDBSwigPythonStopHookCallHandleStop(void *implementor, - lldb::ExecutionContextRefSP exc_ctx_sp, - lldb::StreamSP stream) { - return false; -} diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.h b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.h deleted file mode 100644 index 07e3eba9e9d..00000000000 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.h +++ /dev/null @@ -1,21 +0,0 @@ -//===-- PythonTestSuite.cpp -------------------------------------*- C++ -*-===// -// -// 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 "gtest/gtest.h" - -using namespace lldb_private; - -class PythonTestSuite : public testing::Test { -public: - void SetUp() override; - - void TearDown() override; - -private: - PyGILState_STATE m_gil_state; -}; diff --git a/gnu/llvm/lldb/unittests/Signals/CMakeLists.txt b/gnu/llvm/lldb/unittests/Signals/CMakeLists.txt deleted file mode 100644 index e3f2e884d93..00000000000 --- a/gnu/llvm/lldb/unittests/Signals/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_lldb_unittest(SignalsTests - UnixSignalsTest.cpp - - LINK_LIBS - lldbTarget - ) diff --git a/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp b/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp deleted file mode 100644 index 1a53f0a2495..00000000000 --- a/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp +++ /dev/null @@ -1,139 +0,0 @@ -//===-- UnixSignalsTest.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 - -#include "gtest/gtest.h" - -#include "lldb/Target/UnixSignals.h" -#include "llvm/Support/FormatVariadic.h" - -using namespace lldb; -using namespace lldb_private; -using llvm::None; - -class TestSignals : public UnixSignals { -public: - TestSignals() { - m_signals.clear(); - AddSignal(2, "SIG2", false, true, true, "DESC2"); - AddSignal(4, "SIG4", true, false, true, "DESC4"); - AddSignal(8, "SIG8", true, true, true, "DESC8"); - AddSignal(16, "SIG16", true, false, false, "DESC16"); - } -}; - -void ExpectEqArrays(llvm::ArrayRef expected, - llvm::ArrayRef observed, const char *file, - int line) { - std::string location = llvm::formatv("{0}:{1}", file, line); - ASSERT_EQ(expected.size(), observed.size()) << location; - - for (size_t i = 0; i < observed.size(); ++i) { - ASSERT_EQ(expected[i], observed[i]) - << "array index: " << i << "location:" << location; - } -} - -#define EXPECT_EQ_ARRAYS(expected, observed) \ - ExpectEqArrays((expected), (observed), __FILE__, __LINE__); - -TEST(UnixSignalsTest, Iteration) { - TestSignals signals; - - EXPECT_EQ(4, signals.GetNumSignals()); - EXPECT_EQ(2, signals.GetFirstSignalNumber()); - EXPECT_EQ(4, signals.GetNextSignalNumber(2)); - EXPECT_EQ(8, signals.GetNextSignalNumber(4)); - EXPECT_EQ(16, signals.GetNextSignalNumber(8)); - EXPECT_EQ(LLDB_INVALID_SIGNAL_NUMBER, signals.GetNextSignalNumber(16)); -} - -TEST(UnixSignalsTest, GetInfo) { - TestSignals signals; - - bool should_suppress = false, should_stop = false, should_notify = false; - int32_t signo = 4; - std::string name = - signals.GetSignalInfo(signo, should_suppress, should_stop, should_notify); - EXPECT_EQ("SIG4", name); - EXPECT_EQ(true, should_suppress); - EXPECT_EQ(false, should_stop); - EXPECT_EQ(true, should_notify); - - EXPECT_EQ(true, signals.GetShouldSuppress(signo)); - EXPECT_EQ(false, signals.GetShouldStop(signo)); - EXPECT_EQ(true, signals.GetShouldNotify(signo)); - EXPECT_EQ(name, signals.GetSignalAsCString(signo)); -} - -TEST(UnixSignalsTest, VersionChange) { - TestSignals signals; - - int32_t signo = 8; - uint64_t ver = signals.GetVersion(); - EXPECT_GT(ver, 0ull); - EXPECT_EQ(true, signals.GetShouldSuppress(signo)); - EXPECT_EQ(true, signals.GetShouldStop(signo)); - EXPECT_EQ(true, signals.GetShouldNotify(signo)); - - EXPECT_EQ(signals.GetVersion(), ver); - - signals.SetShouldSuppress(signo, false); - EXPECT_LT(ver, signals.GetVersion()); - ver = signals.GetVersion(); - - signals.SetShouldStop(signo, true); - EXPECT_LT(ver, signals.GetVersion()); - ver = signals.GetVersion(); - - signals.SetShouldNotify(signo, false); - EXPECT_LT(ver, signals.GetVersion()); - ver = signals.GetVersion(); - - EXPECT_EQ(false, signals.GetShouldSuppress(signo)); - EXPECT_EQ(true, signals.GetShouldStop(signo)); - EXPECT_EQ(false, signals.GetShouldNotify(signo)); - - EXPECT_EQ(ver, signals.GetVersion()); -} - -TEST(UnixSignalsTest, GetFilteredSignals) { - TestSignals signals; - - auto all_signals = signals.GetFilteredSignals(None, None, None); - std::vector expected = {2, 4, 8, 16}; - EXPECT_EQ_ARRAYS(expected, all_signals); - - auto supressed = signals.GetFilteredSignals(true, None, None); - expected = {4, 8, 16}; - EXPECT_EQ_ARRAYS(expected, supressed); - - auto not_supressed = signals.GetFilteredSignals(false, None, None); - expected = {2}; - EXPECT_EQ_ARRAYS(expected, not_supressed); - - auto stopped = signals.GetFilteredSignals(None, true, None); - expected = {2, 8}; - EXPECT_EQ_ARRAYS(expected, stopped); - - auto not_stopped = signals.GetFilteredSignals(None, false, None); - expected = {4, 16}; - EXPECT_EQ_ARRAYS(expected, not_stopped); - - auto notified = signals.GetFilteredSignals(None, None, true); - expected = {2, 4, 8}; - EXPECT_EQ_ARRAYS(expected, notified); - - auto not_notified = signals.GetFilteredSignals(None, None, false); - expected = {16}; - EXPECT_EQ_ARRAYS(expected, not_notified); - - auto signal4 = signals.GetFilteredSignals(true, false, true); - expected = {4}; - EXPECT_EQ_ARRAYS(expected, signal4); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt b/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt deleted file mode 100644 index 748faf33b55..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -add_lldb_unittest(SymbolTests - LocateSymbolFileTest.cpp - PostfixExpressionTest.cpp - TestTypeSystem.cpp - TestTypeSystemClang.cpp - TestClangASTImporter.cpp - TestDWARFCallFrameInfo.cpp - TestType.cpp - TestLineEntry.cpp - - LINK_LIBS - lldbHost - lldbSymbol - lldbUtilityHelpers - lldbPluginObjectFileELF - lldbPluginObjectFileMachO - lldbPluginSymbolFileDWARF - lldbPluginSymbolFileSymtab - lldbPluginTypeSystemClang - LLVMTestingSupport - ) - -set(test_inputs - inlined-functions.yaml - ) -add_unittest_inputs(SymbolTests "${test_inputs}") diff --git a/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml b/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml deleted file mode 100644 index 8498cf7f6d3..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml +++ /dev/null @@ -1,929 +0,0 @@ ---- !mach-o -FileHeader: - magic: 0xFEEDFACF - cputype: 0x01000007 - cpusubtype: 0x00000003 - filetype: 0x00000001 - ncmds: 4 - sizeofcmds: 1160 - flags: 0x00002000 - reserved: 0x00000000 -LoadCommands: - - cmd: LC_SEGMENT_64 - cmdsize: 1032 - segname: '' - vmaddr: 0 - vmsize: 2022 - fileoff: 1192 - filesize: 2022 - maxprot: 7 - initprot: 7 - nsects: 6 - flags: 0 - Sections: - - sectname: __text - segname: __TEXT - addr: 0x0000000000000000 - size: 224 - offset: 0x000004A8 - align: 4 - reloff: 0x00000C90 - nreloc: 1 - flags: 0x80000400 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 - - sectname: __debug_str - segname: __DWARF - addr: 0x00000000000000E0 - size: 223 - offset: 0x00000588 - align: 0 - reloff: 0x00000000 - nreloc: 0 - flags: 0x02000000 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 - - sectname: __debug_abbrev - segname: __DWARF - addr: 0x00000000000001BF - size: 190 - offset: 0x00000667 - align: 0 - reloff: 0x00000000 - nreloc: 0 - flags: 0x02000000 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 - - sectname: __debug_info - segname: __DWARF - addr: 0x000000000000027D - size: 583 - offset: 0x00000725 - align: 0 - reloff: 0x00000C98 - nreloc: 8 - flags: 0x02000000 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 - - sectname: __compact_unwind - segname: __LD - addr: 0x0000000000000670 - size: 64 - offset: 0x00000B18 - align: 3 - reloff: 0x00000CD8 - nreloc: 2 - flags: 0x02000000 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 - - sectname: __debug_line - segname: __DWARF - addr: 0x0000000000000718 - size: 206 - offset: 0x00000BC0 - align: 0 - reloff: 0x00000CE8 - nreloc: 1 - flags: 0x02000000 - reserved1: 0x00000000 - reserved2: 0x00000000 - reserved3: 0x00000000 - - cmd: LC_BUILD_VERSION - cmdsize: 24 - platform: 1 - minos: 658944 - sdk: 658944 - ntools: 0 - - cmd: LC_SYMTAB - cmdsize: 24 - symoff: 3312 - nsyms: 2 - stroff: 3344 - strsize: 20 - - cmd: LC_DYSYMTAB - cmdsize: 80 - ilocalsym: 0 - nlocalsym: 0 - iextdefsym: 0 - nextdefsym: 2 - iundefsym: 2 - nundefsym: 0 - tocoff: 0 - ntoc: 0 - modtaboff: 0 - nmodtab: 0 - extrefsymoff: 0 - nextrefsyms: 0 - indirectsymoff: 0 - nindirectsyms: 0 - extreloff: 0 - nextrel: 0 - locreloff: 0 - nlocrel: 0 -LinkEditData: - NameList: - - n_strx: 7 - n_type: 0x0F - n_sect: 1 - n_desc: 0 - n_value: 0 - - n_strx: 1 - n_type: 0x0F - n_sect: 1 - n_desc: 0 - n_value: 32 - StringTable: - - '' - - _main - - __Z4sum3iii - - '' -DWARF: - debug_str: - - 'Apple LLVM version 10.0.1 (clang-1001.0.46.3)' - - inlined-functions.cpp - - '/Users/aadsm/Projects/llvm-project/lldb/unittests/Symbol/Inputs' - - sum3 - - _Z4sum3iii - - _Z4sum2ii - - sum2 - - int - - a - - b - - result - - _Z4sum4iiii - - sum4 - - c - - d - - main - - argc - - argv - - char - - sum - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_producer - Form: DW_FORM_strp - - Attribute: DW_AT_language - Form: DW_FORM_data2 - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_stmt_list - Form: DW_FORM_sec_offset - - Attribute: DW_AT_comp_dir - Form: DW_FORM_strp - - Attribute: DW_AT_low_pc - Form: DW_FORM_addr - - Attribute: DW_AT_high_pc - Form: DW_FORM_data4 - - Code: 0x00000002 - Tag: DW_TAG_subprogram - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_low_pc - Form: DW_FORM_addr - - Attribute: DW_AT_high_pc - Form: DW_FORM_data4 - - Attribute: DW_AT_frame_base - Form: DW_FORM_exprloc - - Attribute: DW_AT_linkage_name - Form: DW_FORM_strp - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Attribute: DW_AT_external - Form: DW_FORM_flag_present - - Code: 0x00000003 - Tag: DW_TAG_formal_parameter - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_location - Form: DW_FORM_exprloc - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Code: 0x00000004 - Tag: DW_TAG_variable - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_location - Form: DW_FORM_exprloc - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Code: 0x00000005 - Tag: DW_TAG_subprogram - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_linkage_name - Form: DW_FORM_strp - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Attribute: DW_AT_external - Form: DW_FORM_flag_present - - Attribute: DW_AT_inline - Form: DW_FORM_data1 - - Code: 0x00000006 - Tag: DW_TAG_formal_parameter - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Code: 0x00000007 - Tag: DW_TAG_variable - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Code: 0x00000008 - Tag: DW_TAG_base_type - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_encoding - Form: DW_FORM_data1 - - Attribute: DW_AT_byte_size - Form: DW_FORM_data1 - - Code: 0x00000009 - Tag: DW_TAG_subprogram - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_low_pc - Form: DW_FORM_addr - - Attribute: DW_AT_high_pc - Form: DW_FORM_data4 - - Attribute: DW_AT_frame_base - Form: DW_FORM_exprloc - - Attribute: DW_AT_name - Form: DW_FORM_strp - - Attribute: DW_AT_decl_file - Form: DW_FORM_data1 - - Attribute: DW_AT_decl_line - Form: DW_FORM_data1 - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - - Attribute: DW_AT_external - Form: DW_FORM_flag_present - - Code: 0x0000000A - Tag: DW_TAG_inlined_subroutine - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_abstract_origin - Form: DW_FORM_ref4 - - Attribute: DW_AT_low_pc - Form: DW_FORM_addr - - Attribute: DW_AT_high_pc - Form: DW_FORM_data4 - - Attribute: DW_AT_call_file - Form: DW_FORM_data1 - - Attribute: DW_AT_call_line - Form: DW_FORM_data1 - - Code: 0x0000000B - Tag: DW_TAG_formal_parameter - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_location - Form: DW_FORM_exprloc - - Attribute: DW_AT_abstract_origin - Form: DW_FORM_ref4 - - Code: 0x0000000C - Tag: DW_TAG_variable - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_location - Form: DW_FORM_exprloc - - Attribute: DW_AT_abstract_origin - Form: DW_FORM_ref4 - - Code: 0x0000000D - Tag: DW_TAG_pointer_type - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_type - Form: DW_FORM_ref4 - debug_info: - - Version: 4 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000001 - Values: - - Value: 0x0000000000000000 - - Value: 0x0000000000000004 - - Value: 0x000000000000002E - - Value: 0x0000000000000000 - - Value: 0x0000000000000044 - - Value: 0x0000000000000000 - - Value: 0x00000000000000E0 - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000000 - - Value: 0x000000000000001E - - Value: 0x0000000000000001 - BlockData: - - 0x56 - - Value: 0x0000000000000089 - - Value: 0x0000000000000084 - - Value: 0x0000000000000001 - - Value: 0x0000000000000006 - - Value: 0x00000000000000B2 - - Value: 0x0000000000000001 - - AbbrCode: 0x00000003 - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x7C - - Value: 0x00000000000000A7 - - Value: 0x0000000000000001 - - Value: 0x0000000000000006 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000003 - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x78 - - Value: 0x00000000000000A9 - - Value: 0x0000000000000001 - - Value: 0x0000000000000006 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000003 - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x74 - - Value: 0x00000000000000C3 - - Value: 0x0000000000000001 - - Value: 0x0000000000000006 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000004 - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x70 - - Value: 0x00000000000000AB - - Value: 0x0000000000000001 - - Value: 0x0000000000000007 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000000 - - AbbrCode: 0x00000005 - Values: - - Value: 0x0000000000000094 - - Value: 0x000000000000009E - - Value: 0x0000000000000001 - - Value: 0x0000000000000001 - - Value: 0x00000000000000B2 - - Value: 0x0000000000000001 - - Value: 0x0000000000000001 - - AbbrCode: 0x00000006 - Values: - - Value: 0x00000000000000A7 - - Value: 0x0000000000000001 - - Value: 0x0000000000000001 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000006 - Values: - - Value: 0x00000000000000A9 - - Value: 0x0000000000000001 - - Value: 0x0000000000000001 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000007 - Values: - - Value: 0x00000000000000AB - - Value: 0x0000000000000001 - - Value: 0x0000000000000002 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000000 - - AbbrCode: 0x00000008 - Values: - - Value: 0x00000000000000A3 - - Value: 0x0000000000000005 - - Value: 0x0000000000000004 - - AbbrCode: 0x00000005 - Values: - - Value: 0x00000000000000B2 - - Value: 0x00000000000000BE - - Value: 0x0000000000000001 - - Value: 0x000000000000000B - - Value: 0x00000000000000B2 - - Value: 0x0000000000000001 - - Value: 0x0000000000000001 - - AbbrCode: 0x00000006 - Values: - - Value: 0x00000000000000A7 - - Value: 0x0000000000000001 - - Value: 0x000000000000000B - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000006 - Values: - - Value: 0x00000000000000A9 - - Value: 0x0000000000000001 - - Value: 0x000000000000000B - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000006 - Values: - - Value: 0x00000000000000C3 - - Value: 0x0000000000000001 - - Value: 0x000000000000000B - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000006 - Values: - - Value: 0x00000000000000C5 - - Value: 0x0000000000000001 - - Value: 0x000000000000000B - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000007 - Values: - - Value: 0x00000000000000AB - - Value: 0x0000000000000001 - - Value: 0x000000000000000C - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000000 - - AbbrCode: 0x00000009 - Values: - - Value: 0x0000000000000020 - - Value: 0x00000000000000C0 - - Value: 0x0000000000000001 - BlockData: - - 0x56 - - Value: 0x00000000000000C7 - - Value: 0x0000000000000001 - - Value: 0x0000000000000011 - - Value: 0x00000000000000B2 - - Value: 0x0000000000000001 - - AbbrCode: 0x00000003 - Values: - - Value: 0x0000000000000003 - BlockData: - - 0x91 - - 0xB4 - - 0x7F - - Value: 0x00000000000000CC - - Value: 0x0000000000000001 - - Value: 0x0000000000000011 - - Value: 0x00000000000000B2 - - AbbrCode: 0x00000003 - Values: - - Value: 0x0000000000000003 - BlockData: - - 0x91 - - 0xA8 - - 0x7F - - Value: 0x00000000000000D1 - - Value: 0x0000000000000001 - - Value: 0x0000000000000011 - - Value: 0x0000000000000235 - - AbbrCode: 0x00000004 - Values: - - Value: 0x0000000000000003 - BlockData: - - 0x91 - - 0xA4 - - 0x7F - - Value: 0x00000000000000DB - - Value: 0x0000000000000001 - - Value: 0x0000000000000013 - - Value: 0x00000000000000B2 - - AbbrCode: 0x0000000A - Values: - - Value: 0x0000000000000080 - - Value: 0x000000000000005A - - Value: 0x0000000000000025 - - Value: 0x0000000000000001 - - Value: 0x0000000000000012 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x44 - - Value: 0x0000000000000090 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x40 - - Value: 0x000000000000009B - - AbbrCode: 0x0000000C - Values: - - Value: 0x0000000000000003 - BlockData: - - 0x91 - - 0xBC - - 0x7F - - Value: 0x00000000000000A6 - - AbbrCode: 0x00000000 - - AbbrCode: 0x0000000A - Values: - - Value: 0x00000000000000B9 - - Value: 0x000000000000007F - - Value: 0x000000000000003C - - Value: 0x0000000000000001 - - Value: 0x0000000000000013 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x64 - - Value: 0x00000000000000C9 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x60 - - Value: 0x00000000000000D4 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x5C - - Value: 0x00000000000000DF - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x58 - - Value: 0x00000000000000EA - - AbbrCode: 0x0000000C - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x54 - - Value: 0x00000000000000F5 - - AbbrCode: 0x0000000A - Values: - - Value: 0x0000000000000080 - - Value: 0x000000000000008B - - Value: 0x000000000000000C - - Value: 0x0000000000000001 - - Value: 0x000000000000000C - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x70 - - Value: 0x0000000000000090 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x6C - - Value: 0x000000000000009B - - AbbrCode: 0x0000000C - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x68 - - Value: 0x00000000000000A6 - - AbbrCode: 0x00000000 - - AbbrCode: 0x0000000A - Values: - - Value: 0x0000000000000080 - - Value: 0x00000000000000A3 - - Value: 0x0000000000000009 - - Value: 0x0000000000000001 - - Value: 0x000000000000000C - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x7C - - Value: 0x0000000000000090 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x78 - - Value: 0x000000000000009B - - AbbrCode: 0x0000000C - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x74 - - Value: 0x00000000000000A6 - - AbbrCode: 0x00000000 - - AbbrCode: 0x00000000 - - AbbrCode: 0x0000000A - Values: - - Value: 0x0000000000000080 - - Value: 0x00000000000000CC - - Value: 0x0000000000000009 - - Value: 0x0000000000000001 - - Value: 0x0000000000000014 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x50 - - Value: 0x0000000000000090 - - AbbrCode: 0x0000000B - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x4C - - Value: 0x000000000000009B - - AbbrCode: 0x0000000C - Values: - - Value: 0x0000000000000002 - BlockData: - - 0x91 - - 0x48 - - Value: 0x00000000000000A6 - - AbbrCode: 0x00000000 - - AbbrCode: 0x00000000 - - AbbrCode: 0x0000000D - Values: - - Value: 0x000000000000023A - - AbbrCode: 0x0000000D - Values: - - Value: 0x000000000000023F - - AbbrCode: 0x00000008 - Values: - - Value: 0x00000000000000D6 - - Value: 0x0000000000000006 - - Value: 0x0000000000000001 - - AbbrCode: 0x00000000 - debug_line: - - Length: 202 - Version: 4 - PrologueLength: 45 - MinInstLength: 1 - MaxOpsPerInst: 1 - DefaultIsStmt: 1 - LineBase: 251 - LineRange: 14 - OpcodeBase: 13 - StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] - Files: - - Name: inlined-functions.cpp - DirIdx: 0 - ModTime: 0 - Length: 0 - Opcodes: - - Opcode: DW_LNS_extended_op - ExtLen: 9 - SubOpcode: DW_LNE_set_address - Data: 0 - - Opcode: 0x17 - Data: 0 - - Opcode: DW_LNS_set_column - Data: 18 - - Opcode: DW_LNS_set_prologue_end - Data: 18 - - Opcode: 0xC9 - Data: 18 - - Opcode: DW_LNS_set_column - Data: 20 - - Opcode: DW_LNS_negate_stmt - Data: 20 - - Opcode: 0x3C - Data: 20 - - Opcode: DW_LNS_set_column - Data: 24 - - Opcode: 0x3C - Data: 24 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: 0x3C - Data: 9 - - Opcode: DW_LNS_set_column - Data: 12 - - Opcode: DW_LNS_negate_stmt - Data: 12 - - Opcode: 0x3D - Data: 12 - - Opcode: DW_LNS_set_column - Data: 5 - - Opcode: DW_LNS_negate_stmt - Data: 5 - - Opcode: 0x3C - Data: 5 - - Opcode: DW_LNS_set_column - Data: 0 - - Opcode: DW_LNS_negate_stmt - Data: 0 - - Opcode: DW_LNS_advance_line - SData: 9 - Data: 0 - - Opcode: 0x4A - Data: 0 - - Opcode: DW_LNS_set_column - Data: 5 - - Opcode: DW_LNS_set_prologue_end - Data: 5 - - Opcode: DW_LNS_const_add_pc - Data: 5 - - Opcode: 0x59 - Data: 5 - - Opcode: DW_LNS_set_column - Data: 18 - - Opcode: DW_LNS_advance_line - SData: -16 - Data: 18 - - Opcode: DW_LNS_advance_pc - Data: 36 - - Opcode: DW_LNS_copy - Data: 36 - - Opcode: DW_LNS_set_column - Data: 20 - - Opcode: DW_LNS_negate_stmt - Data: 20 - - Opcode: 0x3C - Data: 20 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: 0x3C - Data: 9 - - Opcode: DW_LNS_set_column - Data: 23 - - Opcode: DW_LNS_negate_stmt - Data: 23 - - Opcode: DW_LNS_advance_line - SData: 10 - Data: 23 - - Opcode: DW_LNS_const_add_pc - Data: 23 - - Opcode: 0xD6 - Data: 23 - - Opcode: DW_LNS_set_column - Data: 26 - - Opcode: DW_LNS_negate_stmt - Data: 26 - - Opcode: 0x3C - Data: 26 - - Opcode: DW_LNS_set_column - Data: 18 - - Opcode: DW_LNS_negate_stmt - Data: 18 - - Opcode: DW_LNS_advance_line - SData: -10 - Data: 18 - - Opcode: 0x90 - Data: 18 - - Opcode: DW_LNS_set_column - Data: 20 - - Opcode: DW_LNS_negate_stmt - Data: 20 - - Opcode: 0x3C - Data: 20 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: 0x3C - Data: 9 - - Opcode: DW_LNS_set_column - Data: 12 - - Opcode: DW_LNS_negate_stmt - Data: 12 - - Opcode: 0x3D - Data: 12 - - Opcode: DW_LNS_set_column - Data: 36 - - Opcode: DW_LNS_advance_line - SData: 9 - Data: 36 - - Opcode: 0x3C - Data: 36 - - Opcode: DW_LNS_set_column - Data: 39 - - Opcode: DW_LNS_negate_stmt - Data: 39 - - Opcode: 0x3C - Data: 39 - - Opcode: DW_LNS_set_column - Data: 18 - - Opcode: DW_LNS_negate_stmt - Data: 18 - - Opcode: DW_LNS_advance_line - SData: -10 - Data: 18 - - Opcode: 0x90 - Data: 18 - - Opcode: DW_LNS_set_column - Data: 20 - - Opcode: DW_LNS_negate_stmt - Data: 20 - - Opcode: 0x3C - Data: 20 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: 0x3C - Data: 9 - - Opcode: DW_LNS_set_column - Data: 29 - - Opcode: DW_LNS_negate_stmt - Data: 29 - - Opcode: DW_LNS_advance_line - SData: 10 - Data: 29 - - Opcode: 0x3C - Data: 29 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: DW_LNS_negate_stmt - Data: 9 - - Opcode: 0x3C - Data: 9 - - Opcode: DW_LNS_set_column - Data: 12 - - Opcode: DW_LNS_negate_stmt - Data: 12 - - Opcode: 0x3D - Data: 12 - - Opcode: 0x67 - Data: 12 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: 0x41 - Data: 9 - - Opcode: DW_LNS_set_column - Data: 18 - - Opcode: DW_LNS_advance_line - SData: -17 - Data: 18 - - Opcode: DW_LNS_const_add_pc - Data: 18 - - Opcode: 0x12 - Data: 18 - - Opcode: DW_LNS_set_column - Data: 20 - - Opcode: DW_LNS_negate_stmt - Data: 20 - - Opcode: 0x3C - Data: 20 - - Opcode: DW_LNS_set_column - Data: 9 - - Opcode: 0x3C - Data: 9 - - Opcode: DW_LNS_set_column - Data: 5 - - Opcode: DW_LNS_negate_stmt - Data: 5 - - Opcode: DW_LNS_advance_line - SData: 19 - Data: 5 - - Opcode: 0x3C - Data: 5 - - Opcode: DW_LNS_advance_pc - Data: 11 - - Opcode: DW_LNS_extended_op - ExtLen: 1 - SubOpcode: DW_LNE_end_sequence - Data: 11 -... diff --git a/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp b/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp deleted file mode 100644 index c51b1ba4904..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===-- SymbolsTest.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 "gtest/gtest.h" - -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/LocateSymbolFile.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/Reproducer.h" - -using namespace lldb_private; - -namespace { -class SymbolsTest : public ::testing::Test { -public: - SubsystemRAII subsystems; -}; -} // namespace - -TEST_F( - SymbolsTest, - TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) { - ModuleSpec module_spec; - FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); - FileSpec symbol_file_spec = - Symbols::LocateExecutableSymbolFile(module_spec, search_paths); - EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty()); -} - -TEST_F(SymbolsTest, - LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) { - ModuleSpec module_spec; - // using a GUID here because the symbol file shouldn't actually exist on disk - module_spec.GetSymbolFileSpec().SetFile( - "4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native); - FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); - FileSpec symbol_file_spec = - Symbols::LocateExecutableSymbolFile(module_spec, search_paths); - EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty()); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp b/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp deleted file mode 100644 index 9f66aeed6b6..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp +++ /dev/null @@ -1,194 +0,0 @@ -//===-- PostfixExpressionTest.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 "lldb/Symbol/PostfixExpression.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/DebugInfo/DWARF/DWARFExpression.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/raw_ostream.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::postfix; - -static std::string ToString(BinaryOpNode::OpType type) { - switch (type) { - case BinaryOpNode::Align: - return "@"; - case BinaryOpNode::Minus: - return "-"; - case BinaryOpNode::Plus: - return "+"; - } - llvm_unreachable("Fully covered switch!"); -} - -static std::string ToString(UnaryOpNode::OpType type) { - switch (type) { - case UnaryOpNode::Deref: - return "^"; - } - llvm_unreachable("Fully covered switch!"); -} - -struct ASTPrinter : public Visitor { -protected: - std::string Visit(BinaryOpNode &binary, Node *&) override { - return std::string( - llvm::formatv("{0}({1}, {2})", ToString(binary.GetOpType()), - Dispatch(binary.Left()), Dispatch(binary.Right()))); - } - - std::string Visit(InitialValueNode &, Node *&) override { return "InitialValue"; } - - std::string Visit(IntegerNode &integer, Node *&) override { - return std::string(llvm::formatv("int({0})", integer.GetValue())); - } - - std::string Visit(RegisterNode ®, Node *&) override { - return std::string(llvm::formatv("reg({0})", reg.GetRegNum())); - } - - std::string Visit(SymbolNode &symbol, Node *&) override { - return std::string(symbol.GetName()); - } - - std::string Visit(UnaryOpNode &unary, Node *&) override { - return std::string(llvm::formatv("{0}({1})", ToString(unary.GetOpType()), - Dispatch(unary.Operand()))); - } - -public: - static std::string Print(Node *node) { - if (node) - return ASTPrinter().Dispatch(node); - return "nullptr"; - } -}; - -static std::string ParseOneAndStringify(llvm::StringRef expr) { - llvm::BumpPtrAllocator alloc; - return ASTPrinter::Print(ParseOneExpression(expr, alloc)); -} - -TEST(PostfixExpression, ParseOneExpression) { - EXPECT_EQ("int(47)", ParseOneAndStringify("47")); - EXPECT_EQ("$foo", ParseOneAndStringify("$foo")); - EXPECT_EQ("+(int(1), int(2))", ParseOneAndStringify("1 2 +")); - EXPECT_EQ("-(int(1), int(2))", ParseOneAndStringify("1 2 -")); - EXPECT_EQ("@(int(1), int(2))", ParseOneAndStringify("1 2 @")); - EXPECT_EQ("+(int(1), +(int(2), int(3)))", ParseOneAndStringify("1 2 3 + +")); - EXPECT_EQ("+(+(int(1), int(2)), int(3))", ParseOneAndStringify("1 2 + 3 +")); - EXPECT_EQ("^(int(1))", ParseOneAndStringify("1 ^")); - EXPECT_EQ("^(^(int(1)))", ParseOneAndStringify("1 ^ ^")); - EXPECT_EQ("^(+(int(1), ^(int(2))))", ParseOneAndStringify("1 2 ^ + ^")); - EXPECT_EQ("-($foo, int(47))", ParseOneAndStringify("$foo 47 -")); - EXPECT_EQ("+(int(47), int(-42))", ParseOneAndStringify("47 -42 +")); - - EXPECT_EQ("nullptr", ParseOneAndStringify("+")); - EXPECT_EQ("nullptr", ParseOneAndStringify("^")); - EXPECT_EQ("nullptr", ParseOneAndStringify("1 +")); - EXPECT_EQ("nullptr", ParseOneAndStringify("1 2 ^")); - EXPECT_EQ("nullptr", ParseOneAndStringify("1 2 3 +")); - EXPECT_EQ("nullptr", ParseOneAndStringify("^ 1")); - EXPECT_EQ("nullptr", ParseOneAndStringify("+ 1 2")); - EXPECT_EQ("nullptr", ParseOneAndStringify("1 + 2")); - EXPECT_EQ("nullptr", ParseOneAndStringify("1 2")); - EXPECT_EQ("nullptr", ParseOneAndStringify("")); -} - -static std::vector> -ParseFPOAndStringify(llvm::StringRef prog) { - llvm::BumpPtrAllocator alloc; - std::vector> parsed = - ParseFPOProgram(prog, alloc); - std::vector> result; - for (const auto &p : parsed) - result.emplace_back(p.first.str(), ASTPrinter::Print(p.second)); - return result; -} - -TEST(PostfixExpression, ParseFPOProgram) { - EXPECT_THAT(ParseFPOAndStringify("a 1 ="), - testing::ElementsAre(std::make_pair("a", "int(1)"))); - EXPECT_THAT(ParseFPOAndStringify("a 1 = b 2 3 + ="), - testing::ElementsAre(std::make_pair("a", "int(1)"), - std::make_pair("b", "+(int(2), int(3))"))); - - EXPECT_THAT(ParseFPOAndStringify(""), testing::IsEmpty()); - EXPECT_THAT(ParseFPOAndStringify("="), testing::IsEmpty()); - EXPECT_THAT(ParseFPOAndStringify("a 1"), testing::IsEmpty()); - EXPECT_THAT(ParseFPOAndStringify("a 1 = ="), testing::IsEmpty()); - EXPECT_THAT(ParseFPOAndStringify("a 1 + ="), testing::IsEmpty()); - EXPECT_THAT(ParseFPOAndStringify("= a 1 ="), testing::IsEmpty()); -} - -static std::string ParseAndGenerateDWARF(llvm::StringRef expr) { - llvm::BumpPtrAllocator alloc; - Node *ast = ParseOneExpression(expr, alloc); - if (!ast) - return "Parse failed."; - if (!ResolveSymbols(ast, [&](SymbolNode &symbol) -> Node * { - if (symbol.GetName() == "INIT") - return MakeNode(alloc); - - uint32_t num; - if (to_integer(symbol.GetName().drop_front(), num)) - return MakeNode(alloc, num); - return nullptr; - })) { - return "Resolution failed."; - } - - const size_t addr_size = 4; - StreamString dwarf(Stream::eBinary, addr_size, lldb::eByteOrderLittle); - ToDWARF(*ast, dwarf); - - // print dwarf expression to comparable textual representation - llvm::DataExtractor extractor(dwarf.GetString(), /*IsLittleEndian=*/true, - addr_size); - - std::string result; - llvm::raw_string_ostream os(result); - llvm::DWARFExpression(extractor, addr_size, llvm::dwarf::DWARF32) - .print(os, llvm::DIDumpOptions(), nullptr, nullptr); - return std::move(os.str()); -} - -TEST(PostfixExpression, ToDWARF) { - EXPECT_EQ("DW_OP_consts +0", ParseAndGenerateDWARF("0")); - - EXPECT_EQ("DW_OP_breg1 +0", ParseAndGenerateDWARF("R1")); - - EXPECT_EQ("DW_OP_bregx 0x41 +0", ParseAndGenerateDWARF("R65")); - - EXPECT_EQ("DW_OP_pick 0x0", ParseAndGenerateDWARF("INIT")); - - EXPECT_EQ("DW_OP_pick 0x0, DW_OP_pick 0x1, DW_OP_plus", - ParseAndGenerateDWARF("INIT INIT +")); - - EXPECT_EQ("DW_OP_breg1 +0, DW_OP_pick 0x1, DW_OP_plus", - ParseAndGenerateDWARF("R1 INIT +")); - - EXPECT_EQ("DW_OP_consts +1, DW_OP_pick 0x1, DW_OP_deref, DW_OP_plus", - ParseAndGenerateDWARF("1 INIT ^ +")); - - EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_plus", - ParseAndGenerateDWARF("4 5 +")); - - EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_minus", - ParseAndGenerateDWARF("4 5 -")); - - EXPECT_EQ("DW_OP_consts +4, DW_OP_deref", ParseAndGenerateDWARF("4 ^")); - - EXPECT_EQ("DW_OP_breg6 +0, DW_OP_consts +128, DW_OP_lit1, DW_OP_minus, " - "DW_OP_not, DW_OP_and", - ParseAndGenerateDWARF("R6 128 @")); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp b/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp deleted file mode 100644 index c8ffd099716..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//===-- TestClangASTImporter.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 "gtest/gtest.h" - -#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" -#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" -#include "Plugins/ExpressionParser/Clang/ClangUtil.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/Symbol/ClangTestUtils.h" -#include "lldb/Core/Declaration.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "clang/AST/DeclCXX.h" - -using namespace clang; -using namespace lldb; -using namespace lldb_private; - -class TestClangASTImporter : public testing::Test { -public: - SubsystemRAII subsystems; -}; - -TEST_F(TestClangASTImporter, CanImportInvalidType) { - ClangASTImporter importer; - EXPECT_FALSE(importer.CanImport(CompilerType())); -} - -TEST_F(TestClangASTImporter, ImportInvalidType) { - ClangASTImporter importer; - EXPECT_FALSE(importer.Import(CompilerType())); -} - -TEST_F(TestClangASTImporter, CopyDeclTagDecl) { - // Tests that the ClangASTImporter::CopyDecl can copy TagDecls. - clang_utils::SourceASTWithRecord source; - - std::unique_ptr target_ast = clang_utils::createAST(); - - ClangASTImporter importer; - clang::Decl *imported = - importer.CopyDecl(&target_ast->getASTContext(), source.record_decl); - ASSERT_NE(nullptr, imported); - - // Check that we got the correct decl by just comparing their qualified name. - clang::TagDecl *imported_tag_decl = llvm::cast(imported); - EXPECT_EQ(source.record_decl->getQualifiedNameAsString(), - imported_tag_decl->getQualifiedNameAsString()); - // We did a minimal import of the tag decl. - EXPECT_TRUE(imported_tag_decl->hasExternalLexicalStorage()); - - // Check that origin was set for the imported declaration. - ClangASTImporter::DeclOrigin origin = importer.GetDeclOrigin(imported); - EXPECT_TRUE(origin.Valid()); - EXPECT_EQ(origin.ctx, &source.ast->getASTContext()); - EXPECT_EQ(origin.decl, source.record_decl); -} - -TEST_F(TestClangASTImporter, CopyTypeTagDecl) { - // Tests that the ClangASTImporter::CopyType can copy TagDecls types. - clang_utils::SourceASTWithRecord source; - - std::unique_ptr target_ast = clang_utils::createAST(); - - ClangASTImporter importer; - CompilerType imported = importer.CopyType(*target_ast, source.record_type); - ASSERT_TRUE(imported.IsValid()); - - // Check that we got the correct decl by just comparing their qualified name. - clang::TagDecl *imported_tag_decl = ClangUtil::GetAsTagDecl(imported); - EXPECT_EQ(source.record_decl->getQualifiedNameAsString(), - imported_tag_decl->getQualifiedNameAsString()); - // We did a minimal import of the tag decl. - EXPECT_TRUE(imported_tag_decl->hasExternalLexicalStorage()); - - // Check that origin was set for the imported declaration. - ClangASTImporter::DeclOrigin origin = - importer.GetDeclOrigin(imported_tag_decl); - EXPECT_TRUE(origin.Valid()); - EXPECT_EQ(origin.ctx, &source.ast->getASTContext()); - EXPECT_EQ(origin.decl, source.record_decl); -} - -TEST_F(TestClangASTImporter, CompleteFwdDeclWithOtherOrigin) { - // Create an AST with a full type that is defined. - clang_utils::SourceASTWithRecord source_with_definition; - - // Create an AST with a type thst is only a forward declaration with the - // same name as the one in the other source. - std::unique_ptr fwd_decl_source = clang_utils::createAST(); - CompilerType fwd_decl_type = clang_utils::createRecord( - *fwd_decl_source, source_with_definition.record_decl->getName()); - - // Create a target and import the forward decl. - std::unique_ptr target = clang_utils::createAST(); - ClangASTImporter importer; - CompilerType imported = importer.CopyType(*target, fwd_decl_type); - ASSERT_TRUE(imported.IsValid()); - EXPECT_FALSE(imported.IsDefined()); - - // Now complete the forward decl with the definition from the other source. - // This should define the decl and give it the fields of the other origin. - clang::TagDecl *imported_tag_decl = ClangUtil::GetAsTagDecl(imported); - importer.CompleteTagDeclWithOrigin(imported_tag_decl, - source_with_definition.record_decl); - ASSERT_TRUE(imported.IsValid()); - EXPECT_TRUE(imported.IsDefined()); - EXPECT_EQ(1U, imported.GetNumFields()); -} - -TEST_F(TestClangASTImporter, DeportDeclTagDecl) { - // Tests that the ClangASTImporter::DeportDecl completely copies TagDecls. - clang_utils::SourceASTWithRecord source; - - std::unique_ptr target_ast = clang_utils::createAST(); - - ClangASTImporter importer; - clang::Decl *imported = - importer.DeportDecl(&target_ast->getASTContext(), source.record_decl); - ASSERT_NE(nullptr, imported); - - // Check that we got the correct decl by just comparing their qualified name. - clang::TagDecl *imported_tag_decl = llvm::cast(imported); - EXPECT_EQ(source.record_decl->getQualifiedNameAsString(), - imported_tag_decl->getQualifiedNameAsString()); - // The record should be completed as we deported it. - EXPECT_FALSE(imported_tag_decl->hasExternalLexicalStorage()); - - // Deporting doesn't update the origin map. - EXPECT_FALSE(importer.GetDeclOrigin(imported_tag_decl).Valid()); -} - -TEST_F(TestClangASTImporter, DeportTypeTagDecl) { - // Tests that the ClangASTImporter::CopyType can deport TagDecl types. - clang_utils::SourceASTWithRecord source; - - std::unique_ptr target_ast = clang_utils::createAST(); - - ClangASTImporter importer; - CompilerType imported = importer.DeportType(*target_ast, source.record_type); - ASSERT_TRUE(imported.IsValid()); - - // Check that we got the correct decl by just comparing their qualified name. - clang::TagDecl *imported_tag_decl = ClangUtil::GetAsTagDecl(imported); - EXPECT_EQ(source.record_decl->getQualifiedNameAsString(), - imported_tag_decl->getQualifiedNameAsString()); - // The record should be completed as we deported it. - EXPECT_FALSE(imported_tag_decl->hasExternalLexicalStorage()); - - // Deporting doesn't update the origin map. - EXPECT_FALSE(importer.GetDeclOrigin(imported_tag_decl).Valid()); -} - -TEST_F(TestClangASTImporter, MetadataPropagation) { - // Tests that AST metadata is propagated when copying declarations. - - clang_utils::SourceASTWithRecord source; - - const lldb::user_id_t metadata = 123456; - source.ast->SetMetadataAsUserID(source.record_decl, metadata); - - std::unique_ptr target_ast = clang_utils::createAST(); - - ClangASTImporter importer; - clang::Decl *imported = - importer.CopyDecl(&target_ast->getASTContext(), source.record_decl); - ASSERT_NE(nullptr, imported); - - // Check that we got the same Metadata. - ASSERT_NE(nullptr, importer.GetDeclMetadata(imported)); - EXPECT_EQ(metadata, importer.GetDeclMetadata(imported)->GetUserID()); -} - -TEST_F(TestClangASTImporter, MetadataPropagationIndirectImport) { - // Tests that AST metadata is propagated when copying declarations when - // importing one declaration into a temporary context and then to the - // actual destination context. - - clang_utils::SourceASTWithRecord source; - - const lldb::user_id_t metadata = 123456; - source.ast->SetMetadataAsUserID(source.record_decl, metadata); - - std::unique_ptr temporary_ast = clang_utils::createAST(); - - ClangASTImporter importer; - clang::Decl *temporary_imported = - importer.CopyDecl(&temporary_ast->getASTContext(), source.record_decl); - ASSERT_NE(nullptr, temporary_imported); - - std::unique_ptr target_ast = clang_utils::createAST(); - clang::Decl *imported = - importer.CopyDecl(&target_ast->getASTContext(), temporary_imported); - ASSERT_NE(nullptr, imported); - - // Check that we got the same Metadata. - ASSERT_NE(nullptr, importer.GetDeclMetadata(imported)); - EXPECT_EQ(metadata, importer.GetDeclMetadata(imported)->GetUserID()); -} - -TEST_F(TestClangASTImporter, MetadataPropagationAfterCopying) { - // Tests that AST metadata is propagated when copying declarations even - // when the metadata was set after the declaration has already been copied. - - clang_utils::SourceASTWithRecord source; - const lldb::user_id_t metadata = 123456; - - std::unique_ptr target_ast = clang_utils::createAST(); - - ClangASTImporter importer; - clang::Decl *imported = - importer.CopyDecl(&target_ast->getASTContext(), source.record_decl); - ASSERT_NE(nullptr, imported); - - // The TagDecl has been imported. Now set the metadata of the source and - // make sure the imported one will directly see it. - source.ast->SetMetadataAsUserID(source.record_decl, metadata); - - // Check that we got the same Metadata. - ASSERT_NE(nullptr, importer.GetDeclMetadata(imported)); - EXPECT_EQ(metadata, importer.GetDeclMetadata(imported)->GetUserID()); -} - -TEST_F(TestClangASTImporter, RecordLayout) { - // Test that it is possible to register RecordDecl layouts and then later - // correctly retrieve them. - - clang_utils::SourceASTWithRecord source; - - ClangASTImporter importer; - ClangASTImporter::LayoutInfo layout_info; - layout_info.bit_size = 15; - layout_info.alignment = 2; - layout_info.field_offsets[source.field_decl] = 1; - importer.SetRecordLayout(source.record_decl, layout_info); - - uint64_t bit_size; - uint64_t alignment; - llvm::DenseMap field_offsets; - llvm::DenseMap base_offsets; - llvm::DenseMap vbase_offsets; - importer.LayoutRecordType(source.record_decl, bit_size, alignment, - field_offsets, base_offsets, vbase_offsets); - - EXPECT_EQ(15U, bit_size); - EXPECT_EQ(2U, alignment); - EXPECT_EQ(1U, field_offsets.size()); - EXPECT_EQ(1U, field_offsets[source.field_decl]); - EXPECT_EQ(0U, base_offsets.size()); - EXPECT_EQ(0U, vbase_offsets.size()); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp b/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp deleted file mode 100644 index 86a6cf0cacb..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp +++ /dev/null @@ -1,257 +0,0 @@ -//===-- TestDWARFCallFrameInfo.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 "gtest/gtest.h" - -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/Process/Utility/RegisterContext_x86.h" -#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/Section.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/DWARFCallFrameInfo.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/Testing/Support/Error.h" - -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/raw_ostream.h" - -using namespace lldb_private; -using namespace lldb; - -class DWARFCallFrameInfoTest : public testing::Test { - SubsystemRAII - subsystems; - -protected: - void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol); -}; - -namespace lldb_private { -static std::ostream &operator<<(std::ostream &OS, const UnwindPlan::Row &row) { - StreamString SS; - row.Dump(SS, nullptr, nullptr, 0); - return OS << SS.GetData(); -} -} // namespace lldb_private - -static UnwindPlan::Row GetExpectedRow0() { - UnwindPlan::Row row; - row.SetOffset(0); - row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 8); - row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false); - return row; -} - -static UnwindPlan::Row GetExpectedRow1() { - UnwindPlan::Row row; - row.SetOffset(1); - row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 16); - row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false); - row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rbp_x86_64, -16, false); - return row; -} - -static UnwindPlan::Row GetExpectedRow2() { - UnwindPlan::Row row; - row.SetOffset(4); - row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp_x86_64, 16); - row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false); - row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rbp_x86_64, -16, false); - return row; -} - -void DWARFCallFrameInfoTest::TestBasic(DWARFCallFrameInfo::Type type, - llvm::StringRef symbol) { - auto ExpectedFile = TestFile::fromYaml(R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_DYN - Machine: EM_X86_64 - Entry: 0x0000000000000260 -Sections: - - Name: .text - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR ] - Address: 0x0000000000000260 - AddressAlign: 0x0000000000000010 - Content: 554889E5897DFC8B45FC5DC30F1F4000554889E5897DFC8B45FC5DC30F1F4000554889E5897DFC8B45FC5DC3 -#0000000000000260 : -# 260: 55 push %rbp -# 261: 48 89 e5 mov %rsp,%rbp -# 264: 89 7d fc mov %edi,-0x4(%rbp) -# 267: 8b 45 fc mov -0x4(%rbp),%eax -# 26a: 5d pop %rbp -# 26b: c3 retq -# 26c: 0f 1f 40 00 nopl 0x0(%rax) -# -#0000000000000270 : -# 270: 55 push %rbp -# 271: 48 89 e5 mov %rsp,%rbp -# 274: 89 7d fc mov %edi,-0x4(%rbp) -# 277: 8b 45 fc mov -0x4(%rbp),%eax -# 27a: 5d pop %rbp -# 27b: c3 retq -# 27c: 0f 1f 40 00 nopl 0x0(%rax) -# -#0000000000000280 : -# 280: 55 push %rbp -# 281: 48 89 e5 mov %rsp,%rbp -# 284: 89 7d fc mov %edi,-0x4(%rbp) -# 287: 8b 45 fc mov -0x4(%rbp),%eax -# 28a: 5d pop %rbp -# 28b: c3 retq - - Name: .eh_frame - Type: SHT_X86_64_UNWIND - Flags: [ SHF_ALLOC ] - Address: 0x0000000000000290 - AddressAlign: 0x0000000000000008 - Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000B0FFFFFF0C00000000410E108602430D0600000000000000 -#00000000 0000000000000014 00000000 CIE -# Version: 1 -# Augmentation: "zR" -# Code alignment factor: 1 -# Data alignment factor: -8 -# Return address column: 16 -# Augmentation data: 1b -# -# DW_CFA_def_cfa: r7 (rsp) ofs 8 -# DW_CFA_offset: r16 (rip) at cfa-8 -# DW_CFA_nop -# DW_CFA_nop -# -#00000018 000000000000001c 0000001c FDE cie=00000000 pc=ffffffffffffffd0..ffffffffffffffdc -# DW_CFA_advance_loc: 1 to ffffffffffffffd1 -# DW_CFA_def_cfa_offset: 16 -# DW_CFA_offset: r6 (rbp) at cfa-16 -# DW_CFA_advance_loc: 3 to ffffffffffffffd4 -# DW_CFA_def_cfa_register: r6 (rbp) -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop - - Name: .debug_frame - Type: SHT_PROGBITS - AddressAlign: 0x0000000000000008 - Content: 14000000FFFFFFFF03000178100C070890010000000000001C0000000000000070020000000000000C00000000000000410E108602430D0614000000FFFFFFFF040008000178100C07089001000000001C0000003800000080020000000000000C00000000000000410E108602430D06 -#00000000 0000000000000014 ffffffff CIE -# Version: 3 -# Augmentation: "" -# Code alignment factor: 1 -# Data alignment factor: -8 -# Return address column: 16 -# -# DW_CFA_def_cfa: r7 (rsp) ofs 8 -# DW_CFA_offset: r16 (rip) at cfa-8 -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# -#00000018 000000000000001c 00000000 FDE cie=00000000 pc=0000000000000270..000000000000027c -# DW_CFA_advance_loc: 1 to 0000000000000271 -# DW_CFA_def_cfa_offset: 16 -# DW_CFA_offset: r6 (rbp) at cfa-16 -# DW_CFA_advance_loc: 3 to 0000000000000274 -# DW_CFA_def_cfa_register: r6 (rbp) -# -#00000038 0000000000000014 ffffffff CIE -# Version: 4 -# Augmentation: "" -# Pointer Size: 8 -# Segment Size: 0 -# Code alignment factor: 1 -# Data alignment factor: -8 -# Return address column: 16 -# -# DW_CFA_def_cfa: r7 (rsp) ofs 8 -# DW_CFA_offset: r16 (rip) at cfa-8 -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# DW_CFA_nop -# -#00000050 000000000000001c 00000038 FDE cie=00000038 pc=0000000000000280..000000000000028c -# DW_CFA_advance_loc: 1 to 0000000000000281 -# DW_CFA_def_cfa_offset: 16 -# DW_CFA_offset: r6 (rbp) at cfa-16 -# DW_CFA_advance_loc: 3 to 0000000000000284 -# DW_CFA_def_cfa_register: r6 (rbp) -Symbols: - - Name: eh_frame - Type: STT_FUNC - Section: .text - Value: 0x0000000000000260 - Size: 0x000000000000000C - Binding: STB_GLOBAL - - Name: debug_frame3 - Type: STT_FUNC - Section: .text - Value: 0x0000000000000270 - Size: 0x000000000000000C - Binding: STB_GLOBAL - - Name: debug_frame4 - Type: STT_FUNC - Section: .text - Value: 0x0000000000000280 - Size: 0x000000000000000C - Binding: STB_GLOBAL -... -)"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - - auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); - SectionList *list = module_sp->GetSectionList(); - ASSERT_NE(nullptr, list); - - auto section_sp = list->FindSectionByType(type == DWARFCallFrameInfo::EH - ? eSectionTypeEHFrame - : eSectionTypeDWARFDebugFrame, - false); - ASSERT_NE(nullptr, section_sp); - - DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp, type); - - const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType( - ConstString(symbol), eSymbolTypeAny); - ASSERT_NE(nullptr, sym); - - UnwindPlan plan(eRegisterKindGeneric); - ASSERT_TRUE(cfi.GetUnwindPlan(sym->GetAddress(), plan)); - ASSERT_EQ(3, plan.GetRowCount()); - EXPECT_EQ(GetExpectedRow0(), *plan.GetRowAtIndex(0)); - EXPECT_EQ(GetExpectedRow1(), *plan.GetRowAtIndex(1)); - EXPECT_EQ(GetExpectedRow2(), *plan.GetRowAtIndex(2)); -} - -TEST_F(DWARFCallFrameInfoTest, Basic_dwarf3) { - TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame3"); -} - -TEST_F(DWARFCallFrameInfoTest, Basic_dwarf4) { - TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame4"); -} - -TEST_F(DWARFCallFrameInfoTest, Basic_eh) { - TestBasic(DWARFCallFrameInfo::EH, "eh_frame"); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp b/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp deleted file mode 100644 index 5fc53749703..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp +++ /dev/null @@ -1,208 +0,0 @@ -//===-- TestLineEntry.cpp -------------------------------------------------===// -// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "gtest/gtest.h" -#include - -#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" -#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" - -#include "lldb/Core/Module.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/SymbolContext.h" - -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Program.h" -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private; -using namespace lldb; - -class LineEntryTest : public testing::Test { - SubsystemRAII - subsystem; - -public: - void SetUp() override; - -protected: - llvm::Expected GetLineEntryForLine(uint32_t line); - llvm::Optional m_file; - ModuleSP m_module_sp; -}; - -void LineEntryTest::SetUp() { - auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml"); - ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - m_file.emplace(std::move(*ExpectedFile)); - m_module_sp = std::make_shared(m_file->moduleSpec()); -} - -llvm::Expected LineEntryTest::GetLineEntryForLine(uint32_t line) { - // TODO: Handle SourceLocationSpec column information - SymbolContextList sc_comp_units; - SymbolContextList sc_line_entries; - FileSpec file_spec("inlined-functions.cpp"); - m_module_sp->ResolveSymbolContextsForFileSpec( - file_spec, line, /*check_inlines=*/true, lldb::eSymbolContextCompUnit, - sc_comp_units); - if (sc_comp_units.GetSize() == 0) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "No comp unit found on the test object."); - - SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None, - /*check_inlines=*/true, - /*exact_match=*/true); - - sc_comp_units[0].comp_unit->ResolveSymbolContext( - location_spec, eSymbolContextLineEntry, sc_line_entries); - if (sc_line_entries.GetSize() == 0) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "No line entry found on the test object."); - return sc_line_entries[0].line_entry; -} - -TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNoInlines) { - auto line_entry = GetLineEntryForLine(18); - ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); - bool include_inlined_functions = false; - auto range = - line_entry->GetSameLineContiguousAddressRange(include_inlined_functions); - ASSERT_EQ(range.GetByteSize(), (uint64_t)0x24); -} - -TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeOneInline) { - auto line_entry = GetLineEntryForLine(18); - ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); - bool include_inlined_functions = true; - auto range = - line_entry->GetSameLineContiguousAddressRange(include_inlined_functions); - ASSERT_EQ(range.GetByteSize(), (uint64_t)0x49); -} - -TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNestedInline) { - auto line_entry = GetLineEntryForLine(12); - ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); - bool include_inlined_functions = true; - auto range = - line_entry->GetSameLineContiguousAddressRange(include_inlined_functions); - ASSERT_EQ(range.GetByteSize(), (uint64_t)0x33); -} - -/* -# inlined-functions.cpp -inline __attribute__((always_inline)) int sum2(int a, int b) { - int result = a + b; - return result; -} - -int sum3(int a, int b, int c) { - int result = a + b + c; - return result; -} - -inline __attribute__((always_inline)) int sum4(int a, int b, int c, int d) { - int result = sum2(a, b) + sum2(c, d); - result += 0; - return result; -} - -int main(int argc, char** argv) { - sum3(3, 4, 5) + sum2(1, 2); - int sum = sum4(1, 2, 3, 4); - sum2(5, 6); - return 0; -} - -// g++ -c inlined-functions.cpp -o inlined-functions.o -g -Wno-unused-value -// obj2yaml inlined-functions.o > inlined-functions.yaml - -# Dump of source line per address: -# inlined-functions.cpp is src.cpp for space considerations. -0x20: src.cpp:17 -0x21: src.cpp:17 -0x26: src.cpp:17 -0x27: src.cpp:17 -0x29: src.cpp:17 -0x2e: src.cpp:17 -0x2f: src.cpp:17 -0x31: src.cpp:17 -0x36: src.cpp:18 -0x37: src.cpp:18 -0x39: src.cpp:18 -0x3e: src.cpp:18 -0x3f: src.cpp:18 -0x41: src.cpp:18 -0x46: src.cpp:18 -0x47: src.cpp:18 -0x49: src.cpp:18 -0x4e: src.cpp:18 -0x4f: src.cpp:18 -0x51: src.cpp:18 -0x56: src.cpp:18 -0x57: src.cpp:18 -0x59: src.cpp:18 -0x5e: src.cpp:18 -> sum2@src.cpp:2 -0x5f: src.cpp:18 -> sum2@src.cpp:2 -0x61: src.cpp:18 -> sum2@src.cpp:2 -0x66: src.cpp:18 -> sum2@src.cpp:2 -0x67: src.cpp:18 -> sum2@src.cpp:2 -0x69: src.cpp:18 -> sum2@src.cpp:2 -0x6e: src.cpp:18 -> sum2@src.cpp:2 -0x6f: src.cpp:18 -> sum2@src.cpp:2 -0x71: src.cpp:18 -> sum2@src.cpp:2 -0x76: src.cpp:18 -> sum2@src.cpp:2 -0x77: src.cpp:18 -> sum2@src.cpp:2 -0x79: src.cpp:18 -> sum2@src.cpp:2 -0x7e: src.cpp:18 -> sum2@src.cpp:2 -0x7f: src.cpp:19 -> sum4@src.cpp:12 -0x81: src.cpp:19 -> sum4@src.cpp:12 -0x86: src.cpp:19 -> sum4@src.cpp:12 -0x87: src.cpp:19 -> sum4@src.cpp:12 -0x89: src.cpp:19 -> sum4@src.cpp:12 -0x8e: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2 -0x8f: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2 -0x91: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2 -0x96: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:3 -0x97: src.cpp:19 -> sum4@src.cpp:12 -0x99: src.cpp:19 -> sum4@src.cpp:12 -0x9e: src.cpp:19 -> sum4@src.cpp:12 -0x9f: src.cpp:19 -> sum4@src.cpp:12 -0xa1: src.cpp:19 -> sum4@src.cpp:12 -0xa6: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2 -0xa7: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2 -0xa9: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2 -0xae: src.cpp:19 -> sum4@src.cpp:12 -0xaf: src.cpp:19 -> sum4@src.cpp:12 -0xb1: src.cpp:19 -> sum4@src.cpp:12 -0xb6: src.cpp:19 -> sum4@src.cpp:13 -0xb7: src.cpp:19 -> sum4@src.cpp:13 -0xb9: src.cpp:19 -> sum4@src.cpp:14 -0xbe: src.cpp:19 -0xbf: src.cpp:19 -0xc1: src.cpp:19 -0xc6: src.cpp:19 -0xc7: src.cpp:19 -0xc9: src.cpp:19 -0xce: src.cpp:20 -> sum2@src.cpp:2 -0xcf: src.cpp:20 -> sum2@src.cpp:2 -0xd1: src.cpp:20 -> sum2@src.cpp:2 -0xd6: src.cpp:21 -0xd7: src.cpp:21 -0xd9: src.cpp:21 -0xde: src.cpp:21 -*/ diff --git a/gnu/llvm/lldb/unittests/Symbol/TestType.cpp b/gnu/llvm/lldb/unittests/Symbol/TestType.cpp deleted file mode 100644 index 73f5811434f..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/TestType.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//===-- TestType.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 "gtest/gtest.h" - -#include "lldb/Symbol/Type.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { -void TestGetTypeScopeAndBasenameHelper(const char *full_type, - bool expected_is_scoped, - const char *expected_scope, - const char *expected_name) { - llvm::StringRef scope, name; - lldb::TypeClass type_class; - bool is_scoped = - Type::GetTypeScopeAndBasename(full_type, scope, name, type_class); - EXPECT_EQ(is_scoped, expected_is_scoped); - if (expected_is_scoped) { - EXPECT_EQ(scope, expected_scope); - EXPECT_EQ(name, expected_name); - } -} -} - -TEST(Type, GetTypeScopeAndBasename) { - TestGetTypeScopeAndBasenameHelper("int", false, "", ""); - TestGetTypeScopeAndBasenameHelper("std::string", true, "std::", "string"); - TestGetTypeScopeAndBasenameHelper("std::set", true, "std::", "set"); - TestGetTypeScopeAndBasenameHelper("std::set>", true, - "std::", "set>"); - TestGetTypeScopeAndBasenameHelper("std::string::iterator", true, - "std::string::", "iterator"); - TestGetTypeScopeAndBasenameHelper("std::set::iterator", true, - "std::set::", "iterator"); - TestGetTypeScopeAndBasenameHelper( - "std::set>::iterator", true, - "std::set>::", "iterator"); - TestGetTypeScopeAndBasenameHelper( - "std::set>::iterator", true, - "std::set>::", "iterator"); -} - -TEST(Type, CompilerContextPattern) { - std::vector mms = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Module, ConstString("B")}, - {CompilerContextKind::Struct, ConstString("S")}}; - EXPECT_TRUE(contextMatches(mms, mms)); - std::vector mmc = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Module, ConstString("B")}, - {CompilerContextKind::Class, ConstString("S")}}; - EXPECT_FALSE(contextMatches(mms, mmc)); - std::vector ms = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Struct, ConstString("S")}}; - std::vector mas = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::AnyModule, ConstString("*")}, - {CompilerContextKind::Struct, ConstString("S")}}; - EXPECT_TRUE(contextMatches(mms, mas)); - EXPECT_TRUE(contextMatches(ms, mas)); - EXPECT_FALSE(contextMatches(mas, ms)); - std::vector mmms = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Module, ConstString("B")}, - {CompilerContextKind::Module, ConstString("C")}, - {CompilerContextKind::Struct, ConstString("S")}}; - EXPECT_TRUE(contextMatches(mmms, mas)); - std::vector mme = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Module, ConstString("B")}, - {CompilerContextKind::Enum, ConstString("S")}}; - std::vector mma = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Module, ConstString("B")}, - {CompilerContextKind::AnyType, ConstString("S")}}; - EXPECT_TRUE(contextMatches(mme, mma)); - EXPECT_TRUE(contextMatches(mms, mma)); - std::vector mme2 = { - {CompilerContextKind::Module, ConstString("A")}, - {CompilerContextKind::Module, ConstString("B")}, - {CompilerContextKind::Enum, ConstString("S2")}}; - EXPECT_FALSE(contextMatches(mme2, mma)); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/TestTypeSystem.cpp b/gnu/llvm/lldb/unittests/Symbol/TestTypeSystem.cpp deleted file mode 100644 index 59297a7475d..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/TestTypeSystem.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//===-- TestTypeSystem.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 "TestingSupport/SubsystemRAII.h" -#include "lldb/Core/Module.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/TypeSystem.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -class TestTypeSystemMap : public testing::Test { -public: - SubsystemRAII subsystems; -}; - -TEST_F(TestTypeSystemMap, GetTypeSystemForLanguageWithInvalidModule) { - // GetTypeSystemForLanguage called with an invalid Module. - TypeSystemMap map; - Module module{ModuleSpec()}; - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeUnknown, &module, - /*can_create=*/true), - llvm::FailedWithMessage("TypeSystem for language unknown doesn't exist")); - - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeUnknown, &module, - /*can_create=*/false), - llvm::FailedWithMessage("TypeSystem for language unknown doesn't exist")); - - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeC, &module, - /*can_create=*/true), - llvm::FailedWithMessage("TypeSystem for language c doesn't exist")); - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeC, &module, - /*can_create=*/false), - llvm::FailedWithMessage("TypeSystem for language c doesn't exist")); -} - -TEST_F(TestTypeSystemMap, GetTypeSystemForLanguageWithNoModule) { - // GetTypeSystemForLanguage called with no Module. - TypeSystemMap map; - Module *module = nullptr; - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeUnknown, module, - /*can_create=*/true), - llvm::FailedWithMessage("TypeSystem for language unknown doesn't exist")); - - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeUnknown, module, - /*can_create=*/false), - llvm::FailedWithMessage("TypeSystem for language unknown doesn't exist")); - - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeC, module, /*can_create=*/true), - llvm::FailedWithMessage("TypeSystem for language c doesn't exist")); - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeC, module, - /*can_create=*/false), - llvm::FailedWithMessage("TypeSystem for language c doesn't exist")); -} - -TEST_F(TestTypeSystemMap, GetTypeSystemForLanguageWithNoTarget) { - // GetTypeSystemForLanguage called with no Target. - TypeSystemMap map; - Target *target = nullptr; - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeUnknown, target, - /*can_create=*/true), - llvm::FailedWithMessage("TypeSystem for language unknown doesn't exist")); - - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeUnknown, target, - /*can_create=*/false), - llvm::FailedWithMessage("TypeSystem for language unknown doesn't exist")); - - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeC, target, /*can_create=*/true), - llvm::FailedWithMessage("TypeSystem for language c doesn't exist")); - EXPECT_THAT_EXPECTED( - map.GetTypeSystemForLanguage(eLanguageTypeC, target, - /*can_create=*/false), - llvm::FailedWithMessage("TypeSystem for language c doesn't exist")); -} diff --git a/gnu/llvm/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/gnu/llvm/lldb/unittests/Symbol/TestTypeSystemClang.cpp deleted file mode 100644 index 10f59147dd1..00000000000 --- a/gnu/llvm/lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ /dev/null @@ -1,936 +0,0 @@ -//===-- TestTypeSystemClang.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 "Plugins/ExpressionParser/Clang/ClangUtil.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/Symbol/ClangTestUtils.h" -#include "lldb/Core/Declaration.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/ExprCXX.h" -#include "gtest/gtest.h" - -using namespace clang; -using namespace lldb; -using namespace lldb_private; - -class TestTypeSystemClang : public testing::Test { -public: - SubsystemRAII subsystems; - - void SetUp() override { - m_ast.reset( - new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple())); - } - - void TearDown() override { m_ast.reset(); } - -protected: - std::unique_ptr m_ast; - - QualType GetBasicQualType(BasicType type) const { - return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type)); - } - - QualType GetBasicQualType(const char *name) const { - return ClangUtil::GetQualType( - m_ast->GetBuiltinTypeByName(ConstString(name))); - } -}; - -TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) { - clang::ASTContext &context = m_ast->getASTContext(); - - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16), - context.Char16Ty)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32), - context.Char32Ty)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble), - context.DoubleTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex), - context.DoubleComplexTy)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex), - context.FloatComplexTy)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128), - context.Int128Ty)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble), - context.LongDoubleTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex), - context.LongDoubleComplexTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong), - context.LongLongTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr), - context.NullPtrTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass), - context.getObjCClassType())); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID), - context.getObjCIdType())); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel), - context.getObjCSelType())); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar), - context.SignedCharTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar), - context.UnsignedCharTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt), - context.UnsignedIntTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128), - context.UnsignedInt128Ty)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong), - context.UnsignedLongTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong), - context.UnsignedLongLongTy)); - EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort), - context.UnsignedShortTy)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy)); - EXPECT_TRUE( - context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy)); -} - -TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) { - EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char")); - EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar), - GetBasicQualType("signed char")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar), - GetBasicQualType("unsigned char")); - EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t")); - EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar), - GetBasicQualType("signed wchar_t")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar), - GetBasicQualType("unsigned wchar_t")); - EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short")); - EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), - GetBasicQualType("unsigned short")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), - GetBasicQualType("unsigned short int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), - GetBasicQualType("unsigned int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), - GetBasicQualType("unsigned")); - EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long")); - EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), - GetBasicQualType("unsigned long")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), - GetBasicQualType("unsigned long int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), - GetBasicQualType("long long")); - EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), - GetBasicQualType("long long int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), - GetBasicQualType("unsigned long long")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), - GetBasicQualType("unsigned long long int")); - EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t")); - EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128), - GetBasicQualType("__uint128_t")); - EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void")); - EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool")); - EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float")); - EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double")); - EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble), - GetBasicQualType("long double")); - EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id")); - EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL")); - EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr")); -} - -void VerifyEncodingAndBitSize(TypeSystemClang &clang_context, - lldb::Encoding encoding, unsigned int bit_size) { - clang::ASTContext &context = clang_context.getASTContext(); - - CompilerType type = - clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size); - EXPECT_TRUE(type.IsValid()); - - QualType qtype = ClangUtil::GetQualType(type); - EXPECT_FALSE(qtype.isNull()); - if (qtype.isNull()) - return; - - uint64_t actual_size = context.getTypeSize(qtype); - EXPECT_EQ(bit_size, actual_size); - - const clang::Type *type_ptr = qtype.getTypePtr(); - EXPECT_NE(nullptr, type_ptr); - if (!type_ptr) - return; - - EXPECT_TRUE(type_ptr->isBuiltinType()); - switch (encoding) { - case eEncodingSint: - EXPECT_TRUE(type_ptr->isSignedIntegerType()); - break; - case eEncodingUint: - EXPECT_TRUE(type_ptr->isUnsignedIntegerType()); - break; - case eEncodingIEEE754: - EXPECT_TRUE(type_ptr->isFloatingType()); - break; - default: - FAIL() << "Unexpected encoding"; - break; - } -} - -TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) { - // Make sure we can get types of every possible size in every possible - // encoding. - // We can't make any guarantee about which specific type we get, because the - // standard - // isn't that specific. We only need to make sure the compiler hands us some - // type that - // is both a builtin type and matches the requested bit size. - VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8); - VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16); - VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32); - VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64); - VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128); - - VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8); - VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16); - VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32); - VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64); - VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128); - - VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32); - VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64); -} - -TEST_F(TestTypeSystemClang, TestDisplayName) { - TypeSystemClang ast("some name", llvm::Triple()); - EXPECT_EQ("some name", ast.getDisplayName()); -} - -TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) { - TypeSystemClang ast("", llvm::Triple()); - EXPECT_EQ("", ast.getDisplayName()); -} - -TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) { - EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid()); -} - -TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) { - CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); - CompilerType t = m_ast->GetEnumerationIntegerType(int_type); - EXPECT_FALSE(t.IsValid()); -} - -TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) { - // All possible underlying integer types of enums. - const std::vector types_to_test = { - eBasicTypeInt, eBasicTypeUnsignedInt, eBasicTypeLong, - eBasicTypeUnsignedLong, eBasicTypeLongLong, eBasicTypeUnsignedLongLong, - }; - - for (bool scoped : {true, false}) { - SCOPED_TRACE("scoped: " + std::to_string(scoped)); - for (lldb::BasicType basic_type : types_to_test) { - SCOPED_TRACE(std::to_string(basic_type)); - - TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple()); - CompilerType basic_compiler_type = ast.GetBasicType(basic_type); - EXPECT_TRUE(basic_compiler_type.IsValid()); - - CompilerType enum_type = ast.CreateEnumerationType( - "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(), - Declaration(), basic_compiler_type, scoped); - - CompilerType t = ast.GetEnumerationIntegerType(enum_type); - // Check that the type we put in at the start is found again. - EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName()); - } - } -} - -TEST_F(TestTypeSystemClang, TestOwningModule) { - TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple()); - CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt); - CompilerType enum_type = ast.CreateEnumerationType( - "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100), - Declaration(), basic_compiler_type, false); - auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type); - EXPECT_FALSE(!ed); - EXPECT_EQ(ed->getOwningModuleID(), 100u); - - CompilerType record_type = ast.CreateRecordType( - nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - auto *rd = TypeSystemClang::GetAsRecordDecl(record_type); - EXPECT_FALSE(!rd); - EXPECT_EQ(rd->getOwningModuleID(), 200u); - - CompilerType class_type = - ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(), - OptionalClangModuleID(300), false, false); - auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type); - EXPECT_FALSE(!cd); - EXPECT_EQ(cd->getOwningModuleID(), 300u); -} - -TEST_F(TestTypeSystemClang, TestIsClangType) { - clang::ASTContext &context = m_ast->getASTContext(); - lldb::opaque_compiler_type_t bool_ctype = - TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool); - CompilerType bool_type(m_ast.get(), bool_ctype); - CompilerType record_type = m_ast->CreateRecordType( - nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - // Clang builtin type and record type should pass - EXPECT_TRUE(ClangUtil::IsClangType(bool_type)); - EXPECT_TRUE(ClangUtil::IsClangType(record_type)); - - // Default constructed type should fail - EXPECT_FALSE(ClangUtil::IsClangType(CompilerType())); -} - -TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) { - CompilerType record_type = m_ast->CreateRecordType( - nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - QualType qt; - - qt = ClangUtil::GetQualType(record_type); - EXPECT_EQ(0u, qt.getLocalFastQualifiers()); - record_type = record_type.AddConstModifier(); - record_type = record_type.AddVolatileModifier(); - record_type = record_type.AddRestrictModifier(); - qt = ClangUtil::GetQualType(record_type); - EXPECT_NE(0u, qt.getLocalFastQualifiers()); - record_type = ClangUtil::RemoveFastQualifiers(record_type); - qt = ClangUtil::GetQualType(record_type); - EXPECT_EQ(0u, qt.getLocalFastQualifiers()); -} - -TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) { - EXPECT_EQ(AS_none, - TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone)); - EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( - eAccessPackage)); - EXPECT_EQ(AS_public, - TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic)); - EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( - eAccessPrivate)); - EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( - eAccessProtected)); -} - -TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) { - // Unifying two of the same type should return the same type - EXPECT_EQ(AS_public, - TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public)); - EXPECT_EQ(AS_private, - TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private)); - EXPECT_EQ(AS_protected, - TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected)); - - // Otherwise the result should be the strictest of the two. - EXPECT_EQ(AS_private, - TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public)); - EXPECT_EQ(AS_private, - TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected)); - EXPECT_EQ(AS_private, - TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private)); - EXPECT_EQ(AS_private, - TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private)); - EXPECT_EQ(AS_protected, - TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public)); - EXPECT_EQ(AS_protected, - TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected)); - - // None is stricter than everything (by convention) - EXPECT_EQ(AS_none, - TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public)); - EXPECT_EQ(AS_none, - TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected)); - EXPECT_EQ(AS_none, - TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private)); - EXPECT_EQ(AS_none, - TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none)); - EXPECT_EQ(AS_none, - TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none)); - EXPECT_EQ(AS_none, - TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none)); -} - -TEST_F(TestTypeSystemClang, TestRecordHasFields) { - CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt); - - // Test that a record with no fields returns false - CompilerType empty_base = m_ast->CreateRecordType( - nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - TypeSystemClang::StartTagDeclarationDefinition(empty_base); - TypeSystemClang::CompleteTagDeclarationDefinition(empty_base); - - RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base); - EXPECT_NE(nullptr, empty_base_decl); - EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl)); - - // Test that a record with direct fields returns true - CompilerType non_empty_base = m_ast->CreateRecordType( - nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - TypeSystemClang::StartTagDeclarationDefinition(non_empty_base); - FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType( - non_empty_base, "MyField", int_type, eAccessPublic, 0); - TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base); - RecordDecl *non_empty_base_decl = - TypeSystemClang::GetAsRecordDecl(non_empty_base); - EXPECT_NE(nullptr, non_empty_base_decl); - EXPECT_NE(nullptr, non_empty_base_field_decl); - EXPECT_TRUE(TypeSystemClang::RecordHasFields(non_empty_base_decl)); - - std::vector> bases; - - // Test that a record with no direct fields, but fields in a base returns true - CompilerType empty_derived = m_ast->CreateRecordType( - nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - TypeSystemClang::StartTagDeclarationDefinition(empty_derived); - std::unique_ptr non_empty_base_spec = - m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), - lldb::eAccessPublic, false, false); - bases.push_back(std::move(non_empty_base_spec)); - bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(), - std::move(bases)); - TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived); - EXPECT_TRUE(result); - CXXRecordDecl *empty_derived_non_empty_base_cxx_decl = - m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType()); - RecordDecl *empty_derived_non_empty_base_decl = - TypeSystemClang::GetAsRecordDecl(empty_derived); - EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses( - empty_derived_non_empty_base_cxx_decl, false)); - EXPECT_TRUE( - TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl)); - - // Test that a record with no direct fields, but fields in a virtual base - // returns true - CompilerType empty_derived2 = m_ast->CreateRecordType( - nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2", - clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); - TypeSystemClang::StartTagDeclarationDefinition(empty_derived2); - std::unique_ptr non_empty_vbase_spec = - m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), - lldb::eAccessPublic, true, false); - bases.push_back(std::move(non_empty_vbase_spec)); - result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(), - std::move(bases)); - TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2); - EXPECT_TRUE(result); - CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl = - m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType()); - RecordDecl *empty_derived_non_empty_vbase_decl = - TypeSystemClang::GetAsRecordDecl(empty_derived2); - EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses( - empty_derived_non_empty_vbase_cxx_decl, false)); - EXPECT_TRUE( - TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl)); -} - -TEST_F(TestTypeSystemClang, TemplateArguments) { - TypeSystemClang::TemplateParameterInfos infos; - infos.names.push_back("T"); - infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy)); - infos.names.push_back("I"); - llvm::APSInt arg(llvm::APInt(8, 47)); - infos.args.push_back(TemplateArgument(m_ast->getASTContext(), arg, - m_ast->getASTContext().IntTy)); - - // template struct foo; - ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( - m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, - "foo", TTK_Struct, infos); - ASSERT_NE(decl, nullptr); - - // foo - ClassTemplateSpecializationDecl *spec_decl = - m_ast->CreateClassTemplateSpecializationDecl( - m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl, - TTK_Struct, infos); - ASSERT_NE(spec_decl, nullptr); - CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl); - ASSERT_TRUE(type); - m_ast->StartTagDeclarationDefinition(type); - m_ast->CompleteTagDeclarationDefinition(type); - - // typedef foo foo_def; - CompilerType typedef_type = type.CreateTypedef( - "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0); - - CompilerType auto_type( - m_ast.get(), - m_ast->getASTContext() - .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type), - clang::AutoTypeKeyword::Auto, false) - .getAsOpaquePtr()); - - CompilerType int_type(m_ast.get(), - m_ast->getASTContext().IntTy.getAsOpaquePtr()); - for (CompilerType t : {type, typedef_type, auto_type}) { - SCOPED_TRACE(t.GetTypeName().AsCString()); - - EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), - eTemplateArgumentKindType); - EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), - int_type); - EXPECT_EQ(llvm::None, - m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0)); - - EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), - eTemplateArgumentKindIntegral); - EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), - CompilerType()); - auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); - ASSERT_NE(llvm::None, result); - EXPECT_EQ(arg, result->value); - EXPECT_EQ(int_type, result->type); - } -} - -class TestCreateClassTemplateDecl : public TestTypeSystemClang { -protected: - /// The class templates created so far by the Expect* functions below. - llvm::DenseSet m_created_templates; - - /// Utility function for creating a class template. - ClassTemplateDecl * - CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) { - ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( - m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, - "foo", TTK_Struct, infos); - return decl; - } - - /// Creates a new class template with the given template parameters. - /// Asserts that a new ClassTemplateDecl is created. - /// \param description The gtest scope string that should describe the input. - /// \param infos The template parameters that the class template should have. - /// \returns The created ClassTemplateDecl. - ClassTemplateDecl * - ExpectNewTemplate(std::string description, - const TypeSystemClang::TemplateParameterInfos &infos) { - SCOPED_TRACE(description); - ClassTemplateDecl *first_template = CreateClassTemplate(infos); - // A new template should have been created. - EXPECT_FALSE(m_created_templates.contains(first_template)) - << "Didn't create new class template but reused this existing decl:\n" - << ClangUtil::DumpDecl(first_template); - m_created_templates.insert(first_template); - - // Creating a new template with the same arguments should always return - // the template created above. - ClassTemplateDecl *second_template = CreateClassTemplate(infos); - EXPECT_EQ(first_template, second_template) - << "Second attempt to create class template didn't reuse first decl:\n" - << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n" - << ClangUtil::DumpDecl(second_template); - return first_template; - } - - /// Tries to create a new class template but asserts that an existing class - /// template in the current AST is reused (in contract so a new class - /// template being created). - /// \param description The gtest scope string that should describe the input. - /// \param infos The template parameters that the class template should have. - void - ExpectReusedTemplate(std::string description, - const TypeSystemClang::TemplateParameterInfos &infos, - ClassTemplateDecl *expected) { - SCOPED_TRACE(description); - ClassTemplateDecl *td = CreateClassTemplate(infos); - EXPECT_EQ(td, expected) - << "Created/reused class template is:\n" - << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n" - << ClangUtil::DumpDecl(expected); - } -}; - -TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) { - // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that - // decides whether an existing ClassTemplateDecl in the AST can be reused. - // The behaviour should follow the C++ rules for redeclaring templates - // (e.g., parameter names can be changed/omitted.) - - // This describes a class template *instantiation* from which we will infer - // the structure of the class template. - TypeSystemClang::TemplateParameterInfos infos; - - // Test an empty template parameter list: <> - ExpectNewTemplate("<>", infos); - - // Test that with T = int creates a new template. - infos.names = {"T"}; - infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; - ClassTemplateDecl *single_type_arg = ExpectNewTemplate("", infos); - - // Test that changing the parameter name doesn't create a new class template. - infos.names = {"A"}; - ExpectReusedTemplate(" (A = int)", infos, single_type_arg); - - // Test that changing the used type doesn't create a new class template. - infos.args = {TemplateArgument(m_ast->getASTContext().FloatTy)}; - ExpectReusedTemplate(" (A = float)", infos, single_type_arg); - - // Test that creates a new template with A = int - // and I = 47; - infos.names.push_back("I"); - infos.args.push_back(TemplateArgument(m_ast->getASTContext(), - llvm::APSInt(llvm::APInt(8, 47)), - m_ast->getASTContext().SignedCharTy)); - ClassTemplateDecl *type_and_char_value = - ExpectNewTemplate(" (I = 47)", infos); - - // Change the value of the I parameter to 123. The previously created - // class template should still be reused. - infos.args.pop_back(); - infos.args.push_back(TemplateArgument(m_ast->getASTContext(), - llvm::APSInt(llvm::APInt(8, 123)), - m_ast->getASTContext().SignedCharTy)); - ExpectReusedTemplate(" (I = 123)", infos, - type_and_char_value); - - // Change the type of the I parameter to int so we have . - // The class template from above can't be reused. - infos.args.pop_back(); - infos.args.push_back(TemplateArgument(m_ast->getASTContext(), - llvm::APSInt(llvm::APInt(32, 47)), - m_ast->getASTContext().IntTy)); - ExpectNewTemplate(" (I = 123)", infos); - - // Test a second type parameter will also cause a new template to be created. - // We now have . - infos.names.push_back("B"); - infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy)); - ClassTemplateDecl *type_and_char_value_and_type = - ExpectNewTemplate("", infos); - - // Remove all the names from the parameters which shouldn't influence the - // way the templates get merged. - infos.names = {"", "", ""}; - ExpectReusedTemplate("", infos, - type_and_char_value_and_type); -} - -TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) { - // The same as FindExistingTemplates but for templates with parameter packs. - - TypeSystemClang::TemplateParameterInfos infos; - infos.packed_args = - std::make_unique(); - infos.packed_args->names = {"", ""}; - infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy), - TemplateArgument(m_ast->getASTContext().IntTy)}; - ClassTemplateDecl *type_pack = - ExpectNewTemplate(" (int, int)", infos); - - // Special case: An instantiation for a parameter pack with no values fits - // to whatever class template we find. There isn't enough information to - // do an actual comparison here. - infos.packed_args = - std::make_unique(); - ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack); - - // Change the type content of pack type values. - infos.packed_args->names = {"", ""}; - infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy), - TemplateArgument(m_ast->getASTContext().LongTy)}; - ExpectReusedTemplate(" (int, long)", infos, type_pack); - - // Change the number of pack values. - infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)}; - ExpectReusedTemplate(" (int)", infos, type_pack); - - // The names of the pack values shouldn't matter. - infos.packed_args->names = {"A", "B"}; - ExpectReusedTemplate(" (int)", infos, type_pack); - - // Changing the kind of template argument will create a new template. - infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(), - llvm::APSInt(llvm::APInt(32, 1)), - m_ast->getASTContext().IntTy)}; - ClassTemplateDecl *int_pack = ExpectNewTemplate(" (int = 1)", infos); - - // Changing the value of integral parameters will not create a new template. - infos.packed_args->args = {TemplateArgument( - m_ast->getASTContext(), llvm::APSInt(llvm::APInt(32, 123)), - m_ast->getASTContext().IntTy)}; - ExpectReusedTemplate(" (int = 123)", infos, int_pack); - - // Changing the integral type will create a new template. - infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(), - llvm::APSInt(llvm::APInt(64, 1)), - m_ast->getASTContext().LongTy)}; - ExpectNewTemplate(" (long = 1)", infos); - - // Prependinding a non-pack parameter will create a new template. - infos.names = {"T"}; - infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; - ExpectNewTemplate(" (T = int, long = 1)", infos); -} - -TEST_F(TestTypeSystemClang, OnlyPackName) { - TypeSystemClang::TemplateParameterInfos infos; - infos.pack_name = "A"; - EXPECT_FALSE(infos.IsValid()); -} - -static QualType makeConstInt(clang::ASTContext &ctxt) { - QualType result(ctxt.IntTy); - result.addConst(); - return result; -} - -TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) { - clang::ASTContext &ctxt = m_ast->getASTContext(); - auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); - QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt)); - EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); -} - -TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) { - clang::ASTContext &ctxt = m_ast->getASTContext(); - QualType t = ctxt.getTypeOfType(makeConstInt(ctxt)); - EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); -} - -TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) { - clang::ASTContext &ctxt = m_ast->getASTContext(); - auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); - QualType t = ctxt.getTypeOfExprType(nullptr_expr); - EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); -} - -TEST_F(TestTypeSystemClang, TestGetTypeClassNested) { - clang::ASTContext &ctxt = m_ast->getASTContext(); - QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt)); - QualType t = ctxt.getTypeOfType(t_base); - EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); -} - -TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) { - // Tests creating a function template. - - CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); - clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); - - // Prepare the declarations/types we need for the template. - CompilerType clang_type = - m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); - FunctionDecl *func = m_ast->CreateFunctionDeclaration( - TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, - false); - TypeSystemClang::TemplateParameterInfos empty_params; - - // Create the actual function template. - clang::FunctionTemplateDecl *func_template = - m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func, - empty_params); - - EXPECT_EQ(TU, func_template->getDeclContext()); - EXPECT_EQ("foo", func_template->getName()); - EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess()); -} - -TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) { - // Tests creating a function template inside a record. - - CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); - clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); - - // Create a record we can put the function template int. - CompilerType record_type = - clang_utils::createRecordWithField(*m_ast, "record", int_type, "field"); - clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type); - - // Prepare the declarations/types we need for the template. - CompilerType clang_type = - m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); - // We create the FunctionDecl for the template in the TU DeclContext because: - // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can). - // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine. - FunctionDecl *func = m_ast->CreateFunctionDeclaration( - TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, - false); - TypeSystemClang::TemplateParameterInfos empty_params; - - // Create the actual function template. - clang::FunctionTemplateDecl *func_template = - m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func, - empty_params); - - EXPECT_EQ(record, func_template->getDeclContext()); - EXPECT_EQ("foo", func_template->getName()); - EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess()); -} - -TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) { - // We need to simulate this behavior in our AST that we construct as we don't - // have a Sema instance that can do this for us: - // C++11 [class.copy]p7, p18: - // If the class definition declares a move constructor or move assignment - // operator, an implicitly declared copy constructor or copy assignment - // operator is defined as deleted. - - // Create a record and start defining it. - llvm::StringRef class_name = "S"; - CompilerType t = clang_utils::createRecord(*m_ast, class_name); - m_ast->StartTagDeclarationDefinition(t); - - // Create a move constructor that will delete the implicit copy constructor. - CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); - CompilerType param_type = t.GetRValueReferenceType(); - CompilerType function_type = - m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, - /*variadic=*/false, /*quals*/ 0U); - bool is_virtual = false; - bool is_static = false; - bool is_inline = false; - bool is_explicit = true; - bool is_attr_used = false; - bool is_artificial = false; - m_ast->AddMethodToCXXRecordType( - t.GetOpaqueQualType(), class_name, nullptr, function_type, - lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, - is_explicit, is_attr_used, is_artificial); - - // Complete the definition and check the created record. - m_ast->CompleteTagDeclarationDefinition(t); - auto *record = llvm::cast(ClangUtil::GetAsTagDecl(t)); - // We can't call defaultedCopyConstructorIsDeleted() as this requires that - // the Decl passes through Sema which will actually compute this field. - // Instead we check that there is no copy constructor declared by the user - // which only leaves a non-deleted defaulted copy constructor as an option - // that our record will have no simple copy constructor. - EXPECT_FALSE(record->hasUserDeclaredCopyConstructor()); - EXPECT_FALSE(record->hasSimpleCopyConstructor()); -} - -TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) { - // Tests that we don't delete the a user-defined copy constructor when - // a move constructor is provided. - // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test. - llvm::StringRef class_name = "S"; - CompilerType t = clang_utils::createRecord(*m_ast, class_name); - m_ast->StartTagDeclarationDefinition(t); - - CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); - bool is_virtual = false; - bool is_static = false; - bool is_inline = false; - bool is_explicit = true; - bool is_attr_used = false; - bool is_artificial = false; - // Create a move constructor. - { - CompilerType param_type = t.GetRValueReferenceType(); - CompilerType function_type = - m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, - /*variadic=*/false, /*quals*/ 0U); - m_ast->AddMethodToCXXRecordType( - t.GetOpaqueQualType(), class_name, nullptr, function_type, - lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, - is_explicit, is_attr_used, is_artificial); - } - // Create a copy constructor. - { - CompilerType param_type = t.GetLValueReferenceType().AddConstModifier(); - CompilerType function_type = - m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, - /*variadic=*/false, /*quals*/ 0U); - m_ast->AddMethodToCXXRecordType( - t.GetOpaqueQualType(), class_name, nullptr, function_type, - lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, - is_explicit, is_attr_used, is_artificial); - } - - // Complete the definition and check the created record. - m_ast->CompleteTagDeclarationDefinition(t); - auto *record = llvm::cast(ClangUtil::GetAsTagDecl(t)); - EXPECT_TRUE(record->hasUserDeclaredCopyConstructor()); -} - -TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) { - // Create an interface decl and mark it as having external storage. - CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(), - OptionalClangModuleID(), - /*IsForwardDecl*/ false, - /*IsInternal*/ false); - ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c); - m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true); - EXPECT_TRUE(interface->hasExternalLexicalStorage()); - - // Add a method to the interface. - std::vector args; - CompilerType func_type = - m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt), - args.data(), args.size(), /*variadic*/ false, - /*quals*/ 0, clang::CallingConv::CC_C); - bool variadic = false; - bool artificial = false; - bool objc_direct = false; - clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType( - c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic, - objc_direct); - ASSERT_NE(method, nullptr); - - // The interface decl should still have external lexical storage. - EXPECT_TRUE(interface->hasExternalLexicalStorage()); - - // Test some properties of the created ObjCMethodDecl. - EXPECT_FALSE(method->isVariadic()); - EXPECT_TRUE(method->isImplicit()); - EXPECT_FALSE(method->isDirectMethod()); - EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo"); -} - -TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) { - LangOptions lang_opts; - EXPECT_EQ( - ScratchTypeSystemClang::DefaultAST, - ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); - - lang_opts.Modules = true; - EXPECT_EQ( - ScratchTypeSystemClang::IsolatedASTKind::CppModules, - ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); -} - -TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) { - CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt); - lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr, - 0, {}, {}, compiler_type, - lldb_private::Type::ResolveState::Full); - // Test that getting the execution module when no type system is present - // is handled gracefully. - ModuleSP module = t.GetExeModule(); - EXPECT_EQ(module.get(), nullptr); -} - diff --git a/gnu/llvm/lldb/unittests/SymbolFile/CMakeLists.txt b/gnu/llvm/lldb/unittests/SymbolFile/CMakeLists.txt deleted file mode 100644 index 804555f8c90..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_subdirectory(DWARF) -add_subdirectory(NativePDB) -if (LLVM_ENABLE_DIA_SDK) - add_subdirectory(PDB) -endif() diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt deleted file mode 100644 index 76215c31b2a..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -add_lldb_unittest(SymbolFileDWARFTests - DWARFASTParserClangTests.cpp - DWARFDIETest.cpp - DWARFUnitTest.cpp - SymbolFileDWARFTests.cpp - XcodeSDKModuleTests.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbSymbol - lldbPluginObjectFilePECOFF - lldbPluginSymbolFileDWARF - lldbPluginSymbolFilePDB - lldbPluginTypeSystemClang - lldbPluginPlatformMacOSX - lldbUtilityHelpers - lldbSymbolHelpers - LINK_COMPONENTS - Support - DebugInfoPDB - ) - -set(test_inputs - test-dwarf.exe) - -add_unittest_inputs(SymbolFileDWARFTests "${test_inputs}") diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp deleted file mode 100644 index 435da1f9643..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ /dev/null @@ -1,118 +0,0 @@ -//===-- DWARFASTParserClangTests.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 "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" -#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" -#include "Plugins/SymbolFile/DWARF/DWARFDIE.h" -#include "TestingSupport/Symbol/YAMLModuleTester.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { -class DWARFASTParserClangTests : public testing::Test {}; - -class DWARFASTParserClangStub : public DWARFASTParserClang { -public: - using DWARFASTParserClang::DWARFASTParserClang; - using DWARFASTParserClang::LinkDeclContextToDIE; - - std::vector GetDeclContextToDIEMapKeys() { - std::vector keys; - for (const auto &it : m_decl_ctx_to_die) - keys.push_back(it.first); - return keys; - } -}; -} // namespace - -// If your implementation needs to dereference the dummy pointers we are -// defining here, causing this test to fail, feel free to delete it. -TEST_F(DWARFASTParserClangTests, - EnsureAllDIEsInDeclContextHaveBeenParsedParsesOnlyMatchingEntries) { - - /// Auxiliary debug info. - const char *yamldata = R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 -DWARF: - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_language - Form: DW_FORM_data2 - - Code: 0x00000002 - Tag: DW_TAG_base_type - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_encoding - Form: DW_FORM_data1 - - Attribute: DW_AT_byte_size - Form: DW_FORM_data1 - debug_info: - - Version: 4 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000001 - Values: - - Value: 0x000000000000000C - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000007 # DW_ATE_unsigned - - Value: 0x0000000000000004 - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000007 # DW_ATE_unsigned - - Value: 0x0000000000000008 - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000005 # DW_ATE_signed - - Value: 0x0000000000000008 - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000008 # DW_ATE_unsigned_char - - Value: 0x0000000000000001 - - AbbrCode: 0x00000000 -)"; - - YAMLModuleTester t(yamldata); - ASSERT_TRUE((bool)t.GetDwarfUnit()); - - TypeSystemClang ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple()); - DWARFASTParserClangStub ast_parser(ast_ctx); - - DWARFUnit *unit = t.GetDwarfUnit(); - const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); - const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); - const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); - const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling(); - const DWARFDebugInfoEntry *die_child3 = die_child2->GetSibling(); - std::vector dies = { - DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1), - DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)}; - std::vector decl_ctxs = { - (clang::DeclContext *)1LL, (clang::DeclContext *)2LL, - (clang::DeclContext *)2LL, (clang::DeclContext *)3LL}; - for (int i = 0; i < 4; ++i) - ast_parser.LinkDeclContextToDIE(decl_ctxs[i], dies[i]); - ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed( - CompilerDeclContext(nullptr, decl_ctxs[1])); - - EXPECT_THAT(ast_parser.GetDeclContextToDIEMapKeys(), - testing::UnorderedElementsAre(decl_ctxs[0], decl_ctxs[3])); -} - diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp deleted file mode 100644 index 7fc37cefea2..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp +++ /dev/null @@ -1,105 +0,0 @@ -//===-- DWARFDIETest.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 "Plugins/SymbolFile/DWARF/DWARFDIE.h" -#include "TestingSupport/Symbol/YAMLModuleTester.h" -#include "llvm/ADT/STLExtras.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(DWARFDIETest, ChildIteration) { - // Tests DWARFDIE::child_iterator. - - const char *yamldata = R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 -DWARF: - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_language - Form: DW_FORM_data2 - - Code: 0x00000002 - Tag: DW_TAG_base_type - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_encoding - Form: DW_FORM_data1 - - Attribute: DW_AT_byte_size - Form: DW_FORM_data1 - debug_info: - - Version: 4 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000001 - Values: - - Value: 0x000000000000000C - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000007 # DW_ATE_unsigned - - Value: 0x0000000000000004 - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000007 # DW_ATE_unsigned - - Value: 0x0000000000000008 - - AbbrCode: 0x00000002 - Values: - - Value: 0x0000000000000005 # DW_ATE_signed - - Value: 0x0000000000000008 - - AbbrCode: 0x00000000 -)"; - - YAMLModuleTester t(yamldata); - ASSERT_TRUE((bool)t.GetDwarfUnit()); - - DWARFUnit *unit = t.GetDwarfUnit(); - const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); - - // Create a DWARFDIE that has three DW_TAG_base_type children. - DWARFDIE top_die(unit, die_first); - - // Create the iterator range that has the three tags as elements. - llvm::iterator_range children = top_die.children(); - - // Compare begin() to the first child DIE. - DWARFDIE::child_iterator child_iter = children.begin(); - ASSERT_NE(child_iter, children.end()); - const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); - EXPECT_EQ((*child_iter).GetDIE(), die_child0); - - // Step to the second child DIE. - ++child_iter; - ASSERT_NE(child_iter, children.end()); - const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); - EXPECT_EQ((*child_iter).GetDIE(), die_child1); - - // Step to the third child DIE. - ++child_iter; - ASSERT_NE(child_iter, children.end()); - const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling(); - EXPECT_EQ((*child_iter).GetDIE(), die_child2); - - // Step to the end of the range. - ++child_iter; - EXPECT_EQ(child_iter, children.end()); - - // Take one of the DW_TAG_base_type DIEs (which has no children) and make - // sure the children range is now empty. - DWARFDIE no_children_die(unit, die_child0); - EXPECT_TRUE(no_children_die.children().empty()); -} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp deleted file mode 100644 index f5cfd1e6112..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//===-- DWARFUnitTest.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 "Plugins/SymbolFile/DWARF/DWARFUnit.h" -#include "TestingSupport/Symbol/YAMLModuleTester.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(DWARFUnitTest, NullUnitDie) { - // Make sure we don't crash parsing a null unit DIE. - const char *yamldata = R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 -DWARF: - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_language - Form: DW_FORM_data2 - debug_info: - - Version: 4 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000000 -)"; - - YAMLModuleTester t(yamldata); - ASSERT_TRUE((bool)t.GetDwarfUnit()); - - DWARFUnit *unit = t.GetDwarfUnit(); - const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); - ASSERT_NE(die_first, nullptr); - EXPECT_TRUE(die_first->IsNULL()); -} - -TEST(DWARFUnitTest, MissingSentinel) { - // Make sure we don't crash if the debug info is missing a null DIE sentinel. - const char *yamldata = R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 -DWARF: - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_language - Form: DW_FORM_data2 - debug_info: - - Version: 4 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000001 - Values: - - Value: 0x000000000000000C -)"; - - YAMLModuleTester t(yamldata); - ASSERT_TRUE((bool)t.GetDwarfUnit()); - - DWARFUnit *unit = t.GetDwarfUnit(); - const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); - ASSERT_NE(die_first, nullptr); - EXPECT_EQ(die_first->GetFirstChild(), nullptr); - EXPECT_EQ(die_first->GetSibling(), nullptr); -} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/Inputs/test-dwarf.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/Inputs/test-dwarf.cpp deleted file mode 100644 index a987e6a9a36..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/Inputs/test-dwarf.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// Compile with "cl /c /Zi /GR- test.cpp" -// Link with "link test.obj /debug /nodefaultlib /entry:main /out:test.exe" - -int __cdecl _purecall(void) { return 0; } - -int main(int argc, char **argv) { return 0; } diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp deleted file mode 100644 index 92fb798d5d4..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp +++ /dev/null @@ -1,531 +0,0 @@ -//===-- SymbolFileDWARFTests.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 "gtest/gtest.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/PDB/PDBSymbolData.h" -#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - -#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" -#include "Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h" -#include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h" -#include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h" -#include "Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h" -#include "Plugins/SymbolFile/DWARF/DWARFDebugAranges.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Core/Address.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/LineTable.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/DataEncoder.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/StreamString.h" - -using namespace lldb; -using namespace lldb_private; - -class SymbolFileDWARFTests : public testing::Test { - SubsystemRAII - subsystems; - -public: - void SetUp() override { - m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe"); - } - -protected: - std::string m_dwarf_test_exe; -}; - -TEST_F(SymbolFileDWARFTests, TestAbilitiesForDWARF) { - // Test that when we have Dwarf debug info, SymbolFileDWARF is used. - FileSpec fspec(m_dwarf_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - ASSERT_NE(nullptr, symfile); - EXPECT_EQ(symfile->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic()); - - uint32_t expected_abilities = SymbolFile::kAllAbilities; - EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start1) { - // Test that if we have a .debug_abbrev that contains ordered abbreviation - // codes that start at 1, that we get O(1) access. - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(1); // Abbrev code 1 - encoder.PutULEB128(DW_TAG_compile_unit); - encoder.PutHex8(DW_CHILDREN_yes); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(2); // Abbrev code 2 - encoder.PutULEB128(DW_TAG_subprogram); - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(0); // Abbrev code 0 (termination) - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - EXPECT_FALSE(bool(error)); - // Make sure we have O(1) access to each abbreviation by making sure the - // index offset is 1 and not UINT32_MAX - EXPECT_EQ(abbrev_set.GetIndexOffset(), 1u); - - auto abbrev1 = abbrev_set.GetAbbreviationDeclaration(1); - EXPECT_EQ(abbrev1->Tag(), DW_TAG_compile_unit); - EXPECT_TRUE(abbrev1->HasChildren()); - EXPECT_EQ(abbrev1->NumAttributes(), 1u); - auto abbrev2 = abbrev_set.GetAbbreviationDeclaration(2); - EXPECT_EQ(abbrev2->Tag(), DW_TAG_subprogram); - EXPECT_FALSE(abbrev2->HasChildren()); - EXPECT_EQ(abbrev2->NumAttributes(), 1u); -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start5) { - // Test that if we have a .debug_abbrev that contains ordered abbreviation - // codes that start at 5, that we get O(1) access. - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(5); // Abbrev code 5 - encoder.PutULEB128(DW_TAG_compile_unit); - encoder.PutHex8(DW_CHILDREN_yes); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(6); // Abbrev code 6 - encoder.PutULEB128(DW_TAG_subprogram); - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(0); // Abbrev code 0 (termination) - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - EXPECT_FALSE(bool(error)); - // Make sure we have O(1) access to each abbreviation by making sure the - // index offset is 5 and not UINT32_MAX - EXPECT_EQ(abbrev_set.GetIndexOffset(), 5u); - - auto abbrev1 = abbrev_set.GetAbbreviationDeclaration(5); - EXPECT_EQ(abbrev1->Tag(), DW_TAG_compile_unit); - EXPECT_TRUE(abbrev1->HasChildren()); - EXPECT_EQ(abbrev1->NumAttributes(), 1u); - auto abbrev2 = abbrev_set.GetAbbreviationDeclaration(6); - EXPECT_EQ(abbrev2->Tag(), DW_TAG_subprogram); - EXPECT_FALSE(abbrev2->HasChildren()); - EXPECT_EQ(abbrev2->NumAttributes(), 1u); -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevOutOfOrder) { - // Test that if we have a .debug_abbrev that contains unordered abbreviation - // codes, that we can access the information correctly. - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(2); // Abbrev code 2 - encoder.PutULEB128(DW_TAG_compile_unit); - encoder.PutHex8(DW_CHILDREN_yes); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(1); // Abbrev code 1 - encoder.PutULEB128(DW_TAG_subprogram); - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(0); // Abbrev code 0 (termination) - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - EXPECT_FALSE(bool(error)); - // Make sure we don't have O(1) access to each abbreviation by making sure - // the index offset is UINT32_MAX - EXPECT_EQ(abbrev_set.GetIndexOffset(), UINT32_MAX); - - auto abbrev1 = abbrev_set.GetAbbreviationDeclaration(2); - EXPECT_EQ(abbrev1->Tag(), DW_TAG_compile_unit); - EXPECT_TRUE(abbrev1->HasChildren()); - EXPECT_EQ(abbrev1->NumAttributes(), 1u); - auto abbrev2 = abbrev_set.GetAbbreviationDeclaration(1); - EXPECT_EQ(abbrev2->Tag(), DW_TAG_subprogram); - EXPECT_FALSE(abbrev2->HasChildren()); - EXPECT_EQ(abbrev2->NumAttributes(), 1u); -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevInvalidNULLTag) { - // Test that we detect when an abbreviation has a NULL tag and that we get - // an error when decoding. - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(1); // Abbrev code 1 - encoder.PutULEB128(0); // Invalid NULL tag here! - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(0); // Abbrev code 0 (termination) - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - // Verify we get an error - EXPECT_TRUE(bool(error)); - EXPECT_EQ("abbrev decl requires non-null tag.", - llvm::toString(std::move(error))); - -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevNullAttrValidForm) { - // Test that we detect when an abbreviation has a NULL attribute and a non - // NULL form and that we get an error when decoding. - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(1); // Abbrev code 1 - encoder.PutULEB128(DW_TAG_compile_unit); - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(0); // Invalid NULL DW_AT - encoder.PutULEB128(DW_FORM_strp); // With a valid form - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(0); // Abbrev code 0 (termination) - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - // Verify we get an error - EXPECT_TRUE(bool(error)); - EXPECT_EQ("malformed abbreviation declaration attribute", - llvm::toString(std::move(error))); -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevValidAttrNullForm) { - // Test that we detect when an abbreviation has a valid attribute and a - // NULL form and that we get an error when decoding. - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(1); // Abbrev code 1 - encoder.PutULEB128(DW_TAG_compile_unit); - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(DW_AT_name); // Valid attribute - encoder.PutULEB128(0); // NULL form - encoder.PutULEB128(0); - encoder.PutULEB128(0); - - encoder.PutULEB128(0); // Abbrev code 0 (termination) - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - // Verify we get an error - EXPECT_TRUE(bool(error)); - EXPECT_EQ("malformed abbreviation declaration attribute", - llvm::toString(std::move(error))); -} - -TEST_F(SymbolFileDWARFTests, TestAbbrevMissingTerminator) { - // Test that we detect when an abbreviation has a valid attribute and a - // form, but is missing the NULL attribute and form that terminates an - // abbreviation - - const auto byte_order = eByteOrderLittle; - const uint8_t addr_size = 4; - StreamString encoder(Stream::eBinary, addr_size, byte_order); - encoder.PutULEB128(1); // Abbrev code 1 - encoder.PutULEB128(DW_TAG_compile_unit); - encoder.PutHex8(DW_CHILDREN_no); - encoder.PutULEB128(DW_AT_name); - encoder.PutULEB128(DW_FORM_strp); - // Don't add the NULL DW_AT and NULL DW_FORM terminator - - DWARFDataExtractor data; - data.SetData(encoder.GetData(), encoder.GetSize(), byte_order); - DWARFAbbreviationDeclarationSet abbrev_set; - lldb::offset_t data_offset = 0; - llvm::Error error = abbrev_set.extract(data, &data_offset); - // Verify we get an error - EXPECT_TRUE(bool(error)); - EXPECT_EQ("abbreviation declaration attribute list not terminated with a " - "null entry", llvm::toString(std::move(error))); -} - -TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) { - // This `.debug_aranges` table header is a valid 32bit big-endian section - // according to the DWARFv5 spec:6.2.1, but contains segment selectors which - // are not supported by lldb, and should be gracefully rejected - const unsigned char binary_data[] = { - 0, 0, 0, 41, // unit_length (length field not including this field itself) - 0, 2, // DWARF version number (half) - 0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes - // of this test - 4, // address size - 1, // segment size - // alignment for the first tuple which "begins at an offset that is a - // multiple of the size of a single tuple". Tuples are nine bytes in this - // example. - 0, 0, 0, 0, 0, 0, - // BEGIN TUPLES - 1, 0, 0, 0, 4, 0, 0, 0, - 1, // a 1byte object starting at address 4 in segment 1 - 0, 0, 0, 0, 4, 0, 0, 0, - 1, // a 1byte object starting at address 4 in segment 0 - // END TUPLES - 0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator - }; - DWARFDataExtractor data; - data.SetData(static_cast(binary_data), sizeof binary_data, - lldb::ByteOrder::eByteOrderBig); - DWARFDebugArangeSet debug_aranges; - offset_t off = 0; - llvm::Error error = debug_aranges.extract(data, &off); - EXPECT_TRUE(bool(error)); - EXPECT_EQ("segmented arange entries are not supported", - llvm::toString(std::move(error))); - EXPECT_EQ(off, 12U); // Parser should read no further than the segment size -} - -TEST_F(SymbolFileDWARFTests, ParseArangesWithMultipleTerminators) { - // This .debug_aranges set has multiple terminator entries which appear in - // binaries produced by popular linux compilers and linker combinations. We - // must be able to parse all the way through the data for each - // DWARFDebugArangeSet. Previously the DWARFDebugArangeSet::extract() - // function would stop parsing as soon as we ran into a terminator even - // though the length field stated that there was more data that follows. This - // would cause the next DWARFDebugArangeSet to be parsed immediately - // following the first terminator and it would attempt to decode the - // DWARFDebugArangeSet header using the remaining segment + address pairs - // from the remaining bytes. - unsigned char binary_data[] = { - 0, 0, 0, 0, // unit_length that will be set correctly after this - 0, 2, // DWARF version number (uint16_t) - 0, 0, 0, 0, // CU offset (ignored for the purposes of this test) - 4, // address size - 0, // segment size - 0, 0, 0, 0, // alignment for the first tuple - // BEGIN TUPLES - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // premature terminator - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // premature terminator - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, // [0x2000-0x2010) - // END TUPLES - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator - }; - // Set the big endian length correctly. - const offset_t binary_data_size = sizeof(binary_data); - binary_data[3] = (uint8_t)binary_data_size - 4; - DWARFDataExtractor data; - data.SetData(static_cast(binary_data), sizeof binary_data, - lldb::ByteOrder::eByteOrderBig); - DWARFDebugArangeSet set; - offset_t off = 0; - llvm::Error error = set.extract(data, &off); - // Multiple terminators are not fatal as they do appear in binaries. - EXPECT_FALSE(bool(error)); - // Parser should read all terminators to the end of the length specified. - EXPECT_EQ(off, binary_data_size); - ASSERT_EQ(set.NumDescriptors(), 2U); - ASSERT_EQ(set.GetDescriptorRef(0).address, (dw_addr_t)0x1000); - ASSERT_EQ(set.GetDescriptorRef(0).length, (dw_addr_t)0x100); - ASSERT_EQ(set.GetDescriptorRef(1).address, (dw_addr_t)0x2000); - ASSERT_EQ(set.GetDescriptorRef(1).length, (dw_addr_t)0x10); -} - -TEST_F(SymbolFileDWARFTests, ParseArangesIgnoreEmpty) { - // This .debug_aranges set has some address ranges which have zero length - // and we ensure that these are ignored by our DWARFDebugArangeSet parser - // and not included in the descriptors that are returned. - unsigned char binary_data[] = { - 0, 0, 0, 0, // unit_length that will be set correctly after this - 0, 2, // DWARF version number (uint16_t) - 0, 0, 0, 0, // CU offset (ignored for the purposes of this test) - 4, // address size - 0, // segment size - 0, 0, 0, 0, // alignment for the first tuple - // BEGIN TUPLES - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100) - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, // [0x1100-0x1100) - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, // [0x2000-0x2010) - 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // [0x2010-0x2010) - // END TUPLES - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator - }; - // Set the big endian length correctly. - const offset_t binary_data_size = sizeof(binary_data); - binary_data[3] = (uint8_t)binary_data_size - 4; - DWARFDataExtractor data; - data.SetData(static_cast(binary_data), sizeof binary_data, - lldb::ByteOrder::eByteOrderBig); - DWARFDebugArangeSet set; - offset_t off = 0; - llvm::Error error = set.extract(data, &off); - // Multiple terminators are not fatal as they do appear in binaries. - EXPECT_FALSE(bool(error)); - // Parser should read all terminators to the end of the length specified. - // Previously the DWARFDebugArangeSet would stop at the first terminator - // entry and leave the offset in the middle of the current - // DWARFDebugArangeSet data, and that would cause the next extracted - // DWARFDebugArangeSet to fail. - EXPECT_EQ(off, binary_data_size); - ASSERT_EQ(set.NumDescriptors(), 2U); - ASSERT_EQ(set.GetDescriptorRef(0).address, (dw_addr_t)0x1000); - ASSERT_EQ(set.GetDescriptorRef(0).length, (dw_addr_t)0x100); - ASSERT_EQ(set.GetDescriptorRef(1).address, (dw_addr_t)0x2000); - ASSERT_EQ(set.GetDescriptorRef(1).length, (dw_addr_t)0x10); -} - -TEST_F(SymbolFileDWARFTests, ParseAranges) { - // Test we can successfully parse a DWARFDebugAranges. The initial error - // checking code had a bug where it would always return an empty address - // ranges for everything in .debug_aranges and no error. - unsigned char binary_data[] = { - 0, 0, 0, 0, // unit_length that will be set correctly after this - 2, 0, // DWARF version number - 255, 0, 0, 0, // offset into the .debug_info_table - 8, // address size - 0, // segment size - 0, 0, 0, 0, // pad bytes - // BEGIN TUPLES - // First tuple: [0x1000-0x1100) - 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Address 0x1000 - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Size 0x0100 - // Second tuple: [0x2000-0x2100) - 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Address 0x2000 - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Size 0x0100 - // Terminating tuple - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Terminator - }; - // Set the little endian length correctly. - binary_data[0] = sizeof(binary_data) - 4; - DWARFDataExtractor data; - data.SetData(static_cast(binary_data), sizeof binary_data, - lldb::ByteOrder::eByteOrderLittle); - DWARFDebugAranges debug_aranges; - debug_aranges.extract(data); - EXPECT_EQ(debug_aranges.GetNumRanges(), 2u); - EXPECT_EQ(debug_aranges.FindAddress(0x0fff), DW_INVALID_OFFSET); - EXPECT_EQ(debug_aranges.FindAddress(0x1000), 255u); - EXPECT_EQ(debug_aranges.FindAddress(0x1100 - 1), 255u); - EXPECT_EQ(debug_aranges.FindAddress(0x1100), DW_INVALID_OFFSET); - EXPECT_EQ(debug_aranges.FindAddress(0x1fff), DW_INVALID_OFFSET); - EXPECT_EQ(debug_aranges.FindAddress(0x2000), 255u); - EXPECT_EQ(debug_aranges.FindAddress(0x2100 - 1), 255u); - EXPECT_EQ(debug_aranges.FindAddress(0x2100), DW_INVALID_OFFSET); -} - -TEST_F(SymbolFileDWARFTests, ParseArangesSkipErrors) { - // Test we can successfully parse a DWARFDebugAranges that contains some - // valid DWARFDebugArangeSet objects and some with errors as long as their - // length is set correctly. This helps LLDB ensure that it can parse newer - // .debug_aranges version that LLDB currently doesn't support, or ignore - // errors in individual DWARFDebugArangeSet objects as long as the length - // is set correctly. - const unsigned char binary_data[] = { - // This DWARFDebugArangeSet is well formed and has a single address range - // for [0x1000-0x1100) with a CU offset of 0x00000000. - 0, 0, 0, 28, // unit_length that will be set correctly after this - 0, 2, // DWARF version number (uint16_t) - 0, 0, 0, 0, // CU offset = 0x00000000 - 4, // address size - 0, // segment size - 0, 0, 0, 0, // alignment for the first tuple - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator - // This DWARFDebugArangeSet has the correct length, but an invalid - // version. We need to be able to skip this correctly and ignore it. - 0, 0, 0, 20, // unit_length that will be set correctly after this - 0, 44, // invalid DWARF version number (uint16_t) - 0, 0, 1, 0, // CU offset = 0x00000100 - 4, // address size - 0, // segment size - 0, 0, 0, 0, // alignment for the first tuple - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator - // This DWARFDebugArangeSet is well formed and has a single address range - // for [0x2000-0x2100) with a CU offset of 0x00000000. - 0, 0, 0, 28, // unit_length that will be set correctly after this - 0, 2, // DWARF version number (uint16_t) - 0, 0, 2, 0, // CU offset = 0x00000200 - 4, // address size - 0, // segment size - 0, 0, 0, 0, // alignment for the first tuple - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x2000-0x2100) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator - }; - - DWARFDataExtractor data; - data.SetData(static_cast(binary_data), sizeof binary_data, - lldb::ByteOrder::eByteOrderBig); - DWARFDebugAranges debug_aranges; - debug_aranges.extract(data); - EXPECT_EQ(debug_aranges.GetNumRanges(), 2u); - EXPECT_EQ(debug_aranges.FindAddress(0x0fff), DW_INVALID_OFFSET); - EXPECT_EQ(debug_aranges.FindAddress(0x1000), 0u); - EXPECT_EQ(debug_aranges.FindAddress(0x1100 - 1), 0u); - EXPECT_EQ(debug_aranges.FindAddress(0x1100), DW_INVALID_OFFSET); - EXPECT_EQ(debug_aranges.FindAddress(0x1fff), DW_INVALID_OFFSET); - EXPECT_EQ(debug_aranges.FindAddress(0x2000), 0x200u); - EXPECT_EQ(debug_aranges.FindAddress(0x2100 - 1), 0x200u); - EXPECT_EQ(debug_aranges.FindAddress(0x2100), DW_INVALID_OFFSET); -} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp deleted file mode 100644 index 9fb4602a41e..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//===-- XcodeSDKModuleTests.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 "Plugins/Platform/MacOSX/PlatformMacOSX.h" -#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" -#include "Plugins/SymbolFile/DWARF/DWARFDIE.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/Symbol/YAMLModuleTester.h" -#include "lldb/Core/PluginManager.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -#ifdef __APPLE__ -namespace { -class XcodeSDKModuleTests : public testing::Test { - SubsystemRAII subsystems; -}; -} // namespace - - -TEST_F(XcodeSDKModuleTests, TestModuleGetXcodeSDK) { - const char *yamldata = R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 -DWARF: - debug_str: - - MacOSX10.9.sdk - debug_abbrev: - - Table: - - Code: 0x00000001 - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_no - Attributes: - - Attribute: DW_AT_language - Form: DW_FORM_data2 - - Attribute: DW_AT_APPLE_sdk - Form: DW_FORM_strp - debug_info: - - Version: 2 - AddrSize: 8 - Entries: - - AbbrCode: 0x00000001 - Values: - - Value: 0x000000000000000C - - Value: 0x0000000000000000 - - AbbrCode: 0x00000000 -... -)"; - - YAMLModuleTester t(yamldata); - DWARFUnit *dwarf_unit = t.GetDwarfUnit(); - auto *dwarf_cu = llvm::cast(dwarf_unit); - ASSERT_TRUE(static_cast(dwarf_cu)); - SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF(); - CompUnitSP comp_unit = sym_file.GetCompileUnitAtIndex(0); - ASSERT_TRUE(static_cast(comp_unit.get())); - ModuleSP module = t.GetModule(); - ASSERT_EQ(module->GetSourceMappingList().GetSize(), 0u); - XcodeSDK sdk = sym_file.ParseXcodeSDK(*comp_unit); - ASSERT_EQ(sdk.GetType(), XcodeSDK::Type::MacOSX); - ASSERT_EQ(module->GetSourceMappingList().GetSize(), 1u); -} -#endif diff --git a/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/CMakeLists.txt b/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/CMakeLists.txt deleted file mode 100644 index b82199f21dd..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_lldb_unittest(SymbolFileNativePDBTests - PdbFPOProgramToDWARFExpressionTests.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbSymbol - lldbPluginSymbolFileNativePDB - lldbUtilityHelpers - LINK_COMPONENTS - Support - DebugInfoPDB - ) diff --git a/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp deleted file mode 100644 index 3692f0c94c5..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp +++ /dev/null @@ -1,131 +0,0 @@ -//===-- PDBFPOProgramToDWARFExpressionTests.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 "gtest/gtest.h" - -#include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h" - -#include "lldb/Core/StreamBuffer.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/DebugInfo/DWARF/DWARFExpression.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::npdb; - -/// Valid programs tests - -static void -CheckValidProgramTranslation(llvm::StringRef fpo_program, - llvm::StringRef target_register_name, - llvm::StringRef expected_dwarf_expression) { - // program translation - StreamBuffer<32> stream(Stream::eBinary, 4, eByteOrderLittle); - ASSERT_TRUE(TranslateFPOProgramToDWARFExpression( - fpo_program, target_register_name, llvm::Triple::x86, stream)); - - // print dwarf expression to comparable textual representation - llvm::DataExtractor extractor({stream.GetData(), stream.GetSize()}, - /*IsLittleEndian=*/true, /*AddressSize=*/4); - - std::string result; - llvm::raw_string_ostream os(result); - llvm::DWARFExpression(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32) - .print(os, llvm::DIDumpOptions(), nullptr, nullptr); - - // actual check - ASSERT_EQ(expected_dwarf_expression, os.str()); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentRegisterRef) { - CheckValidProgramTranslation("$T0 $ebp = ", "$T0", "DW_OP_breg6 +0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, MultipleIndependentAssignments) { - CheckValidProgramTranslation("$T1 1 = $T0 0 =", "$T0", "DW_OP_consts +0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, MultipleDependentAssignments) { - CheckValidProgramTranslation( - "$T1 $ebp 4 + = $T0 $T1 8 - 128 @ = ", "$T0", - "DW_OP_breg6 +0, DW_OP_consts +4, DW_OP_plus, DW_OP_consts +8, " - "DW_OP_minus, DW_OP_consts +128, DW_OP_lit1, DW_OP_minus, DW_OP_not, " - "DW_OP_and"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, DependencyChain) { - CheckValidProgramTranslation("$T1 0 = $T0 $T1 = $ebp $T0 =", "$ebp", - "DW_OP_consts +0"); -} - -/// Invalid programs tests -static void -CheckInvalidProgramTranslation(llvm::StringRef fpo_program, - llvm::StringRef target_register_name) { - // initial setup - ArchSpec arch_spec("i686-pc-windows"); - llvm::Triple::ArchType arch_type = arch_spec.GetMachine(); - ByteOrder byte_order = arch_spec.GetByteOrder(); - uint32_t address_size = arch_spec.GetAddressByteSize(); - - // program translation - StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); - EXPECT_FALSE(TranslateFPOProgramToDWARFExpression( - fpo_program, target_register_name, arch_type, stream)); - EXPECT_EQ((size_t)0, stream.GetSize()); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentSingle) { - CheckInvalidProgramTranslation("$T0 0", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentMultiple) { - CheckInvalidProgramTranslation("$T1 0 = $T0 0", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, UnknownOp) { - CheckInvalidProgramTranslation("$T0 $ebp 0 & = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpBinary) { - CheckInvalidProgramTranslation("$T0 0 + = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpUnary) { - CheckInvalidProgramTranslation("$T0 ^ = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, MissingTargetRegister) { - CheckInvalidProgramTranslation("$T1 0 = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, UnresolvedRegisterReference) { - CheckInvalidProgramTranslation("$T0 $abc = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, - UnresolvedRegisterAssignmentReference) { - CheckInvalidProgramTranslation("$T2 0 = $T0 $T1 = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, - UnresolvedCyclicRegisterAssignmentReference) { - CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = ", "$T0"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, - UnresolvedDependentCyclicRegisterAssignmentReference) { - CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = $T2 $T1 =", "$T2"); -} - -TEST(PDBFPOProgramToDWARFExpressionTests, UnsupportedRASearch) { - CheckInvalidProgramTranslation("$T0 .raSearch = ", "$T0"); -} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt b/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt deleted file mode 100644 index 8fc2167ee6b..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -add_lldb_unittest(SymbolFilePDBTests - SymbolFilePDBTests.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbSymbol - lldbPluginObjectFilePECOFF - lldbPluginSymbolFileDWARF - lldbPluginSymbolFilePDB - lldbPluginTypeSystemClang - lldbUtilityHelpers - LLVMTestingSupport - LINK_COMPONENTS - Support - DebugInfoPDB - ) - -set(test_inputs - test-pdb.exe - test-pdb.pdb - test-pdb-types.exe - test-pdb-types.pdb) - -add_unittest_inputs(SymbolFilePDBTests "${test_inputs}") diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp deleted file mode 100644 index 33d7df0e4a8..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Compile with "cl /c /Zi /GR- test-pdb-alt.cpp" -// Link with "link test-pdb.obj test-pdb-alt.obj /debug /nodefaultlib -// /entry:main /out:test-pdb.exe" - -#include "test-pdb.h" - -int bar(int n) { return n - 1; } diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h deleted file mode 100644 index 9d399555823..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef TEST_PDB_NESTED_H -#define TEST_PDB_NESTED_H - -inline int baz(int n) { return n + 1; } - -#endif diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp deleted file mode 100644 index 363be7b3c49..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Compile with "cl /c /Zi /GR- /EHsc test-pdb-types.cpp" -// Link with "link test-pdb-types.obj /debug /nodefaultlib /entry:main -// /out:test-pdb-types.exe" - -using namespace std; - -// Sizes of builtin types -static const int sizeof_char = sizeof(char); -static const int sizeof_uchar = sizeof(unsigned char); -static const int sizeof_short = sizeof(short); -static const int sizeof_ushort = sizeof(unsigned short); -static const int sizeof_int = sizeof(int); -static const int sizeof_uint = sizeof(unsigned int); -static const int sizeof_long = sizeof(long); -static const int sizeof_ulong = sizeof(unsigned long); -static const int sizeof_longlong = sizeof(long long); -static const int sizeof_ulonglong = sizeof(unsigned long long); -static const int sizeof_int64 = sizeof(__int64); -static const int sizeof_uint64 = sizeof(unsigned __int64); -static const int sizeof_float = sizeof(float); -static const int sizeof_double = sizeof(double); -static const int sizeof_bool = sizeof(bool); -static const int sizeof_wchar = sizeof(wchar_t); - -enum Enum { - EValue1 = 1, - EValue2 = 2, -}; - -enum ShortEnum : short { ESValue1 = 1, ESValue2 = 2 }; - -namespace NS { -class NSClass { - float f; - double d; -}; -} // namespace NS - -class Class { -public: - class NestedClass { - Enum e; - }; - ShortEnum se; -}; - -int test_func(int a, int b) { return a + b; } - -typedef Class ClassTypedef; -typedef NS::NSClass NSClassTypedef; -typedef int (*FuncPointerTypedef)(); -typedef int (*VariadicFuncPointerTypedef)(char, ...); -FuncPointerTypedef GlobalFunc; -VariadicFuncPointerTypedef GlobalVariadicFunc; -int GlobalArray[10]; - -static const int sizeof_NSClass = sizeof(NS::NSClass); -static const int sizeof_Class = sizeof(Class); -static const int sizeof_NestedClass = sizeof(Class::NestedClass); -static const int sizeof_Enum = sizeof(Enum); -static const int sizeof_ShortEnum = sizeof(ShortEnum); -static const int sizeof_ClassTypedef = sizeof(ClassTypedef); -static const int sizeof_NSClassTypedef = sizeof(NSClassTypedef); -static const int sizeof_FuncPointerTypedef = sizeof(FuncPointerTypedef); -static const int sizeof_VariadicFuncPointerTypedef = - sizeof(VariadicFuncPointerTypedef); -static const int sizeof_GlobalArray = sizeof(GlobalArray); - -int main(int argc, char **argv) { - ShortEnum e1; - Enum e2; - Class c1; - Class::NestedClass c2; - NS::NSClass c3; - - ClassTypedef t1; - NSClassTypedef t2; - return test_func(1, 2); -} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdb b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdb deleted file mode 100644 index 1a249e3635c..00000000000 Binary files a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdb and /dev/null differ diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.cpp b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.cpp deleted file mode 100644 index 77956acd875..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// Compile with "cl /c /Zi /GR- test-pdb.cpp" -// Link with "link test-pdb.obj /debug /nodefaultlib /entry:main -// /out:test-pdb.exe" - -#include "test-pdb.h" - -int __cdecl _purecall(void) { return 0; } - -int main(int argc, char **argv) { return foo(argc) + bar(argc); } diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.h b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.h deleted file mode 100644 index c935de334d7..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef TEST_PDB_H -#define TEST_PDB_H - -#include "test-pdb-nested.h" - -int bar(int n); - -inline int foo(int n) { return baz(n) + 1; } - -#endif diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.pdb b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.pdb deleted file mode 100644 index f43d334d215..00000000000 Binary files a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb.pdb and /dev/null differ diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp deleted file mode 100644 index 7c7d1902eef..00000000000 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ /dev/null @@ -1,627 +0,0 @@ -//===-- PythonDataObjectsTests.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 "gtest/gtest.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/PDB/PDBSymbolData.h" -#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Testing/Support/Error.h" - -#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Core/Address.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/TypeMap.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/FileSpec.h" - -#if defined(_WIN32) -#include "lldb/Host/windows/windows.h" -#include -#endif - -#include - -using namespace lldb_private; - -class SymbolFilePDBTests : public testing::Test { -public: - void SetUp() override { -// Initialize and TearDown the plugin every time, so we get a brand new -// AST every time so that modifications to the AST from each test don't -// leak into the next test. -#if defined(_WIN32) - ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); -#endif - - FileSystem::Initialize(); - HostInfo::Initialize(); - ObjectFilePECOFF::Initialize(); - SymbolFileDWARF::Initialize(); - TypeSystemClang::Initialize(); - SymbolFilePDB::Initialize(); - - m_pdb_test_exe = GetInputFilePath("test-pdb.exe"); - m_types_test_exe = GetInputFilePath("test-pdb-types.exe"); - } - - void TearDown() override { - SymbolFilePDB::Terminate(); - TypeSystemClang::Initialize(); - SymbolFileDWARF::Terminate(); - ObjectFilePECOFF::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - -#if defined(_WIN32) - ::CoUninitialize(); -#endif - } - -protected: - std::string m_pdb_test_exe; - std::string m_types_test_exe; - - bool FileSpecMatchesAsBaseOrFull(const FileSpec &left, - const FileSpec &right) const { - // If the filenames don't match, the paths can't be equal - if (!left.FileEquals(right)) - return false; - // If BOTH have a directory, also compare the directories. - if (left.GetDirectory() && right.GetDirectory()) - return left.DirectoryEquals(right); - - // If one has a directory but not the other, they match. - return true; - } - - void VerifyLineEntry(lldb::ModuleSP module, const SymbolContext &sc, - const FileSpec &spec, LineTable <, uint32_t line, - lldb::addr_t addr) { - LineEntry entry; - Address address; - EXPECT_TRUE(module->ResolveFileAddress(addr, address)); - - EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry)); - EXPECT_EQ(line, entry.line); - EXPECT_EQ(address, entry.range.GetBaseAddress()); - - EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.file)); - } - - bool ContainsCompileUnit(const SymbolContextList &sc_list, - const FileSpec &spec) const { - for (size_t i = 0; i < sc_list.GetSize(); ++i) { - const SymbolContext &sc = sc_list[i]; - if (FileSpecMatchesAsBaseOrFull(sc.comp_unit->GetPrimaryFile(), spec)) - return true; - } - return false; - } - - uint64_t GetGlobalConstantInteger(llvm::pdb::IPDBSession &session, - llvm::StringRef var) const { - auto global = session.getGlobalScope(); - auto results = - global->findChildren(llvm::pdb::PDB_SymType::Data, var, - llvm::pdb::PDB_NameSearchFlags::NS_Default); - uint32_t count = results->getChildCount(); - if (count == 0) - return -1; - - auto item = results->getChildAtIndex(0); - auto symbol = llvm::dyn_cast(item.get()); - if (!symbol) - return -1; - llvm::pdb::Variant value = symbol->getValue(); - switch (value.Type) { - case llvm::pdb::PDB_VariantType::Int16: - return value.Value.Int16; - case llvm::pdb::PDB_VariantType::Int32: - return value.Value.Int32; - case llvm::pdb::PDB_VariantType::UInt16: - return value.Value.UInt16; - case llvm::pdb::PDB_VariantType::UInt32: - return value.Value.UInt32; - default: - return 0; - } - } -}; - -TEST_F(SymbolFilePDBTests, TestAbilitiesForPDB) { - // Test that when we have PDB debug info, SymbolFilePDB is used. - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - EXPECT_NE(nullptr, symfile); - EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic()); - - uint32_t expected_abilities = SymbolFile::kAllAbilities; - EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); -} - -TEST_F(SymbolFilePDBTests, TestResolveSymbolContextBasename) { - // Test that attempting to call ResolveSymbolContext with only a basename - // finds all full paths - // with the same basename - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - - FileSpec header_spec("test-pdb.cpp"); - SymbolContextList sc_list; - SourceLocationSpec location_spec(header_spec, /*line=*/0); - uint32_t result_count = symfile->ResolveSymbolContext( - location_spec, lldb::eSymbolContextCompUnit, sc_list); - EXPECT_EQ(1u, result_count); - EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec)); -} - -TEST_F(SymbolFilePDBTests, TestResolveSymbolContextFullPath) { - // Test that attempting to call ResolveSymbolContext with a full path only - // finds the one source - // file that matches the full path. - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - - FileSpec header_spec( - R"spec(D:\src\llvm\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.cpp)spec"); - SymbolContextList sc_list; - SourceLocationSpec location_spec(header_spec, /*line=*/0); - uint32_t result_count = symfile->ResolveSymbolContext( - location_spec, lldb::eSymbolContextCompUnit, sc_list); - EXPECT_GE(1u, result_count); - EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec)); -} - -TEST_F(SymbolFilePDBTests, TestLookupOfHeaderFileWithInlines) { - // Test that when looking up a header file via ResolveSymbolContext (i.e. a - // file that was not by itself - // compiled, but only contributes to the combined code of other source files), - // a SymbolContext is returned - // for each compiland which has line contributions from the requested header. - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - - FileSpec header_specs[] = {FileSpec("test-pdb.h"), - FileSpec("test-pdb-nested.h")}; - FileSpec main_cpp_spec("test-pdb.cpp"); - FileSpec alt_cpp_spec("test-pdb-alt.cpp"); - for (const auto &hspec : header_specs) { - SymbolContextList sc_list; - SourceLocationSpec location_spec(hspec, /*line=*/0, /*column=*/llvm::None, - /*check_inlines=*/true); - uint32_t result_count = symfile->ResolveSymbolContext( - location_spec, lldb::eSymbolContextCompUnit, sc_list); - EXPECT_EQ(2u, result_count); - EXPECT_TRUE(ContainsCompileUnit(sc_list, main_cpp_spec)); - EXPECT_TRUE(ContainsCompileUnit(sc_list, alt_cpp_spec)); - } -} - -TEST_F(SymbolFilePDBTests, TestLookupOfHeaderFileWithNoInlines) { - // Test that when looking up a header file via ResolveSymbolContext (i.e. a - // file that was not by itself - // compiled, but only contributes to the combined code of other source files), - // that if check_inlines - // is false, no SymbolContexts are returned. - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - - FileSpec header_specs[] = {FileSpec("test-pdb.h"), - FileSpec("test-pdb-nested.h")}; - for (const auto &hspec : header_specs) { - SymbolContextList sc_list; - SourceLocationSpec location_spec(hspec, /*line=*/0); - uint32_t result_count = symfile->ResolveSymbolContext( - location_spec, lldb::eSymbolContextCompUnit, sc_list); - EXPECT_EQ(0u, result_count); - } -} - -TEST_F(SymbolFilePDBTests, TestLineTablesMatchAll) { - // Test that when calling ResolveSymbolContext with a line number of 0, all - // line entries from - // the specified files are returned. - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - - FileSpec source_file("test-pdb.cpp"); - FileSpec header1("test-pdb.h"); - FileSpec header2("test-pdb-nested.h"); - uint32_t cus = symfile->GetNumCompileUnits(); - EXPECT_EQ(2u, cus); - - SymbolContextList sc_list; - lldb::SymbolContextItem scope = - lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; - - SourceLocationSpec location_spec( - source_file, /*line=*/0, /*column=*/llvm::None, /*check_inlines=*/true); - uint32_t count = symfile->ResolveSymbolContext(location_spec, scope, sc_list); - EXPECT_EQ(1u, count); - SymbolContext sc; - EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); - - LineTable *lt = sc.comp_unit->GetLineTable(); - EXPECT_NE(nullptr, lt); - count = lt->GetSize(); - // We expect one extra entry for termination (per function) - EXPECT_EQ(16u, count); - - VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040); - VerifyLineEntry(module, sc, source_file, *lt, 8, 0x401043); - VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045); - - VerifyLineEntry(module, sc, source_file, *lt, 13, 0x401050); - VerifyLineEntry(module, sc, source_file, *lt, 14, 0x401054); - VerifyLineEntry(module, sc, source_file, *lt, 15, 0x401070); - - VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090); - VerifyLineEntry(module, sc, header1, *lt, 10, 0x401093); - VerifyLineEntry(module, sc, header1, *lt, 11, 0x4010a2); - - VerifyLineEntry(module, sc, header2, *lt, 5, 0x401080); - VerifyLineEntry(module, sc, header2, *lt, 6, 0x401083); - VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089); -} - -TEST_F(SymbolFilePDBTests, TestLineTablesMatchSpecific) { - // Test that when calling ResolveSymbolContext with a specific line number, - // only line entries - // which match the requested line are returned. - FileSpec fspec(m_pdb_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFile *symfile = module->GetSymbolFile(); - - FileSpec source_file("test-pdb.cpp"); - FileSpec header1("test-pdb.h"); - FileSpec header2("test-pdb-nested.h"); - uint32_t cus = symfile->GetNumCompileUnits(); - EXPECT_EQ(2u, cus); - - SymbolContextList sc_list; - lldb::SymbolContextItem scope = - lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; - - // First test with line 7, and verify that only line 7 entries are added. - SourceLocationSpec location_spec( - source_file, /*line=*/7, /*column=*/llvm::None, /*check_inlines=*/true); - uint32_t count = symfile->ResolveSymbolContext(location_spec, scope, sc_list); - EXPECT_EQ(1u, count); - SymbolContext sc; - EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); - - LineTable *lt = sc.comp_unit->GetLineTable(); - EXPECT_NE(nullptr, lt); - count = lt->GetSize(); - // We expect one extra entry for termination - EXPECT_EQ(3u, count); - - VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040); - VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089); - - sc_list.Clear(); - // Then test with line 9, and verify that only line 9 entries are added. - location_spec = SourceLocationSpec( - source_file, /*line=*/9, /*column=*/llvm::None, /*check_inlines=*/true); - count = symfile->ResolveSymbolContext(location_spec, scope, sc_list); - EXPECT_EQ(1u, count); - EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); - - lt = sc.comp_unit->GetLineTable(); - EXPECT_NE(nullptr, lt); - count = lt->GetSize(); - // We expect one extra entry for termination - EXPECT_EQ(3u, count); - - VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045); - VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090); -} - -TEST_F(SymbolFilePDBTests, TestSimpleClassTypes) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); - llvm::DenseSet searched_files; - TypeMap results; - symfile->FindTypes(ConstString("Class"), CompilerDeclContext(), 0, - searched_files, results); - EXPECT_EQ(1u, results.GetSize()); - lldb::TypeSP udt_type = results.GetTypeAtIndex(0); - EXPECT_EQ(ConstString("Class"), udt_type->GetName()); - CompilerType compiler_type = udt_type->GetForwardCompilerType(); - EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType())); - EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_Class"), - udt_type->GetByteSize(nullptr)); -} - -TEST_F(SymbolFilePDBTests, TestNestedClassTypes) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); - llvm::DenseSet searched_files; - TypeMap results; - - auto clang_ast_ctx_or_err = - symfile->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); - ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err, llvm::Succeeded()); - - auto clang_ast_ctx = - llvm::dyn_cast_or_null(&clang_ast_ctx_or_err.get()); - EXPECT_NE(nullptr, clang_ast_ctx); - - symfile->FindTypes(ConstString("Class"), CompilerDeclContext(), 0, - searched_files, results); - EXPECT_EQ(1u, results.GetSize()); - - auto Class = results.GetTypeAtIndex(0); - EXPECT_TRUE(Class); - EXPECT_TRUE(Class->IsValidType()); - - auto ClassCompilerType = Class->GetFullCompilerType(); - EXPECT_TRUE(ClassCompilerType.IsValid()); - - auto ClassDeclCtx = clang_ast_ctx->GetDeclContextForType(ClassCompilerType); - EXPECT_NE(nullptr, ClassDeclCtx); - - // There are two symbols for nested classes: one belonging to enclosing class - // and one is global. We process correctly this case and create the same - // compiler type for both, but `FindTypes` may return more than one type - // (with the same compiler type) because the symbols have different IDs. - - TypeMap more_results; - auto ClassCompilerDeclCtx = CompilerDeclContext(clang_ast_ctx, ClassDeclCtx); - symfile->FindTypes(ConstString("NestedClass"), ClassCompilerDeclCtx, 0, - searched_files, more_results); - EXPECT_LE(1u, more_results.GetSize()); - - lldb::TypeSP udt_type = more_results.GetTypeAtIndex(0); - EXPECT_EQ(ConstString("NestedClass"), udt_type->GetName()); - - CompilerType compiler_type = udt_type->GetForwardCompilerType(); - EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType())); - - EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NestedClass"), - udt_type->GetByteSize(nullptr)); -} - -TEST_F(SymbolFilePDBTests, TestClassInNamespace) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); - llvm::DenseSet searched_files; - TypeMap results; - - auto clang_ast_ctx_or_err = - symfile->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); - ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err, llvm::Succeeded()); - - auto clang_ast_ctx = - llvm::dyn_cast_or_null(&clang_ast_ctx_or_err.get()); - EXPECT_NE(nullptr, clang_ast_ctx); - - clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext(); - - auto tu = ast_ctx.getTranslationUnitDecl(); - EXPECT_NE(nullptr, tu); - - symfile->ParseDeclsForContext(CompilerDeclContext( - clang_ast_ctx, static_cast(tu))); - - auto ns_namespace = symfile->FindNamespace(ConstString("NS"), CompilerDeclContext()); - EXPECT_TRUE(ns_namespace.IsValid()); - - symfile->FindTypes(ConstString("NSClass"), ns_namespace, 0, searched_files, - results); - EXPECT_EQ(1u, results.GetSize()); - - lldb::TypeSP udt_type = results.GetTypeAtIndex(0); - EXPECT_EQ(ConstString("NSClass"), udt_type->GetName()); - - CompilerType compiler_type = udt_type->GetForwardCompilerType(); - EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType())); - - EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NSClass"), - udt_type->GetByteSize(nullptr)); -} - -TEST_F(SymbolFilePDBTests, TestEnumTypes) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); - llvm::DenseSet searched_files; - const char *EnumsToCheck[] = {"Enum", "ShortEnum"}; - for (auto Enum : EnumsToCheck) { - TypeMap results; - symfile->FindTypes(ConstString(Enum), CompilerDeclContext(), 0, - searched_files, results); - EXPECT_EQ(1u, results.GetSize()); - lldb::TypeSP enum_type = results.GetTypeAtIndex(0); - EXPECT_EQ(ConstString(Enum), enum_type->GetName()); - CompilerType compiler_type = enum_type->GetFullCompilerType(); - EXPECT_TRUE(TypeSystemClang::IsEnumType(compiler_type.GetOpaqueQualType())); - clang::EnumDecl *enum_decl = TypeSystemClang::GetAsEnumDecl(compiler_type); - EXPECT_NE(nullptr, enum_decl); - EXPECT_EQ(2, std::distance(enum_decl->enumerator_begin(), - enum_decl->enumerator_end())); - - std::string sizeof_var = "sizeof_"; - sizeof_var.append(Enum); - EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var), - enum_type->GetByteSize(nullptr)); - } -} - -TEST_F(SymbolFilePDBTests, TestArrayTypes) { - // In order to get this test working, we need to support lookup by symbol - // name. Because array - // types themselves do not have names, only the symbols have names (i.e. the - // name of the array). -} - -TEST_F(SymbolFilePDBTests, TestFunctionTypes) { - // In order to get this test working, we need to support lookup by symbol - // name. Because array - // types themselves do not have names, only the symbols have names (i.e. the - // name of the array). -} - -TEST_F(SymbolFilePDBTests, TestTypedefs) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); - llvm::DenseSet searched_files; - TypeMap results; - - const char *TypedefsToCheck[] = {"ClassTypedef", "NSClassTypedef", - "FuncPointerTypedef", - "VariadicFuncPointerTypedef"}; - for (auto Typedef : TypedefsToCheck) { - TypeMap results; - symfile->FindTypes(ConstString(Typedef), CompilerDeclContext(), 0, - searched_files, results); - EXPECT_EQ(1u, results.GetSize()); - lldb::TypeSP typedef_type = results.GetTypeAtIndex(0); - EXPECT_EQ(ConstString(Typedef), typedef_type->GetName()); - CompilerType compiler_type = typedef_type->GetFullCompilerType(); - TypeSystemClang *clang_type_system = - llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); - EXPECT_TRUE( - clang_type_system->IsTypedefType(compiler_type.GetOpaqueQualType())); - - std::string sizeof_var = "sizeof_"; - sizeof_var.append(Typedef); - EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var), - typedef_type->GetByteSize(nullptr)); - } -} - -TEST_F(SymbolFilePDBTests, TestRegexNameMatch) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - TypeMap results; - - symfile->FindTypesByRegex(RegularExpression(".*"), 0, results); - EXPECT_GT(results.GetSize(), 1u); - - // We expect no exception thrown if the given regex can't be compiled - results.Clear(); - symfile->FindTypesByRegex(RegularExpression("**"), 0, results); - EXPECT_EQ(0u, results.GetSize()); -} - -TEST_F(SymbolFilePDBTests, TestMaxMatches) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::DenseSet searched_files; - TypeMap results; - const ConstString name("ClassTypedef"); - symfile->FindTypes(name, CompilerDeclContext(), 0, searched_files, results); - // Try to limit ourselves from 1 to 10 results, otherwise we could - // be doing this thousands of times. The idea is just to make sure - // that for a variety of values, the number of limited results - // always comes out to the number we are expecting. - uint32_t num_results = results.GetSize(); - uint32_t iterations = std::min(num_results, 10u); - for (uint32_t i = 1; i <= iterations; ++i) { - TypeMap more_results; - symfile->FindTypes(name, CompilerDeclContext(), i, searched_files, - more_results); - uint32_t num_limited_results = more_results.GetSize(); - EXPECT_EQ(i, num_limited_results); - } -} - -TEST_F(SymbolFilePDBTests, TestNullName) { - FileSpec fspec(m_types_test_exe); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolFilePDB *symfile = - static_cast(module->GetSymbolFile()); - llvm::DenseSet searched_files; - TypeMap results; - symfile->FindTypes(ConstString(), CompilerDeclContext(), 0, searched_files, - results); - EXPECT_EQ(0u, results.GetSize()); -} - -TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { - FileSpec fspec(m_pdb_test_exe.c_str()); - ArchSpec aspec("i686-pc-windows"); - lldb::ModuleSP module = std::make_shared(fspec, aspec); - - SymbolContextList sc_list; - module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), - lldb::eSymbolTypeAny, sc_list); - EXPECT_EQ(1u, sc_list.GetSize()); - - SymbolContext sc; - EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); - EXPECT_STREQ("int foo(int)", - sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); -} diff --git a/gnu/llvm/lldb/unittests/Target/ABITest.cpp b/gnu/llvm/lldb/unittests/Target/ABITest.cpp deleted file mode 100644 index 6ac34c872f2..00000000000 --- a/gnu/llvm/lldb/unittests/Target/ABITest.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//===-- ABITest.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 "lldb/Target/ABI.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(MCBasedABI, MapRegisterName) { - auto map = [](std::string name) { - MCBasedABI::MapRegisterName(name, "foo", "bar"); - return name; - }; - EXPECT_EQ("bar", map("foo")); - EXPECT_EQ("bar0", map("foo0")); - EXPECT_EQ("bar47", map("foo47")); - EXPECT_EQ("foo47x", map("foo47x")); - EXPECT_EQ("fooo47", map("fooo47")); - EXPECT_EQ("bar47", map("bar47")); -} - diff --git a/gnu/llvm/lldb/unittests/Target/CMakeLists.txt b/gnu/llvm/lldb/unittests/Target/CMakeLists.txt deleted file mode 100644 index 2c3ba699b0e..00000000000 --- a/gnu/llvm/lldb/unittests/Target/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -add_lldb_unittest(TargetTests - ABITest.cpp - ExecutionContextTest.cpp - MemoryRegionInfoTest.cpp - ModuleCacheTest.cpp - PathMappingListTest.cpp - RemoteAwarePlatformTest.cpp - StackFrameRecognizerTest.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbPluginObjectFileELF - lldbPluginPlatformLinux - lldbPluginSymbolFileSymtab - lldbTarget - lldbSymbol - lldbUtility - lldbUtilityHelpers - LINK_COMPONENTS - Support - ) - -add_unittest_inputs(TargetTests TestModule.so) diff --git a/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp b/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp deleted file mode 100644 index 7456faf65f6..00000000000 --- a/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//===-- ExecutionContextTest.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 "lldb/Target/ExecutionContext.h" -#include "Plugins/Platform/Linux/PlatformLinux.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Platform.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Endian.h" -#include "lldb/Utility/Reproducer.h" -#include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" -#include "lldb/lldb-private-enumerations.h" -#include "lldb/lldb-private.h" -#include "llvm/Support/FormatVariadic.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace lldb; - -namespace { -class ExecutionContextTest : public ::testing::Test { -public: - void SetUp() override { - llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); - FileSystem::Initialize(); - HostInfo::Initialize(); - platform_linux::PlatformLinux::Initialize(); - } - void TearDown() override { - platform_linux::PlatformLinux::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - Reproducer::Terminate(); - } -}; - -class DummyProcess : public Process { -public: - using Process::Process; - - bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override { - return true; - } - Status DoDestroy() override { return {}; } - void RefreshStateAfterStop() override {} - size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - Status &error) override { - return 0; - } - bool DoUpdateThreadList(ThreadList &old_thread_list, - ThreadList &new_thread_list) override { - return false; - } - ConstString GetPluginName() override { return ConstString("Dummy"); } - uint32_t GetPluginVersion() override { return 0; } -}; -} // namespace - -TEST_F(ExecutionContextTest, GetByteOrder) { - ExecutionContext exe_ctx(nullptr, nullptr, nullptr); - EXPECT_EQ(endian::InlHostByteOrder(), exe_ctx.GetByteOrder()); -} - -TEST_F(ExecutionContextTest, GetByteOrderTarget) { - ArchSpec arch("powerpc64-pc-linux"); - - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - TargetSP target_sp; - PlatformSP platform_sp; - Status error = debugger_sp->GetTargetList().CreateTarget( - *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); - ASSERT_TRUE(target_sp); - ASSERT_TRUE(target_sp->GetArchitecture().IsValid()); - ASSERT_TRUE(platform_sp); - - ExecutionContext target_ctx(target_sp, false); - EXPECT_EQ(target_sp->GetArchitecture().GetByteOrder(), - target_ctx.GetByteOrder()); -} - -TEST_F(ExecutionContextTest, GetByteOrderProcess) { - ArchSpec arch("powerpc64-pc-linux"); - - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - TargetSP target_sp; - PlatformSP platform_sp; - Status error = debugger_sp->GetTargetList().CreateTarget( - *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); - ASSERT_TRUE(target_sp); - ASSERT_TRUE(target_sp->GetArchitecture().IsValid()); - ASSERT_TRUE(platform_sp); - - ListenerSP listener_sp(Listener::MakeListener("dummy")); - ProcessSP process_sp = std::make_shared(target_sp, listener_sp); - ASSERT_TRUE(process_sp); - - ExecutionContext process_ctx(process_sp); - EXPECT_EQ(process_sp->GetByteOrder(), process_ctx.GetByteOrder()); -} diff --git a/gnu/llvm/lldb/unittests/Target/Inputs/TestModule.c b/gnu/llvm/lldb/unittests/Target/Inputs/TestModule.c deleted file mode 100644 index 6347f726494..00000000000 --- a/gnu/llvm/lldb/unittests/Target/Inputs/TestModule.c +++ /dev/null @@ -1,9 +0,0 @@ -// Compile with $CC -nostdlib -shared TestModule.c -o TestModule.so -// The actual contents of the test module is not important here. I am using this -// because it -// produces an extremely tiny (but still perfectly valid) module. - -void boom(void) { - char *BOOM; - *BOOM = 47; -} diff --git a/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp b/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp deleted file mode 100644 index c272b23b233..00000000000 --- a/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//===-- MemoryRegionInfoTest.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 "lldb/Target/MemoryRegionInfo.h" -#include "llvm/Support/FormatVariadic.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(MemoryRegionInfoTest, Formatv) { - EXPECT_EQ("yes", llvm::formatv("{0}", MemoryRegionInfo::eYes).str()); - EXPECT_EQ("no", llvm::formatv("{0}", MemoryRegionInfo::eNo).str()); - EXPECT_EQ("don't know", llvm::formatv("{0}", MemoryRegionInfo::eDontKnow).str()); -} diff --git a/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp b/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp deleted file mode 100644 index 273338c8369..00000000000 --- a/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "gtest/gtest.h" - -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Target/ModuleCache.h" - -using namespace lldb_private; -using namespace lldb; - -namespace { - -class ModuleCacheTest : public testing::Test { - SubsystemRAII - subsystems; - -public: - void SetUp() override; - -protected: - FileSpec s_cache_dir; - std::string s_test_executable; - - void TryGetAndPut(const FileSpec &cache_dir, const char *hostname, - bool expect_download); -}; -} - -static const char dummy_hostname[] = "dummy_hostname"; -static const char dummy_remote_dir[] = "bin"; -static const char module_name[] = "TestModule.so"; -static const char module_uuid[] = - "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; -static const size_t module_size = 5602; - -static FileSpec GetDummyRemotePath() { - FileSpec fs("/", FileSpec::Style::posix); - fs.AppendPathComponent(dummy_remote_dir); - fs.AppendPathComponent(module_name); - return fs; -} - -static FileSpec GetUuidView(FileSpec spec) { - spec.AppendPathComponent(".cache"); - spec.AppendPathComponent(module_uuid); - spec.AppendPathComponent(module_name); - return spec; -} - -static FileSpec GetSysrootView(FileSpec spec, const char *hostname) { - spec.AppendPathComponent(hostname); - spec.AppendPathComponent(dummy_remote_dir); - spec.AppendPathComponent(module_name); - return spec; -} - -void ModuleCacheTest::SetUp() { - s_cache_dir = HostInfo::GetProcessTempDir(); - s_test_executable = GetInputFilePath(module_name); -} - -static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { - FileSpec uuid_view = GetUuidView(cache_dir); - EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view)) - << "uuid_view is: " << uuid_view.GetCString(); - EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view)); - - FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); - EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view)) - << "sysroot_view is: " << sysroot_view.GetCString(); - EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view)); -} - -void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, - const char *hostname, bool expect_download) { - ModuleCache mc; - ModuleSpec module_spec; - module_spec.GetFileSpec() = GetDummyRemotePath(); - module_spec.GetUUID().SetFromStringRef(module_uuid); - module_spec.SetObjectSize(module_size); - ModuleSP module_sp; - bool did_create; - bool download_called = false; - - Status error = mc.GetAndPut( - cache_dir, hostname, module_spec, - [&download_called, this](const ModuleSpec &module_spec, - const FileSpec &tmp_download_file_spec) { - download_called = true; - EXPECT_STREQ(GetDummyRemotePath().GetCString(), - module_spec.GetFileSpec().GetCString()); - std::error_code ec = llvm::sys::fs::copy_file( - s_test_executable, tmp_download_file_spec.GetCString()); - EXPECT_FALSE(ec); - return Status(); - }, - [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { - return Status("Not supported."); - }, - module_sp, &did_create); - EXPECT_EQ(expect_download, download_called); - - EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); - EXPECT_TRUE(did_create); - ASSERT_TRUE(bool(module_sp)); - - SymbolContextList sc_list; - module_sp->FindFunctionSymbols(ConstString("boom"), eFunctionNameTypeFull, - sc_list); - EXPECT_EQ(1u, sc_list.GetSize()); - EXPECT_STREQ(GetDummyRemotePath().GetCString(), - module_sp->GetPlatformFileSpec().GetCString()); - EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); -} - -TEST_F(ModuleCacheTest, GetAndPut) { - FileSpec test_cache_dir = s_cache_dir; - test_cache_dir.AppendPathComponent("GetAndPut"); - - const bool expect_download = true; - TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); - VerifyDiskState(test_cache_dir, dummy_hostname); -} - -TEST_F(ModuleCacheTest, GetAndPutUuidExists) { - FileSpec test_cache_dir = s_cache_dir; - test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); - - FileSpec uuid_view = GetUuidView(test_cache_dir); - std::error_code ec = - llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); - ASSERT_FALSE(ec); - ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); - ASSERT_FALSE(ec); - - const bool expect_download = false; - TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); - VerifyDiskState(test_cache_dir, dummy_hostname); -} - -TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { - FileSpec test_cache_dir = s_cache_dir; - test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); - - const bool expect_download = true; - TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); - VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); -} diff --git a/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp b/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp deleted file mode 100644 index 90b6f1134a2..00000000000 --- a/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//===-- PathMappingListTest.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 "lldb/Target/PathMappingList.h" -#include "lldb/Utility/FileSpec.h" -#include "llvm/ADT/ArrayRef.h" -#include "gtest/gtest.h" -#include - -using namespace lldb_private; - -namespace { -struct Matches { - FileSpec original; - FileSpec remapped; - Matches(const char *o, const char *r) : original(o), remapped(r) {} - Matches(const char *o, llvm::sys::path::Style style, const char *r) - : original(o, style), remapped(r) {} -}; -} // namespace - -static void TestPathMappings(const PathMappingList &map, - llvm::ArrayRef matches, - llvm::ArrayRef fails) { - ConstString actual_remapped; - for (const auto &fail : fails) { - SCOPED_TRACE(fail.GetCString()); - EXPECT_FALSE(map.RemapPath(fail, actual_remapped)) - << "actual_remapped: " << actual_remapped.GetCString(); - } - for (const auto &match : matches) { - SCOPED_TRACE(match.original.GetPath() + " -> " + match.remapped.GetPath()); - std::string orig_normalized = match.original.GetPath(); - EXPECT_TRUE( - map.RemapPath(ConstString(match.original.GetPath()), actual_remapped)); - EXPECT_EQ(FileSpec(actual_remapped.GetStringRef()), match.remapped); - FileSpec unmapped_spec; - EXPECT_TRUE(map.ReverseRemapPath(match.remapped, unmapped_spec)); - std::string unmapped_path = unmapped_spec.GetPath(); - EXPECT_EQ(unmapped_path, orig_normalized); - } -} - -TEST(PathMappingListTest, RelativeTests) { - Matches matches[] = { - {".", "/tmp"}, - {"./", "/tmp"}, - {"./////", "/tmp"}, - {"./foo.c", "/tmp/foo.c"}, - {"foo.c", "/tmp/foo.c"}, - {"./bar/foo.c", "/tmp/bar/foo.c"}, - {"bar/foo.c", "/tmp/bar/foo.c"}, - }; - ConstString fails[] = { -#ifdef _WIN32 - ConstString("C:\\"), - ConstString("C:\\a"), -#else - ConstString("/a"), - ConstString("/"), -#endif - }; - PathMappingList map; - map.Append(ConstString("."), ConstString("/tmp"), false); - TestPathMappings(map, matches, fails); - PathMappingList map2; - map2.Append(ConstString(""), ConstString("/tmp"), false); - TestPathMappings(map, matches, fails); -} - -TEST(PathMappingListTest, AbsoluteTests) { - PathMappingList map; - map.Append(ConstString("/old"), ConstString("/new"), false); - Matches matches[] = { - {"/old", "/new"}, - {"/old/", "/new"}, - {"/old/foo/.", "/new/foo"}, - {"/old/foo.c", "/new/foo.c"}, - {"/old/foo.c/.", "/new/foo.c"}, - {"/old/./foo.c", "/new/foo.c"}, - }; - ConstString fails[] = { - ConstString("/foo"), - ConstString("/"), - ConstString("foo.c"), - ConstString("./foo.c"), - ConstString("../foo.c"), - ConstString("../bar/foo.c"), - }; - TestPathMappings(map, matches, fails); -} - -TEST(PathMappingListTest, RemapRoot) { - PathMappingList map; - map.Append(ConstString("/"), ConstString("/new"), false); - Matches matches[] = { - {"/old", "/new/old"}, - {"/old/", "/new/old"}, - {"/old/foo/.", "/new/old/foo"}, - {"/old/foo.c", "/new/old/foo.c"}, - {"/old/foo.c/.", "/new/old/foo.c"}, - {"/old/./foo.c", "/new/old/foo.c"}, - }; - ConstString fails[] = { - ConstString("foo.c"), - ConstString("./foo.c"), - ConstString("../foo.c"), - ConstString("../bar/foo.c"), - }; - TestPathMappings(map, matches, fails); -} - -#ifndef _WIN32 -TEST(PathMappingListTest, CrossPlatformTests) { - PathMappingList map; - map.Append(ConstString(R"(C:\old)"), ConstString("/new"), false); - Matches matches[] = { - {R"(C:\old)", llvm::sys::path::Style::windows, "/new"}, - {R"(C:\old\)", llvm::sys::path::Style::windows, "/new"}, - {R"(C:\old\foo\.)", llvm::sys::path::Style::windows, "/new/foo"}, - {R"(C:\old\foo.c)", llvm::sys::path::Style::windows, "/new/foo.c"}, - {R"(C:\old\foo.c\.)", llvm::sys::path::Style::windows, "/new/foo.c"}, - {R"(C:\old\.\foo.c)", llvm::sys::path::Style::windows, "/new/foo.c"}, - }; - ConstString fails[] = { - ConstString("/foo"), - ConstString("/"), - ConstString("foo.c"), - ConstString("./foo.c"), - ConstString("../foo.c"), - ConstString("../bar/foo.c"), - }; - TestPathMappings(map, matches, fails); -} -#endif diff --git a/gnu/llvm/lldb/unittests/Target/RemoteAwarePlatformTest.cpp b/gnu/llvm/lldb/unittests/Target/RemoteAwarePlatformTest.cpp deleted file mode 100644 index be9fbc347a2..00000000000 --- a/gnu/llvm/lldb/unittests/Target/RemoteAwarePlatformTest.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//===-- RemoteAwarePlatformTest.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 "lldb/Target/RemoteAwarePlatform.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Target/Platform.h" -#include "lldb/Target/Process.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb; -using namespace testing; - -class RemoteAwarePlatformTester : public RemoteAwarePlatform { -public: - using RemoteAwarePlatform::RemoteAwarePlatform; - - MOCK_METHOD0(GetDescription, const char *()); - MOCK_METHOD0(GetPluginVersion, uint32_t()); - MOCK_METHOD0(GetPluginName, ConstString()); - MOCK_METHOD2(GetSupportedArchitectureAtIndex, bool(uint32_t, ArchSpec &)); - MOCK_METHOD4(Attach, - ProcessSP(ProcessAttachInfo &, Debugger &, Target *, Status &)); - MOCK_METHOD0(CalculateTrapHandlerSymbolNames, void()); - - void SetRemotePlatform(lldb::PlatformSP platform) { - m_remote_platform_sp = platform; - } -}; - -class TargetPlatformTester : public Platform { -public: - using Platform::Platform; - - MOCK_METHOD0(GetDescription, const char *()); - MOCK_METHOD0(GetPluginVersion, uint32_t()); - MOCK_METHOD0(GetPluginName, ConstString()); - MOCK_METHOD2(GetSupportedArchitectureAtIndex, bool(uint32_t, ArchSpec &)); - MOCK_METHOD4(Attach, - ProcessSP(ProcessAttachInfo &, Debugger &, Target *, Status &)); - MOCK_METHOD0(CalculateTrapHandlerSymbolNames, void()); - MOCK_METHOD0(GetUserIDResolver, UserIDResolver &()); - - MOCK_METHOD2(ResolveExecutable, - std::pair(const ModuleSpec &, - const FileSpecList *)); - Status - ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) /*override*/ { - auto pair = ResolveExecutable(module_spec, module_search_paths_ptr); - exe_module_sp = pair.second; - return pair.first; - } -}; - -namespace { -class RemoteAwarePlatformTest : public testing::Test { -public: - static void SetUpTestCase() { FileSystem::Initialize(); } - static void TearDownTestCase() { FileSystem::Terminate(); } -}; -} // namespace - -TEST_F(RemoteAwarePlatformTest, TestResolveExecutabelOnClientByPlatform) { - ModuleSpec executable_spec; - ModuleSP expected_executable(new Module(executable_spec)); - - auto platform_sp = std::make_shared(false); - EXPECT_CALL(*platform_sp, ResolveExecutable(_, _)) - .WillRepeatedly(Return(std::make_pair(Status(), expected_executable))); - - RemoteAwarePlatformTester platform(false); - EXPECT_CALL(platform, GetSupportedArchitectureAtIndex(_, _)) - .WillRepeatedly(Return(false)); - - platform.SetRemotePlatform(platform_sp); - - ModuleSP resolved_sp; - lldb_private::Status status = - platform.ResolveExecutable(executable_spec, resolved_sp, nullptr); - - ASSERT_TRUE(status.Success()); - EXPECT_EQ(expected_executable.get(), resolved_sp.get()); -} diff --git a/gnu/llvm/lldb/unittests/Target/StackFrameRecognizerTest.cpp b/gnu/llvm/lldb/unittests/Target/StackFrameRecognizerTest.cpp deleted file mode 100644 index bf458b3b141..00000000000 --- a/gnu/llvm/lldb/unittests/Target/StackFrameRecognizerTest.cpp +++ /dev/null @@ -1,81 +0,0 @@ -//===-- StackFrameRecognizerTest.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 "lldb/Target/StackFrameRecognizer.h" -#include "Plugins/Platform/Linux/PlatformLinux.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Utility/Reproducer.h" -#include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" -#include "lldb/lldb-private-enumerations.h" -#include "lldb/lldb-private.h" -#include "llvm/Support/FormatVariadic.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace lldb; - -namespace { -class StackFrameRecognizerTest : public ::testing::Test { -public: - void SetUp() override { - llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); - FileSystem::Initialize(); - HostInfo::Initialize(); - - // Pretend Linux is the host platform. - platform_linux::PlatformLinux::Initialize(); - ArchSpec arch("powerpc64-pc-linux"); - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - } - - void TearDown() override { - platform_linux::PlatformLinux::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - Reproducer::Terminate(); - } -}; - -class DummyStackFrameRecognizer : public StackFrameRecognizer { -public: - std::string GetName() override { return "Dummy StackFrame Recognizer"; } -}; - -void RegisterDummyStackFrameRecognizer(StackFrameRecognizerManager &manager) { - RegularExpressionSP module_regex_sp = nullptr; - RegularExpressionSP symbol_regex_sp(new RegularExpression("boom")); - - StackFrameRecognizerSP dummy_recognizer_sp(new DummyStackFrameRecognizer()); - - manager.AddRecognizer(dummy_recognizer_sp, module_regex_sp, symbol_regex_sp, - false); -} - -} // namespace - -TEST_F(StackFrameRecognizerTest, NullModuleRegex) { - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - StackFrameRecognizerManager manager; - - RegisterDummyStackFrameRecognizer(manager); - - bool any_printed = false; - manager.ForEach([&any_printed](uint32_t recognizer_id, std::string name, - std::string function, - llvm::ArrayRef symbols, - bool regexp) { any_printed = true; }); - - EXPECT_TRUE(any_printed); -} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt b/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt deleted file mode 100644 index c62bc3b023b..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON) -add_lldb_library(lldbUtilityHelpers - MockTildeExpressionResolver.cpp - TestUtilities.cpp - - LINK_LIBS - lldbUtility - gtest - - LINK_COMPONENTS - Support - ObjectYAML - ) - -add_subdirectory(Symbol) diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h b/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h deleted file mode 100644 index 4efb18397d9..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h +++ /dev/null @@ -1,156 +0,0 @@ -//===-- NativeProcessTestUtils.cpp ------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H -#define LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H - -#include "lldb/Host/common/NativeProcessProtocol.h" -#include "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" - -using namespace lldb_private; -using namespace lldb; -using namespace testing; - -namespace lldb_private { - -class MockDelegate : public NativeProcessProtocol::NativeDelegate { -public: - MOCK_METHOD1(InitializeDelegate, void(NativeProcessProtocol *Process)); - MOCK_METHOD2(ProcessStateChanged, - void(NativeProcessProtocol *Process, StateType State)); - MOCK_METHOD1(DidExec, void(NativeProcessProtocol *Process)); - MOCK_METHOD2(NewSubprocessImpl, - void(NativeProcessProtocol *parent_process, - std::unique_ptr &child_process)); - // This is a hack to avoid MOCK_METHOD2 incompatibility with std::unique_ptr - // passed as value. - void NewSubprocess(NativeProcessProtocol *parent_process, - std::unique_ptr child_process) { - NewSubprocessImpl(parent_process, child_process); - } -}; - -// NB: This class doesn't use the override keyword to avoid -// -Winconsistent-missing-override warnings from the compiler. The -// inconsistency comes from the overriding definitions in the MOCK_*** macros. -template class MockProcess : public T { -public: - MockProcess(NativeProcessProtocol::NativeDelegate &Delegate, - const ArchSpec &Arch, lldb::pid_t Pid = 1) - : T(Pid, -1, Delegate), Arch(Arch) {} - - MOCK_METHOD1(Resume, Status(const ResumeActionList &ResumeActions)); - MOCK_METHOD0(Halt, Status()); - MOCK_METHOD0(Detach, Status()); - MOCK_METHOD1(Signal, Status(int Signo)); - MOCK_METHOD0(Kill, Status()); - MOCK_METHOD0(GetSharedLibraryInfoAddress, addr_t()); - MOCK_METHOD0(UpdateThreads, size_t()); - MOCK_CONST_METHOD0(GetAuxvData, - llvm::ErrorOr>()); - MOCK_METHOD2(GetLoadedModuleFileSpec, - Status(const char *ModulePath, FileSpec &Spec)); - MOCK_METHOD2(GetFileLoadAddress, - Status(const llvm::StringRef &FileName, addr_t &Addr)); - - const ArchSpec &GetArchitecture() const /*override*/ { return Arch; } - Status SetBreakpoint(lldb::addr_t Addr, uint32_t Size, - bool Hardware) /*override*/ { - if (Hardware) - return this->SetHardwareBreakpoint(Addr, Size); - else - return this->SetSoftwareBreakpoint(Addr, Size); - } - - // Redirect base class Read/Write Memory methods to functions whose signatures - // are more mock-friendly. - Status ReadMemory(addr_t Addr, void *Buf, size_t Size, - size_t &BytesRead) /*override*/ { - auto ExpectedMemory = this->ReadMemory(Addr, Size); - if (!ExpectedMemory) { - BytesRead = 0; - return Status(ExpectedMemory.takeError()); - } - BytesRead = ExpectedMemory->size(); - assert(BytesRead <= Size); - std::memcpy(Buf, ExpectedMemory->data(), BytesRead); - return Status(); - } - - Status WriteMemory(addr_t Addr, const void *Buf, size_t Size, - size_t &BytesWritten) /*override*/ { - auto ExpectedBytes = this->WriteMemory( - Addr, llvm::makeArrayRef(static_cast(Buf), Size)); - if (!ExpectedBytes) { - BytesWritten = 0; - return Status(ExpectedBytes.takeError()); - } - BytesWritten = *ExpectedBytes; - return Status(); - } - - MOCK_METHOD2(ReadMemory, - llvm::Expected>(addr_t Addr, size_t Size)); - MOCK_METHOD2(WriteMemory, - llvm::Expected(addr_t Addr, - llvm::ArrayRef Data)); - - using T::GetSoftwareBreakpointTrapOpcode; - llvm::Expected> ReadMemoryWithoutTrap(addr_t Addr, - size_t Size) { - std::vector Data(Size, 0); - size_t BytesRead; - Status ST = - T::ReadMemoryWithoutTrap(Addr, Data.data(), Data.size(), BytesRead); - if (ST.Fail()) - return ST.ToError(); - Data.resize(BytesRead); - return std::move(Data); - } - -private: - ArchSpec Arch; -}; - -class FakeMemory { -public: - FakeMemory(llvm::ArrayRef Data, addr_t start_addr = 0) - : Data(Data), m_start_addr(start_addr) {} - - FakeMemory(const void *Data, size_t data_size, addr_t start_addr = 0) - : Data((const uint8_t *)Data, ((const uint8_t *)Data) + data_size), - m_start_addr(start_addr) {} - - llvm::Expected> Read(addr_t Addr, size_t Size) { - Addr -= m_start_addr; - if (Addr >= Data.size()) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Address out of range."); - Size = std::min(Size, Data.size() - (size_t)Addr); - auto Begin = std::next(Data.begin(), Addr); - return std::vector(Begin, std::next(Begin, Size)); - } - - llvm::Expected Write(addr_t Addr, llvm::ArrayRef Chunk) { - Addr -= m_start_addr; - if (Addr >= Data.size()) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Address out of range."); - size_t Size = std::min(Chunk.size(), Data.size() - (size_t)Addr); - std::copy_n(Chunk.begin(), Size, &Data[Addr]); - return Size; - } - -private: - std::vector Data; - addr_t m_start_addr; -}; -} // namespace lldb_private - -#endif diff --git a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp b/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp deleted file mode 100644 index 2e103b9e61f..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//===-- MockTildeExpressionResolver.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 "MockTildeExpressionResolver.h" -#include "llvm/Support/Path.h" - -using namespace lldb_private; -using namespace llvm; - -MockTildeExpressionResolver::MockTildeExpressionResolver(StringRef CurrentUser, - StringRef HomeDir) - : CurrentUser(CurrentUser) { - UserDirectories.insert(std::make_pair(CurrentUser, HomeDir)); -} - -void MockTildeExpressionResolver::AddKnownUser(StringRef User, - StringRef HomeDir) { - assert(UserDirectories.find(User) == UserDirectories.end()); - UserDirectories.insert(std::make_pair(User, HomeDir)); -} - -void MockTildeExpressionResolver::Clear() { - CurrentUser = StringRef(); - UserDirectories.clear(); -} - -void MockTildeExpressionResolver::SetCurrentUser(StringRef User) { - assert(UserDirectories.find(User) != UserDirectories.end()); - CurrentUser = User; -} - -bool MockTildeExpressionResolver::ResolveExact(StringRef Expr, - SmallVectorImpl &Output) { - Output.clear(); - - assert(!llvm::any_of( - Expr, [](char c) { return llvm::sys::path::is_separator(c); })); - assert(Expr.empty() || Expr[0] == '~'); - Expr = Expr.drop_front(); - if (Expr.empty()) { - auto Dir = UserDirectories[CurrentUser]; - Output.append(Dir.begin(), Dir.end()); - return true; - } - - for (const auto &User : UserDirectories) { - if (User.getKey() != Expr) - continue; - Output.append(User.getValue().begin(), User.getValue().end()); - return true; - } - return false; -} - -bool MockTildeExpressionResolver::ResolvePartial(StringRef Expr, - StringSet<> &Output) { - Output.clear(); - - assert(!llvm::any_of( - Expr, [](char c) { return llvm::sys::path::is_separator(c); })); - assert(Expr.empty() || Expr[0] == '~'); - Expr = Expr.drop_front(); - - SmallString<16> QualifiedName("~"); - for (const auto &User : UserDirectories) { - if (!User.getKey().startswith(Expr)) - continue; - QualifiedName.resize(1); - QualifiedName.append(User.getKey().begin(), User.getKey().end()); - Output.insert(QualifiedName); - } - - return !Output.empty(); -} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h b/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h deleted file mode 100644 index c96e2d248bf..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h +++ /dev/null @@ -1,36 +0,0 @@ -//===-- MockTildeExpressionResolver.h ---------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_MOCKTILDEEXPRESSIONRESOLVER_H -#define LLDB_UNITTESTS_TESTINGSUPPORT_MOCKTILDEEXPRESSIONRESOLVER_H - -#include "lldb/Utility/TildeExpressionResolver.h" - -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringMap.h" - -namespace lldb_private { -class MockTildeExpressionResolver : public TildeExpressionResolver { - llvm::StringRef CurrentUser; - llvm::StringMap UserDirectories; - -public: - MockTildeExpressionResolver(llvm::StringRef CurrentUser, - llvm::StringRef HomeDir); - - void AddKnownUser(llvm::StringRef User, llvm::StringRef HomeDir); - void Clear(); - void SetCurrentUser(llvm::StringRef User); - - bool ResolveExact(llvm::StringRef Expr, - llvm::SmallVectorImpl &Output) override; - bool ResolvePartial(llvm::StringRef Expr, llvm::StringSet<> &Output) override; -}; -} // namespace lldb_private - -#endif diff --git a/gnu/llvm/lldb/unittests/TestingSupport/SubsystemRAII.h b/gnu/llvm/lldb/unittests/TestingSupport/SubsystemRAII.h deleted file mode 100644 index 3df104b8af2..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/SubsystemRAII.h +++ /dev/null @@ -1,90 +0,0 @@ -//===- SubsystemRAII.h ------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H -#define LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H - -#include "llvm/Support/Error.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" -#include - -namespace lldb_private { - -namespace detail { -/// Initializes and deinitializes a single subsystem. -/// @see SubsystemRAII -template struct SubsystemRAIICase { - - /// Calls ::Initialize if it has a void return type. - template - typename std::enable_if< - std::is_same::value>::type - CallInitialize() { - T::Initialize(); - } - - /// Calls ::Initialize if it has a llvm::Error return type and checks - /// the Error instance for success. - template - typename std::enable_if< - std::is_same::value>::type - CallInitialize() { - ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded()); - } - - SubsystemRAIICase() { CallInitialize(); } - ~SubsystemRAIICase() { T::Terminate(); } -}; -} // namespace detail - -template class SubsystemRAII {}; - -/// RAII for initializing and deinitializing LLDB subsystems. -/// -/// This RAII takes care of calling the Initialize and Terminate functions for -/// the subsystems specified by its template arguments. The ::Initialize -/// functions are called on construction for each subsystem template parameter -/// in the order in which they are passed as template parameters. -/// The ::Terminate functions are called in the reverse order at destruction -/// time. -/// -/// If the ::Initialize function returns an llvm::Error this function handles -/// the Error instance (by checking that there is no error). -/// -/// Constructing this RAII in a scope like this: -/// -/// @code{.cpp} -/// { -/// SubsystemRAII Subsystems; -/// DoingTestWork(); -/// } -/// @endcode -/// -/// is equivalent to the following code: -/// -/// @code{.cpp} -/// { -/// FileSystem::Initialize(); -/// HostInfo::Initialize(); -/// ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded()); -/// -/// DoingTestWork(); -/// -/// Socket::Terminate(); -/// FileSystem::Terminate(); -/// HostInfo::Terminate(); -/// } -/// @endcode -template class SubsystemRAII { - detail::SubsystemRAIICase CurrentSubsystem; - SubsystemRAII RemainingSubsystems; -}; -} // namespace lldb_private - -#endif // LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/CMakeLists.txt b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/CMakeLists.txt deleted file mode 100644 index c4eef2e453d..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON) -add_lldb_library(lldbSymbolHelpers - YAMLModuleTester.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbPluginExpressionParserClang - lldbPluginObjectFileELF - lldbPluginSymbolFileDWARF - lldbPluginTypeSystemClang - lldbUtilityHelpers - LLVMTestingSupport - - LINK_COMPONENTS - ObjectYAML - ) diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h deleted file mode 100644 index 6524f093ab9..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h +++ /dev/null @@ -1,75 +0,0 @@ -//===- ClangTestUtils.h -----------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_CLANGTESTUTILS_H -#define LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_CLANGTESTUTILS_H - -#include "Plugins/ExpressionParser/Clang/ClangUtil.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "lldb/Host/HostInfo.h" - -namespace lldb_private { -namespace clang_utils { -inline clang::DeclarationName getDeclarationName(TypeSystemClang &ast, - llvm::StringRef name) { - clang::IdentifierInfo &II = ast.getASTContext().Idents.get(name); - return ast.getASTContext().DeclarationNames.getIdentifier(&II); -} - -inline std::unique_ptr createAST() { - return std::make_unique("test ASTContext", - HostInfo::GetTargetTriple()); -} - -inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) { - return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(), - OptionalClangModuleID(), - lldb::AccessType::eAccessPublic, name, 0, - lldb::LanguageType::eLanguageTypeC); -} - -/// Create a record with the given name and a field with the given type -/// and name. -inline CompilerType createRecordWithField(TypeSystemClang &ast, - llvm::StringRef record_name, - CompilerType field_type, - llvm::StringRef field_name) { - CompilerType t = createRecord(ast, record_name); - - TypeSystemClang::StartTagDeclarationDefinition(t); - ast.AddFieldToRecordType(t, field_name, field_type, - lldb::AccessType::eAccessPublic, 7); - TypeSystemClang::CompleteTagDeclarationDefinition(t); - - return t; -} - -/// Constructs a TypeSystemClang that contains a single RecordDecl that contains -/// a single FieldDecl. Utility class as this setup is a common starting point -/// for unit test that exercise the ASTImporter. -struct SourceASTWithRecord { - std::unique_ptr ast; - CompilerType record_type; - clang::RecordDecl *record_decl = nullptr; - clang::FieldDecl *field_decl = nullptr; - SourceASTWithRecord() { - ast = createAST(); - record_type = createRecordWithField( - *ast, "Source", ast->GetBasicType(lldb::BasicType::eBasicTypeChar), - "a_field"); - record_decl = - llvm::cast(ClangUtil::GetAsTagDecl(record_type)); - field_decl = *record_decl->fields().begin(); - assert(field_decl); - } -}; - -} // namespace clang_utils -} // namespace lldb_private - -#endif diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp deleted file mode 100644 index 15db62451f9..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//===-- YAMLModuleTester.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 "TestingSupport/Symbol/YAMLModuleTester.h" -#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "lldb/Core/Section.h" -#include "llvm/ObjectYAML/DWARFEmitter.h" - -using namespace lldb_private; - -YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data) { - llvm::Expected File = TestFile::fromYaml(yaml_data); - EXPECT_THAT_EXPECTED(File, llvm::Succeeded()); - m_file = std::move(*File); - - m_module_sp = std::make_shared(m_file->moduleSpec()); - auto &symfile = *llvm::cast(m_module_sp->GetSymbolFile()); - - m_dwarf_unit = symfile.DebugInfo().GetUnitAtIndex(0); -} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h deleted file mode 100644 index 60715ab2c16..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h +++ /dev/null @@ -1,43 +0,0 @@ -//===- YAMLModuleTester.h ---------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_YAMLMODULETESTER_H -#define LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_YAMLMODULETESTER_H - -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/SymbolFile/DWARF/DWARFUnit.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "TestingSupport/SubsystemRAII.h" -#include "TestingSupport/TestUtilities.h" -#include "lldb/Core/Module.h" -#include "lldb/Host/HostInfo.h" - -namespace lldb_private { - -/// Helper class that can construct a module from YAML and evaluate -/// DWARF expressions on it. -class YAMLModuleTester { -protected: - SubsystemRAII - subsystems; - llvm::Optional m_file; - lldb::ModuleSP m_module_sp; - DWARFUnit *m_dwarf_unit; - -public: - /// Parse the debug info sections from the YAML description. - YAMLModuleTester(llvm::StringRef yaml_data); - DWARFUnit *GetDwarfUnit() const { return m_dwarf_unit; } - lldb::ModuleSP GetModule() const { return m_module_sp; } -}; - -} // namespace lldb_private - -#endif // LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_YAMLMODULETESTER_H diff --git a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp b/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp deleted file mode 100644 index 86f3d1a7dfa..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp +++ /dev/null @@ -1,46 +0,0 @@ -//===-- TestUtilities.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 "TestUtilities.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ObjectYAML/yaml2obj.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/YAMLTraits.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -extern const char *TestMainArgv0; - -std::string lldb_private::GetInputFilePath(const llvm::Twine &name) { - llvm::SmallString<128> result = llvm::sys::path::parent_path(TestMainArgv0); - llvm::sys::fs::make_absolute(result); - llvm::sys::path::append(result, "Inputs", name); - return std::string(result.str()); -} - -llvm::Expected TestFile::fromYaml(llvm::StringRef Yaml) { - std::string Buffer; - llvm::raw_string_ostream OS(Buffer); - llvm::yaml::Input YIn(Yaml); - if (!llvm::yaml::convertYAML(YIn, OS, [](const llvm::Twine &Msg) {})) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "convertYAML() failed"); - return TestFile(std::move(Buffer)); -} - -llvm::Expected TestFile::fromYamlFile(const llvm::Twine &Name) { - auto BufferOrError = - llvm::MemoryBuffer::getFile(GetInputFilePath(Name), /*IsText=*/false, - /*RequiresNullTerminator=*/false); - if (!BufferOrError) - return llvm::errorCodeToError(BufferOrError.getError()); - return fromYaml(BufferOrError.get()->getBuffer()); -} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h b/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h deleted file mode 100644 index 811c4c15212..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- TestUtilities.h ------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_TESTUTILITIES_H -#define LLDB_UNITTESTS_TESTINGSUPPORT_TESTUTILITIES_H - -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Utility/DataBuffer.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/FileUtilities.h" -#include - -#define ASSERT_NO_ERROR(x) \ - if (std::error_code ASSERT_NO_ERROR_ec = x) { \ - llvm::SmallString<128> MessageStorage; \ - llvm::raw_svector_ostream Message(MessageStorage); \ - Message << #x ": did not return errc::success.\n" \ - << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \ - << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \ - GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \ - } else { \ - } - -namespace lldb_private { -std::string GetInputFilePath(const llvm::Twine &name); - -class TestFile { -public: - static llvm::Expected fromYaml(llvm::StringRef Yaml); - static llvm::Expected fromYamlFile(const llvm::Twine &Name); - - ModuleSpec moduleSpec() { - return ModuleSpec(FileSpec(), UUID(), dataBuffer()); - } - -private: - TestFile(std::string &&Buffer) : Buffer(std::move(Buffer)) {} - - lldb::DataBufferSP dataBuffer() { - auto *Data = reinterpret_cast(Buffer.data()); - return std::make_shared(const_cast(Data), - Buffer.size()); - } - - std::string Buffer; -}; -} - -#endif diff --git a/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap b/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap deleted file mode 100644 index 81d2b988875..00000000000 --- a/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap +++ /dev/null @@ -1,17 +0,0 @@ - -module lldb_TestingSupport { - requires cplusplus - module TestUtilities { header "TestUtilities.h" export * } - module MockTildeExpressionResolver { header "MockTildeExpressionResolver.h" export * } -} - -module lldb_TestingSupport_Host { - requires cplusplus - module NativeProcessTestUtils { header "Host/NativeProcessTestUtils.h" export * } -} - -module lldb_TestingSupport_Symbol { - requires cplusplus - module ClangTestUtils { header "Symbol/ClangTestUtils.h" export * } - module YAMLModuleTester { header "Symbol/YAMLModuleTester.h" export * } -} diff --git a/gnu/llvm/lldb/unittests/Thread/CMakeLists.txt b/gnu/llvm/lldb/unittests/Thread/CMakeLists.txt deleted file mode 100644 index d6e365adac5..00000000000 --- a/gnu/llvm/lldb/unittests/Thread/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_lldb_unittest(ThreadTests - ThreadTest.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbTarget - lldbSymbol - lldbUtility - lldbUtilityHelpers - lldbInterpreter - lldbBreakpoint - lldbPluginPlatformLinux - ) - diff --git a/gnu/llvm/lldb/unittests/Thread/ThreadTest.cpp b/gnu/llvm/lldb/unittests/Thread/ThreadTest.cpp deleted file mode 100644 index a8387a5f03f..00000000000 --- a/gnu/llvm/lldb/unittests/Thread/ThreadTest.cpp +++ /dev/null @@ -1,163 +0,0 @@ -//===-- ThreadTest.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 "lldb/Target/Thread.h" -#include "Plugins/Platform/Linux/PlatformLinux.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Reproducer.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb_private::repro; -using namespace lldb; - -namespace { -class ThreadTest : public ::testing::Test { -public: - void SetUp() override { - llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); - FileSystem::Initialize(); - HostInfo::Initialize(); - platform_linux::PlatformLinux::Initialize(); - } - void TearDown() override { - platform_linux::PlatformLinux::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - Reproducer::Terminate(); - } -}; - -class DummyProcess : public Process { -public: - using Process::Process; - - bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override { - return true; - } - Status DoDestroy() override { return {}; } - void RefreshStateAfterStop() override {} - size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - Status &error) override { - return 0; - } - bool DoUpdateThreadList(ThreadList &old_thread_list, - ThreadList &new_thread_list) override { - return false; - } - ConstString GetPluginName() override { return ConstString("Dummy"); } - uint32_t GetPluginVersion() override { return 0; } - - ProcessModID &GetModIDNonConstRef() { return m_mod_id; } -}; - -class DummyThread : public Thread { -public: - using Thread::Thread; - - ~DummyThread() override { DestroyThread(); } - - void RefreshStateAfterStop() override {} - - lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } - - lldb::RegisterContextSP - CreateRegisterContextForFrame(StackFrame *frame) override { - return nullptr; - } - - bool CalculateStopInfo() override { return false; } - - bool IsStillAtLastBreakpointHit() override { return true; } -}; -} // namespace - -TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) { - PlatformSP platform_sp; - TargetSP target_sp; - debugger_sp->GetTargetList().CreateTarget( - *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); - - return target_sp; -} - -TEST_F(ThreadTest, SetStopInfo) { - ArchSpec arch("powerpc64-pc-linux"); - - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - TargetSP target_sp = CreateTarget(debugger_sp, arch); - ASSERT_TRUE(target_sp); - - ListenerSP listener_sp(Listener::MakeListener("dummy")); - ProcessSP process_sp = std::make_shared(target_sp, listener_sp); - ASSERT_TRUE(process_sp); - - DummyProcess *process = static_cast(process_sp.get()); - - ThreadSP thread_sp = std::make_shared(*process_sp.get(), 0); - ASSERT_TRUE(thread_sp); - - StopInfoSP stopinfo_sp = - StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp.get(), 0); - ASSERT_TRUE(stopinfo_sp->IsValid() == true); - - /* - Should make stopinfo valid. - */ - process->GetModIDNonConstRef().BumpStopID(); - ASSERT_TRUE(stopinfo_sp->IsValid() == false); - - thread_sp->SetStopInfo(stopinfo_sp); - ASSERT_TRUE(stopinfo_sp->IsValid() == true); -} - -TEST_F(ThreadTest, GetPrivateStopInfo) { - ArchSpec arch("powerpc64-pc-linux"); - - Platform::SetHostPlatform( - platform_linux::PlatformLinux::CreateInstance(true, &arch)); - - DebuggerSP debugger_sp = Debugger::CreateInstance(); - ASSERT_TRUE(debugger_sp); - - TargetSP target_sp = CreateTarget(debugger_sp, arch); - ASSERT_TRUE(target_sp); - - ListenerSP listener_sp(Listener::MakeListener("dummy")); - ProcessSP process_sp = std::make_shared(target_sp, listener_sp); - ASSERT_TRUE(process_sp); - - DummyProcess *process = static_cast(process_sp.get()); - - ThreadSP thread_sp = std::make_shared(*process_sp.get(), 0); - ASSERT_TRUE(thread_sp); - - StopInfoSP stopinfo_sp = - StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp.get(), 0); - ASSERT_TRUE(stopinfo_sp); - - thread_sp->SetStopInfo(stopinfo_sp); - - /* - Should make stopinfo valid if thread is at last breakpoint hit. - */ - process->GetModIDNonConstRef().BumpStopID(); - ASSERT_TRUE(stopinfo_sp->IsValid() == false); - StopInfoSP new_stopinfo_sp = thread_sp->GetPrivateStopInfo(); - ASSERT_TRUE(new_stopinfo_sp && stopinfo_sp->IsValid() == true); -} diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt b/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt deleted file mode 100644 index f3bbd71df32..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_lldb_unittest(Arm64InstEmulationTests - TestArm64InstEmulation.cpp - LINK_LIBS - lldbCore - lldbSymbol - lldbTarget - lldbPluginUnwindAssemblyInstEmulation - lldbPluginDisassemblerLLVMC - lldbPluginInstructionARM64 - lldbPluginProcessUtility - LINK_COMPONENTS - Support - ${LLVM_TARGETS_TO_BUILD}) diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp b/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp deleted file mode 100644 index b3ad351c716..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp +++ /dev/null @@ -1,857 +0,0 @@ -//===-- TestArm64InstEmulation.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 "gtest/gtest.h" - -#include - -#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/UnwindAssembly.h" -#include "lldb/Utility/ArchSpec.h" - -#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" -#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" -#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" -#include "llvm/Support/TargetSelect.h" - -using namespace lldb; -using namespace lldb_private; - -class TestArm64InstEmulation : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - - // virtual void SetUp() override { } - // virtual void TearDown() override { } - -protected: -}; - -void TestArm64InstEmulation::SetUpTestCase() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllDisassemblers(); - DisassemblerLLVMC::Initialize(); - EmulateInstructionARM64::Initialize(); -} - -void TestArm64InstEmulation::TearDownTestCase() { - DisassemblerLLVMC::Terminate(); - EmulateInstructionARM64::Terminate(); -} - -TEST_F(TestArm64InstEmulation, TestSimpleDarwinFunction) { - ArchSpec arch("arm64-apple-ios10"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // 'int main() { }' compiled for arm64-apple-ios with clang - uint8_t data[] = { - 0xfd, 0x7b, 0xbf, 0xa9, // 0xa9bf7bfd : stp x29, x30, [sp, #-0x10]! - 0xfd, 0x03, 0x00, 0x91, // 0x910003fd : mov x29, sp - 0xff, 0x43, 0x00, 0xd1, // 0xd10043ff : sub sp, sp, #0x10 - - 0xbf, 0x03, 0x00, 0x91, // 0x910003bf : mov sp, x29 - 0xfd, 0x7b, 0xc1, 0xa8, // 0xa8c17bfd : ldp x29, x30, [sp], #16 - 0xc0, 0x03, 0x5f, 0xd6, // 0xd65f03c0 : ret - }; - - // UnwindPlan we expect: - - // row[0]: 0: CFA=sp +0 => - // row[1]: 4: CFA=sp+16 => fp=[CFA-16] lr=[CFA-8] - // row[2]: 8: CFA=fp+16 => fp=[CFA-16] lr=[CFA-8] - // row[2]: 16: CFA=sp+16 => fp=[CFA-16] lr=[CFA-8] - // row[3]: 20: CFA=sp +0 => fp= lr= - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // CFA=sp +0 - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - // CFA=sp+16 => fp=[CFA-16] lr=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // CFA=fp+16 => fp=[CFA-16] lr=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(8ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // CFA=sp+16 => fp=[CFA-16] lr=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // CFA=sp +0 => fp= lr= - row_sp = unwind_plan.GetRowForFunctionOffset(20); - EXPECT_EQ(20ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(TestArm64InstEmulation, TestMediumDarwinFunction) { - ArchSpec arch("arm64-apple-ios10"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // disassembly of -[NSPlaceholderString initWithBytes:length:encoding:] - // from Foundation for iOS. - uint8_t data[] = { - 0xf6, 0x57, 0xbd, 0xa9, // 0: 0xa9bd57f6 stp x22, x21, [sp, #-48]! - 0xf4, 0x4f, 0x01, 0xa9, // 4: 0xa9014ff4 stp x20, x19, [sp, #16] - 0xfd, 0x7b, 0x02, 0xa9, // 8: 0xa9027bfd stp x29, x30, [sp, #32] - 0xfd, 0x83, 0x00, 0x91, // 12: 0x910083fd add x29, sp, #32 - 0xff, 0x43, 0x00, 0xd1, // 16: 0xd10043ff sub sp, sp, #16 - - // [... function body ...] - 0x1f, 0x20, 0x03, 0xd5, // 20: 0xd503201f nop - - 0xbf, 0x83, 0x00, 0xd1, // 24: 0xd10083bf sub sp, x29, #32 - 0xfd, 0x7b, 0x42, 0xa9, // 28: 0xa9427bfd ldp x29, x30, [sp, #32] - 0xf4, 0x4f, 0x41, 0xa9, // 32: 0xa9414ff4 ldp x20, x19, [sp, #16] - 0xf6, 0x57, 0xc3, 0xa8, // 36: 0xa8c357f6 ldp x22, x21, [sp], #48 - 0x01, 0x16, 0x09, 0x14, // 40: 0x14091601 b 0x18f640524 ; symbol stub - // for: CFStringCreateWithBytes - }; - - // UnwindPlan we expect: - // 0: CFA=sp +0 => - // 4: CFA=sp+48 => x21=[CFA-40] x22=[CFA-48] - // 8: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // 12: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // fp=[CFA-16] lr=[CFA-8] - // 16: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // fp=[CFA-16] lr=[CFA-8] - - // [... function body ...] - - // 28: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // fp=[CFA-16] lr=[CFA-8] - // 32: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] fp= - // lr= - // 36: CFA=sp+48 => x19= x20= x21=[CFA-40] x22=[CFA-48] fp= - // lr= - // 40: CFA=sp +0 => x19= x20= x21= x22= fp= - // lr= - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // 0: CFA=sp +0 => - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - // 4: CFA=sp+48 => x21=[CFA-40] x22=[CFA-48] - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x21_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-40, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x22_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-48, regloc.GetOffset()); - - // 8: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(8ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x19_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-24, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-32, regloc.GetOffset()); - - // 12: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // fp=[CFA-16] lr=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 16: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // fp=[CFA-16] lr=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - // 28: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // fp=[CFA-16] lr=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(28); - EXPECT_EQ(28ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset()); - - // 32: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] fp= - // lr= - row_sp = unwind_plan.GetRowForFunctionOffset(32); - EXPECT_EQ(32ull, row_sp->GetOffset()); - - // I'd prefer if these restored registers were cleared entirely instead of set - // to IsSame... - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc)); - EXPECT_TRUE(regloc.IsSame()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc)); - EXPECT_TRUE(regloc.IsSame()); - - // 36: CFA=sp+48 => x19= x20= x21=[CFA-40] x22=[CFA-48] fp= - // lr= - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_EQ(36ull, row_sp->GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x19_arm64, regloc)); - EXPECT_TRUE(regloc.IsSame()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc)); - EXPECT_TRUE(regloc.IsSame()); - - // 40: CFA=sp +0 => x19= x20= x21= x22= fp= - // lr= - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(40ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x21_arm64, regloc)); - EXPECT_TRUE(regloc.IsSame()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x22_arm64, regloc)); - EXPECT_TRUE(regloc.IsSame()); -} - -TEST_F(TestArm64InstEmulation, TestFramelessThreeEpilogueFunction) { - ArchSpec arch("arm64-apple-ios10"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // disassembly of JSC::ARM64LogicalImmediate::findBitRange<16u> - // from JavaScriptcore for iOS. - uint8_t data[] = { - 0x08, 0x3c, 0x0f, 0x53, // 0: 0x530f3c08 ubfx w8, w0, #15, #1 - 0x68, 0x00, 0x00, 0x39, // 4: 0x39000068 strb w8, [x3] - 0x08, 0x3c, 0x40, 0xd2, // 8: 0xd2403c08 eor x8, x0, #0xffff - 0x1f, 0x00, 0x71, 0xf2, // 12: 0xf271001f tst x0, #0x8000 - - // [...] - - 0x3f, 0x01, 0x0c, 0xeb, // 16: 0xeb0c013f cmp x9, x12 - 0x81, 0x00, 0x00, 0x54, // 20: 0x54000081 b.ne +34 - 0x5f, 0x00, 0x00, 0xb9, // 24: 0xb900005f str wzr, [x2] - 0xe0, 0x03, 0x00, 0x32, // 28: 0x320003e0 orr w0, wzr, #0x1 - 0xc0, 0x03, 0x5f, 0xd6, // 32: 0xd65f03c0 ret - 0x89, 0x01, 0x09, 0xca, // 36: 0xca090189 eor x9, x12, x9 - - // [...] - - 0x08, 0x05, 0x00, 0x11, // 40: 0x11000508 add w8, w8, #0x1 - 0x48, 0x00, 0x00, 0xb9, // 44: 0xb9000048 str w8, [x2] - 0xe0, 0x03, 0x00, 0x32, // 48: 0x320003e0 orr w0, wzr, #0x1 - 0xc0, 0x03, 0x5f, 0xd6, // 52: 0xd65f03c0 ret - 0x00, 0x00, 0x80, 0x52, // 56: 0x52800000 mov w0, #0x0 - 0xc0, 0x03, 0x5f, 0xd6, // 60: 0xd65f03c0 ret - - }; - - // UnwindPlan we expect: - // 0: CFA=sp +0 => - // (possibly with additional rows at offsets 36 and 56 saying the same thing) - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // 0: CFA=sp +0 => - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(32); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x19_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x21_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x22_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x23_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x24_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x25_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x26_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x27_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x28_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc)); - - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(52); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(56); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(60); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(TestArm64InstEmulation, TestRegisterSavedTwice) { - ArchSpec arch("arm64-apple-ios10"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // disassembly of mach_msg_sever_once from libsystem_kernel.dylib for iOS. - uint8_t data[] = { - - 0xfc, 0x6f, 0xba, 0xa9, // 0: 0xa9ba6ffc stp x28, x27, [sp, #-0x60]! - 0xfa, 0x67, 0x01, 0xa9, // 4: 0xa90167fa stp x26, x25, [sp, #0x10] - 0xf8, 0x5f, 0x02, 0xa9, // 8: 0xa9025ff8 stp x24, x23, [sp, #0x20] - 0xf6, 0x57, 0x03, 0xa9, // 12: 0xa90357f6 stp x22, x21, [sp, #0x30] - 0xf4, 0x4f, 0x04, 0xa9, // 16: 0xa9044ff4 stp x20, x19, [sp, #0x40] - 0xfd, 0x7b, 0x05, 0xa9, // 20: 0xa9057bfd stp x29, x30, [sp, #0x50] - 0xfd, 0x43, 0x01, 0x91, // 24: 0x910143fd add x29, sp, #0x50 - 0xff, 0xc3, 0x00, 0xd1, // 28: 0xd100c3ff sub sp, sp, #0x30 - - // mid-function, store x20 & x24 on the stack at a different location. - // this should not show up in the unwind plan; caller's values are not - // being saved to stack. - 0xf8, 0x53, 0x01, 0xa9, // 32: 0xa90153f8 stp x24, x20, [sp, #0x10] - - // mid-function, copy x20 and x19 off of the stack -- but not from - // their original locations. unwind plan should ignore this. - 0xf4, 0x4f, 0x41, 0xa9, // 36: 0xa9414ff4 ldp x20, x19, [sp, #0x10] - - // epilogue - 0xbf, 0x43, 0x01, 0xd1, // 40: 0xd10143bf sub sp, x29, #0x50 - 0xfd, 0x7b, 0x45, 0xa9, // 44: 0xa9457bfd ldp x29, x30, [sp, #0x50] - 0xf4, 0x4f, 0x44, 0xa9, // 48: 0xa9444ff4 ldp x20, x19, [sp, #0x40] - 0xf6, 0x57, 0x43, 0xa9, // 52: 0xa94357f6 ldp x22, x21, [sp, #0x30] - 0xf8, 0x5f, 0x42, 0xa9, // 56: 0xa9425ff8 ldp x24, x23, [sp, #0x20] - 0xfa, 0x67, 0x41, 0xa9, // 60: 0xa94167fa ldp x26, x25, [sp, #0x10] - 0xfc, 0x6f, 0xc6, 0xa8, // 64: 0xa8c66ffc ldp x28, x27, [sp], #0x60 - 0xc0, 0x03, 0x5f, 0xd6, // 68: 0xd65f03c0 ret - }; - - // UnwindPlan we expect: - // 0: CFA=sp +0 => - // 4: CFA=sp+96 => x27=[CFA-88] x28=[CFA-96] - // 8: CFA=sp+96 => x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96] - // 12: CFA=sp+96 => x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] - // x27=[CFA-88] x28=[CFA-96] - // 16: CFA=sp+96 => x21=[CFA-40] x22=[CFA-48] x23=[CFA-56] x24=[CFA-64] - // x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96] - // 20: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] - // x28=[CFA-96] - // 24: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] - // x28=[CFA-96] fp=[CFA-16] lr=[CFA-8] - // 28: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] - // x28=[CFA-96] fp=[CFA-16] lr=[CFA-8] - - // 44: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] - // x28=[CFA-96] fp=[CFA-16] lr=[CFA-8] - // 48: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] - // x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] - // x28=[CFA-96] - // 52: CFA=sp+96 => x21=[CFA-40] x22=[CFA-48] x23=[CFA-56] x24=[CFA-64] - // x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96] - // 56: CFA=sp+96 => x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] - // x27=[CFA-88] x28=[CFA-96] - // 60: CFA=sp+96 => x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96] - // 64: CFA=sp+96 => x27=[CFA-88] x28=[CFA-96] - // 68: CFA=sp +0 => - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_EQ(28ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-32, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(28ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-32, regloc.GetOffset()); -} - -TEST_F(TestArm64InstEmulation, TestRegisterDoubleSpills) { - ArchSpec arch("arm64-apple-ios10"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // this file built with clang for iOS arch arm64 optimization -Os - // #include - // double foo(double in) { - // double arr[32]; - // for (int i = 0; i < 32; i++) - // arr[i] = in + i; - // for (int i = 2; i < 30; i++) - // arr[i] = ((((arr[i - 1] * arr[i - 2] * 0.2) + (0.7 * arr[i])) / - // ((((arr[i] * 0.73) + 0.65) * (arr[i - 1] + 0.2)) - ((arr[i + 1] + (arr[i] - // * 0.32) + 0.52) / 0.3) + (0.531 * arr[i - 2]))) + ((arr[i - 1] + 5) / - // ((arr[i + 2] + 0.4) / arr[i])) + (arr[5] * (0.17 + arr[7] * arr[i])) + - // ((i > 5 ? (arr[i - 3]) : arr[i - 1]) * 0.263) + (((arr[i - 2] + arr[i - - // 1]) * 0.3252) + 3.56) - (arr[i + 1] * 0.852311)) * ((arr[i] * 85234.1345) - // + (77342.451324 / (arr[i - 2] + arr[i - 1] - 73425341.33455))) + (arr[i] - // * 875712013.55) - (arr[i - 1] * 0.5555) - ((arr[i] * (arr[i + 1] + - // 17342834.44) / 8688200123.555)) + (arr[i - 2] + 8888.888); - // return arr[16]; - //} - // int main(int argc, char **argv) { printf("%g\n", foo(argc)); } - - // so function foo() uses enough registers that it spills the callee-saved - // floating point registers. - uint8_t data[] = { - // prologue - 0xef, 0x3b, 0xba, 0x6d, // 0: 0x6dba3bef stp d15, d14, [sp, #-0x60]! - 0xed, 0x33, 0x01, 0x6d, // 4: 0x6d0133ed stp d13, d12, [sp, #0x10] - 0xeb, 0x2b, 0x02, 0x6d, // 8: 0x6d022beb stp d11, d10, [sp, #0x20] - 0xe9, 0x23, 0x03, 0x6d, // 12: 0x6d0323e9 stp d9, d8, [sp, #0x30] - 0xfc, 0x6f, 0x04, 0xa9, // 16: 0xa9046ffc stp x28, x27, [sp, #0x40] - 0xfd, 0x7b, 0x05, 0xa9, // 20: 0xa9057bfd stp x29, x30, [sp, #0x50] - 0xfd, 0x43, 0x01, 0x91, // 24: 0x910143fd add x29, sp, #0x50 - 0xff, 0x43, 0x04, 0xd1, // 28: 0xd10443ff sub sp, sp, #0x110 - - // epilogue - 0xbf, 0x43, 0x01, 0xd1, // 32: 0xd10143bf sub sp, x29, #0x50 - 0xfd, 0x7b, 0x45, 0xa9, // 36: 0xa9457bfd ldp x29, x30, [sp, #0x50] - 0xfc, 0x6f, 0x44, 0xa9, // 40: 0xa9446ffc ldp x28, x27, [sp, #0x40] - 0xe9, 0x23, 0x43, 0x6d, // 44: 0x6d4323e9 ldp d9, d8, [sp, #0x30] - 0xeb, 0x2b, 0x42, 0x6d, // 48: 0x6d422beb ldp d11, d10, [sp, #0x20] - 0xed, 0x33, 0x41, 0x6d, // 52: 0x6d4133ed ldp d13, d12, [sp, #0x10] - 0xef, 0x3b, 0xc6, 0x6c, // 56: 0x6cc63bef ldp d15, d14, [sp], #0x60 - 0xc0, 0x03, 0x5f, 0xd6, // 60: 0xd65f03c0 ret - }; - - // UnwindPlan we expect: - // 0: CFA=sp +0 => - // 4: CFA=sp+96 => d14=[CFA-88] d15=[CFA-96] - // 8: CFA=sp+96 => d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 12: CFA=sp+96 => d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80] - // d14=[CFA-88] d15=[CFA-96] - // 16: CFA=sp+96 => d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] - // d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 20: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] d8=[CFA-40] d9=[CFA-48] - // d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] - // d15=[CFA-96] - // 24: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] - // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 28: CFA=fp+16 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] - // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 36: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] - // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 40: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] d8=[CFA-40] d9=[CFA-48] - // d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] - // d15=[CFA-96] - // 44: CFA=sp+96 => d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] - // d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 48: CFA=sp+96 => d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80] - // d14=[CFA-88] d15=[CFA-96] - // 52: CFA=sp+96 => d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - // 56: CFA=sp+96 => d14=[CFA-88] d15=[CFA-96] - // 60: CFA=sp +0 => - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // 28: CFA=fp+16 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] - // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96] - row_sp = unwind_plan.GetRowForFunctionOffset(28); - EXPECT_EQ(28ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d15_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-96, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d14_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-88, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d13_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-80, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d12_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-72, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d11_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-64, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d10_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-56, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d9_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-48, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d8_arm64, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-40, regloc.GetOffset()); - - // 60: CFA=sp +0 => - row_sp = unwind_plan.GetRowForFunctionOffset(60); - EXPECT_EQ(60ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - if (row_sp->GetRegisterInfo(fpu_d8_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d9_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d10_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d11_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d12_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d13_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d14_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(fpu_d15_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(gpr_x27_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } - if (row_sp->GetRegisterInfo(gpr_x28_arm64, regloc)) { - EXPECT_TRUE(regloc.IsSame()); - } -} - -TEST_F(TestArm64InstEmulation, TestRetguardEmptyFunction) { - ArchSpec arch("arm64-unknown-openbsd6.4"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // void main() { } compiled on arm64-unknown-openbsd6.4 with -fret-protector - uint8_t data[] = { - 0x2f, 0x37, 0x00, 0xf0, // 0: adrp x15, #7237632 - 0xef, 0x35, 0x43, 0xf9, // 4: ldr x15, [x15, #1640] - 0xef, 0x01, 0x1e, 0xca, // 8: eor x15, x15, x30 - 0xef, 0x0f, 0x1f, 0xf8, // 12: str x15, [sp, #-16]! - 0xef, 0x07, 0x41, 0xf8, // 16: ldr x15, [sp], #16 - 0x29, 0x37, 0x00, 0xf0, // 20: adrp x9, #7237632 - 0x29, 0x35, 0x43, 0xf9, // 24: ldr x9, [x9, #1640] - 0xef, 0x01, 0x1e, 0xca, // 28: eor x15, x15, x30 - 0xef, 0x01, 0x09, 0xeb, // 32: subs x15, x15, x9 - 0x4f, 0x00, 0x00, 0xb4, // 36: cbz x15, #8 - 0x20, 0x00, 0x20, 0xd4, // 40: brk #0x1 - 0xc0, 0x03, 0x5f, 0xd6, // 44: ret - }; - - // UnwindPlan we expect - // 0: CFA=sp+0 - // 16: CFA=sp+16 - // 20: CFA=sp+0 - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // 0: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(0ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(0ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(0ull, row_sp->GetOffset()); - - // 16: CFA=sp+16 - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - // 20: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(20); - EXPECT_EQ(20ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(24); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(28); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(32); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(20ull, row_sp->GetOffset()); -} - -TEST_F(TestArm64InstEmulation, TestCFARegisterTrackedAcrossJumps) { - ArchSpec arch("arm64-apple-ios10"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - uint8_t data[] = { - // prologue - 0xf4, 0x4f, 0xbe, 0xa9, // 0: 0xa9be4ff4 stp x20, x19, [sp, #-0x20]! - 0xfd, 0x7b, 0x01, 0xa9, // 4: 0xa9017bfd stp x29, x30, [sp, #0x10] - 0xfd, 0x43, 0x00, 0x91, // 8: 0x910043fd add x29, sp, #0x10 - 0xff, 0x43, 0x00, 0xd1, // 12: 0xd10043ff sub sp, sp, #0x10 - // conditional branch over a mid-function epilogue - 0xeb, 0x00, 0x00, 0x54, // 16: 0x540000eb b.lt <+44> - // mid-function epilogue - 0x1f, 0x20, 0x03, 0xd5, // 20: 0xd503201f nop - 0xe0, 0x03, 0x13, 0xaa, // 24: 0xaa1303e0 mov x0, x19 - 0xbf, 0x43, 0x00, 0xd1, // 28: 0xd10043bf sub sp, x29, #0x10 - 0xfd, 0x7b, 0x41, 0xa9, // 32: 0xa9417bfd ldp x29, x30, [sp, #0x10] - 0xf4, 0x4f, 0xc2, 0xa8, // 36: 0xa8c24ff4 ldp x20, x19, [sp], #0x20 - 0xc0, 0x03, 0x5f, 0xd6, // 40: 0xd65f03c0 ret - // unwind state restored, we're using a frame pointer, let's change the - // stack pointer and see no change in how the CFA is computed - 0x1f, 0x20, 0x03, 0xd5, // 44: 0xd503201f nop - 0xff, 0x43, 0x00, 0xd1, // 48: 0xd10043ff sub sp, sp, #0x10 - 0x1f, 0x20, 0x03, 0xd5, // 52: 0xd503201f nop - // final epilogue - 0xe0, 0x03, 0x13, 0xaa, // 56: 0xaa1303e0 mov x0, x19 - 0xbf, 0x43, 0x00, 0xd1, // 60: 0xd10043bf sub sp, x29, #0x10 - 0xfd, 0x7b, 0x41, 0xa9, // 64: 0xa9417bfd ldp x29, x30, [sp, #0x10] - 0xf4, 0x4f, 0xc2, 0xa8, // 68: 0xa8c24ff4 ldp x20, x19, [sp], #0x20 - 0xc0, 0x03, 0x5f, 0xd6, // 72: 0xd65f03c0 ret - - 0x1f, 0x20, 0x03, 0xd5, // 52: 0xd503201f nop - }; - - // UnwindPlan we expect: - // row[0]: 0: CFA=sp +0 => - // row[1]: 4: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] - // row[2]: 8: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[3]: 12: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[4]: 32: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[5]: 36: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp= lr= - // row[6]: 40: CFA=sp +0 => x19= x20= fp= lr= - // row[7]: 44: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[8]: 64: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[9]: 68: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp= lr= - // row[10]: 72: CFA=sp +0 => x19= x20= fp= lr= - - // The specific bug we're looking for is this incorrect CFA definition, - // where the InstEmulation is using the $sp value mixed in with $fp, - // it looks like this: - // - // row[7]: 44: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[8]: 52: CFA=fp+64 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] - // row[9]: 68: CFA=fp+64 => x19=[CFA-24] x20=[CFA-32] fp= lr= - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // Confirm CFA at mid-func epilogue 'ret' is $sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(40ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - // After the 'ret', confirm we're back to the correct CFA of $fp+16 - row_sp = unwind_plan.GetRowForFunctionOffset(44); - EXPECT_EQ(44ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - // Confirm that we have no additional UnwindPlan rows before the - // real epilogue -- we still get the Row at offset 44. - row_sp = unwind_plan.GetRowForFunctionOffset(60); - EXPECT_EQ(44ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - // And in the epilogue, confirm that we start by switching back to - // defining the CFA in terms of $sp. - row_sp = unwind_plan.GetRowForFunctionOffset(64); - EXPECT_EQ(64ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(32, row_sp->GetCFAValue().GetOffset()); -} - diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/CMakeLists.txt b/gnu/llvm/lldb/unittests/UnwindAssembly/CMakeLists.txt deleted file mode 100644 index 136fcd9ae97..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -if ("AArch64" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(ARM64) -endif() - -if ("PowerPC" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(PPC64) -endif() - -if ("X86" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(x86) -endif() diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt b/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt deleted file mode 100644 index 679f7664cb8..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_lldb_unittest(PPC64InstEmulationTests - TestPPC64InstEmulation.cpp - LINK_LIBS - lldbCore - lldbSymbol - lldbTarget - lldbPluginUnwindAssemblyInstEmulation - lldbPluginDisassemblerLLVMC - lldbPluginInstructionPPC64 - lldbPluginProcessUtility - LINK_COMPONENTS - Support - ${LLVM_TARGETS_TO_BUILD}) diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp b/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp deleted file mode 100644 index 9892e18d99c..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//===-- TestPPC64InstEmulation.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 "gtest/gtest.h" - -#include - -#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/UnwindAssembly.h" -#include "lldb/Utility/ArchSpec.h" - -#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" -#include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h" -#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" -#include "llvm/Support/TargetSelect.h" - -using namespace lldb; -using namespace lldb_private; - -class TestPPC64InstEmulation : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - - // virtual void SetUp() override { } - // virtual void TearDown() override { } - -protected: -}; - -void TestPPC64InstEmulation::SetUpTestCase() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllDisassemblers(); - DisassemblerLLVMC::Initialize(); - EmulateInstructionPPC64::Initialize(); -} - -void TestPPC64InstEmulation::TearDownTestCase() { - DisassemblerLLVMC::Terminate(); - EmulateInstructionPPC64::Terminate(); -} - -TEST_F(TestPPC64InstEmulation, TestSimpleFunction) { - ArchSpec arch("powerpc64le-linux-gnu"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // prologue and epilogue of: - // int main() { - // int i = test(); - // return i; - // } - // - // compiled with clang -O0 -g - uint8_t data[] = { - // prologue - 0x02, 0x10, 0x40, 0x3c, // 0: lis r2, 4098 - 0x00, 0x7f, 0x42, 0x38, // 4: addi r2, r2, 32512 - 0xa6, 0x02, 0x08, 0x7c, // 8: mflr r0 - 0xf8, 0xff, 0xe1, 0xfb, // 12: std r31, -8(r1) - 0x10, 0x00, 0x01, 0xf8, // 16: std r0, 16(r1) - 0x91, 0xff, 0x21, 0xf8, // 20: stdu r1, -112(r1) - 0x78, 0x0b, 0x3f, 0x7c, // 24: mr r31, r1 - 0x00, 0x00, 0x60, 0x38, // 28: li r3, 0 - 0x64, 0x00, 0x7f, 0x90, // 32: stw r3, 100(r31) - - // epilogue - 0x70, 0x00, 0x21, 0x38, // 36: addi r1, r1, 112 - 0x10, 0x00, 0x01, 0xe8, // 40: ld r0, 16(r1) - 0xf8, 0xff, 0xe1, 0xeb, // 44: ld r31, -8(r1) - 0xa6, 0x03, 0x08, 0x7c, // 48: mtlr r0 - 0x20, 0x00, 0x80, 0x4e // 52: blr - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // 0: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - // 1: CFA=sp+0 => fp=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_r31_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 2: CFA=sp+0 => fp=[CFA-8] lr=[CFA+16] - row_sp = unwind_plan.GetRowForFunctionOffset(20); - EXPECT_EQ(20ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(16, regloc.GetOffset()); - - // 3: CFA=sp+112 => fp=[CFA-8] lr=[CFA+16] - row_sp = unwind_plan.GetRowForFunctionOffset(24); - EXPECT_EQ(24ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(112, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_r31_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(16, regloc.GetOffset()); - - // 4: CFA=r31+112 => fp=[CFA-8] lr=[CFA+16] - row_sp = unwind_plan.GetRowForFunctionOffset(28); - EXPECT_EQ(28ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r31_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(112, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_r31_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(16, regloc.GetOffset()); - - // 5: CFA=sp+0 => fp=[CFA-8] lr=[CFA+16] - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(40ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_r31_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(16, regloc.GetOffset()); -} - -TEST_F(TestPPC64InstEmulation, TestMediumFunction) { - ArchSpec arch("powerpc64le-linux-gnu"); - std::unique_ptr engine( - static_cast( - UnwindAssemblyInstEmulation::CreateInstance(arch))); - ASSERT_NE(nullptr, engine); - - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - UnwindPlan::Row::RegisterLocation regloc; - - // prologue and epilogue of main() (call-func.c), - // with several calls and stack variables. - // - // compiled with clang -O0 -g - uint8_t data[] = { - // prologue - 0xa6, 0x02, 0x08, 0x7c, // 0: mflr r0 - 0xf8, 0xff, 0xe1, 0xfb, // 4: std r31, -8(r1) - 0x10, 0x00, 0x01, 0xf8, // 8: std r0, 16(r1) - 0x78, 0x0b, 0x3e, 0x7c, // 12: mr r30, r1 - 0xe0, 0x06, 0x20, 0x78, // 16: clrldi r0, r1, 59 - 0xa0, 0xfa, 0x00, 0x20, // 20: subfic r0, r0, -1376 - 0x6a, 0x01, 0x21, 0x7c, // 24: stdux r1, r1, r0 - 0x78, 0x0b, 0x3f, 0x7c, // 28: mr r31, r1 - - // epilogue - 0x00, 0x00, 0x21, 0xe8, // 32: ld r1, 0(r1) - 0x20, 0x00, 0x80, 0x4e // 36: blr - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - sample_range, data, sizeof(data), unwind_plan)); - - // 0: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - // 1: CFA=sp+0 => fp=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(8ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_r31_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 2: CFA=sp+0 => fp=[CFA-8] lr=[CFA+16] - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_ppc64le, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(16, regloc.GetOffset()); - - // 3: CFA=r30 - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r30_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(32); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r30_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - // 4: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_EQ(36ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); -} diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/x86/CMakeLists.txt b/gnu/llvm/lldb/unittests/UnwindAssembly/x86/CMakeLists.txt deleted file mode 100644 index 2b5b31f7906..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/x86/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_lldb_unittest(UnwindAssemblyx86Tests - Testx86AssemblyInspectionEngine.cpp - LINK_LIBS - lldbCore - lldbSymbol - lldbPluginUnwindAssemblyX86 - LINK_COMPONENTS - Support - ${LLVM_TARGETS_TO_BUILD} - ) diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp b/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp deleted file mode 100644 index 8267ecbf57e..00000000000 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ /dev/null @@ -1,3117 +0,0 @@ -//===-- Testx86AssemblyInspectionEngine.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 "gtest/gtest.h" - -#include -#include - -#include "Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h" -#include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/StreamString.h" - -#include "llvm/Support/TargetSelect.h" - -using namespace lldb; -using namespace lldb_private; - -class Testx86AssemblyInspectionEngine : public testing::Test { -public: - static void SetUpTestCase(); - - // static void TearDownTestCase() { } - - // virtual void SetUp() override { } - - // virtual void TearDown() override { } - -protected: -}; - -void Testx86AssemblyInspectionEngine::SetUpTestCase() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllDisassemblers(); -} - -// only defining the register names / numbers that the unwinder is actually -// using today - -// names should match the constants below. These will be the eRegisterKindLLDB -// register numbers. - -const char *x86_64_reg_names[] = {"rax", "rbx", "rcx", "rdx", "rsp", "rbp", - "rsi", "rdi", "r8", "r9", "r10", "r11", - "r12", "r13", "r14", "r15", "rip"}; - -enum x86_64_regs { - k_rax = 0, - k_rbx = 1, - k_rcx = 2, - k_rdx = 3, - k_rsp = 4, - k_rbp = 5, - k_rsi = 6, - k_rdi = 7, - k_r8 = 8, - k_r9 = 9, - k_r10 = 10, - k_r11 = 11, - k_r12 = 12, - k_r13 = 13, - k_r14 = 14, - k_r15 = 15, - k_rip = 16 -}; - -// names should match the constants below. These will be the eRegisterKindLLDB -// register numbers. - -const char *i386_reg_names[] = {"eax", "ecx", "edx", "ebx", "esp", - "ebp", "esi", "edi", "eip"}; - -enum i386_regs { - k_eax = 0, - k_ecx = 1, - k_edx = 2, - k_ebx = 3, - k_esp = 4, - k_ebp = 5, - k_esi = 6, - k_edi = 7, - k_eip = 8 -}; - -std::unique_ptr Getx86_64Inspector() { - - ArchSpec arch("x86_64-apple-macosx"); - std::unique_ptr engine( - new x86AssemblyInspectionEngine(arch)); - - std::vector lldb_regnums; - int i = 0; - for (const auto &name : x86_64_reg_names) { - x86AssemblyInspectionEngine::lldb_reg_info ri; - ri.name = name; - ri.lldb_regnum = i++; - lldb_regnums.push_back(ri); - } - - engine->Initialize(lldb_regnums); - return engine; -} - -std::unique_ptr Geti386Inspector() { - - ArchSpec arch("i386-apple-macosx"); - std::unique_ptr engine( - new x86AssemblyInspectionEngine(arch)); - - std::vector lldb_regnums; - int i = 0; - for (const auto &name : i386_reg_names) { - x86AssemblyInspectionEngine::lldb_reg_info ri; - ri.name = name; - ri.lldb_regnum = i++; - lldb_regnums.push_back(ri); - } - - engine->Initialize(lldb_regnums); - return engine; -} - -namespace lldb_private { -static std::ostream &operator<<(std::ostream &OS, - const UnwindPlan::Row::FAValue &CFA) { - StreamString S; - CFA.Dump(S, nullptr, nullptr); - return OS << S.GetData(); -} -} // namespace lldb_private - -TEST_F(Testx86AssemblyInspectionEngine, TestSimple64bitFrameFunction) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for x86_64-apple-macosx with clang - uint8_t data[] = { - 0x55, // offset 0 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp - 0x31, 0xc0, // offset 4 -- xorl %eax, %eax - 0x5d, // offset 6 -- popq %rbp - 0xc3 // offset 7 -- retq - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Expect four unwind rows: - // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 4: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 7: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - - EXPECT_TRUE(unwind_plan.GetInitialCFARegister() == k_rsp); - EXPECT_TRUE(unwind_plan.GetUnwindPlanValidAtAllInstructions() == - eLazyBoolYes); - EXPECT_TRUE(unwind_plan.GetSourcedFromCompiler() == eLazyBoolNo); - - UnwindPlan::Row::RegisterLocation regloc; - - // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 4: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 7: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSimple32bitFrameFunction) { - std::unique_ptr engine = Geti386Inspector(); - - // 'int main() { }' compiled for i386-apple-macosx with clang - uint8_t data[] = { - 0x55, // offset 0 -- pushl %ebp - 0x89, 0xe5, // offset 1 -- movl %esp, %ebp - 0x31, 0xc0, // offset 3 -- xorl %eax, %eax - 0x5d, // offset 5 -- popl %ebp - 0xc3 // offset 6 -- retl - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Expect four unwind rows: - // 0: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - // 1: CFA=esp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - // 3: CFA=ebp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - // 6: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - - EXPECT_TRUE(unwind_plan.GetInitialCFARegister() == k_esp); - EXPECT_TRUE(unwind_plan.GetUnwindPlanValidAtAllInstructions() == - eLazyBoolYes); - EXPECT_TRUE(unwind_plan.GetSourcedFromCompiler() == eLazyBoolNo); - - UnwindPlan::Row::RegisterLocation regloc; - - // offset 0 -- pushl %ebp - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_TRUE(regloc.GetOffset() == -4); - - // 1: CFA=esp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-4, regloc.GetOffset()); - - // 3: CFA=ebp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(3); - EXPECT_EQ(3ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_ebp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-4, regloc.GetOffset()); - - // 6: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(6); - EXPECT_EQ(6ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-4, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, Test64bitFramelessBigStackFrame) { - std::unique_ptr engine = Getx86_64Inspector(); - - // this source file: - // - // #include - // int main (int argc, char **argv) - // { - // - // const int arrsize = 60; - // int buf[arrsize * arrsize]; - // int accum = argc; - // for (int i = 0; i < arrsize; i++) - // for (int j = 0; j < arrsize; j++) - // { - // if (i > 0 && j > 0) - // { - // int n = buf[(i-1) * (j-1)] * 2; - // int m = buf[(i-1) * (j-1)] / 2; - // int j = buf[(i-1) * (j-1)] + 2; - // int k = buf[(i-1) * (j-1)] - 2; - // printf ("%d ", n + m + j + k); - // buf[(i-1) * (j-1)] += n - m + j - k; - // } - // buf[i*j] = accum++; - // } - // - // return buf[(arrsize * arrsize) - 2] + printf ("%d\n", buf[(arrsize * - // arrsize) - 3]); - // } - // - // compiled 'clang -fomit-frame-pointer -Os' for x86_64-apple-macosx - - uint8_t data[] = { - 0x55, // offset 0 -- pushq %rbp - 0x41, 0x57, // offset 1 -- pushq %r15 - 0x41, 0x56, // offset 3 -- pushq %r14 - 0x41, 0x55, // offset 5 -- pushq %r13 - 0x41, 0x54, // offset 7 -- pushq %r12 - 0x53, // offset 9 -- pushq %rbx - 0x48, 0x81, 0xec, 0x68, 0x38, 0x00, - 0x00, // offset 10 -- subq $0x3868, %rsp - - // .... - - 0x48, 0x81, 0xc4, 0x68, 0x38, 0x00, - 0x00, // offset 17 -- addq $0x3868, %rsp - 0x5b, // offset 24 -- popq %rbx - 0x41, 0x5c, // offset 25 -- popq %r12 - 0x41, 0x5d, // offset 27 -- popq %r13 - 0x41, 0x5e, // offset 29 -- popq %r14 - 0x41, 0x5f, // offset 31 -- popq %r15 - 0x5d, // offset 33 -- popq %rbp - 0xc3, // offset 34 -- retq - 0xe8, 0x12, 0x34, 0x56, 0x78 // offset 35 -- callq whatever - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Unwind rules should look like - // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 3: CFA=rsp+24 => rbp=[CFA-16] rsp=CFA+0 r15=[CFA-24] rip=[CFA-8] - // 5: CFA=rsp+32 => rbp=[CFA-16] rsp=CFA+0 r14=[CFA-32] r15=[CFA-24] - // rip=[CFA-8 - // 7: CFA=rsp+40 => rbp=[CFA-16] rsp=CFA+0 r13=[CFA-40] r14=[CFA-32] - // r15=[CFA-24] rip=[CFA-8] - // 9: CFA=rsp+48 => rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] r13=[CFA-40] - // r14=[CFA-32] r15=[CFA-24] rip=[CFA-8] - // 10: CFA=rsp+56 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] - // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8] - // 17: CFA=rsp+14496 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] - // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8] - - // 24: CFA=rsp+56 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] - // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8] - // 25: CFA=rsp+48 => rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] r13=[CFA-40] - // r14=[CFA-32] r15=[CFA-24] rip=[CFA-8] - // 27: CFA=rsp+40 => rbp=[CFA-16] rsp=CFA+0 r13=[CFA-40] r14=[CFA-32] - // r15=[CFA-24] rip=[CFA-8] - // 29: CFA=rsp+32 => rbp=[CFA-16] rsp=CFA+0 r14=[CFA-32] r15=[CFA-24] - // rip=[CFA-8] - // 31: CFA=rsp+24 => rbp=[CFA-16] rsp=CFA+0 r15=[CFA-24] rip=[CFA-8] - // 33: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 34: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - - UnwindPlan::Row::RegisterLocation regloc; - - // grab the Row for when the prologue has finished executing: - // 17: CFA=rsp+14496 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] - // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8] - - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(17); - - EXPECT_EQ(17ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(14496, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r15, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-24, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r14, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-32, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r13, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-40, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r12, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-48, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbx, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-56, regloc.GetOffset()); - - // grab the Row for when the epilogue has finished executing: - // 34: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - - row_sp = unwind_plan.GetRowForFunctionOffset(34); - - EXPECT_EQ(34ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // these could be set to IsSame and be valid -- meaning that the - // register value is the same as the caller's -- but I'd rather - // they not be mentioned at all. - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rax, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rcx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rdx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rsi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rdi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r8, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r9, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r10, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r11, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r12, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r13, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r14, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r15, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, Test32bitFramelessBigStackFrame) { - std::unique_ptr engine = Geti386Inspector(); - - // this source file: - // - // #include - // int main (int argc, char **argv) - // { - // - // const int arrsize = 60; - // int buf[arrsize * arrsize]; - // int accum = argc; - // for (int i = 0; i < arrsize; i++) - // for (int j = 0; j < arrsize; j++) - // { - // if (i > 0 && j > 0) - // { - // int n = buf[(i-1) * (j-1)] * 2; - // int m = buf[(i-1) * (j-1)] / 2; - // int j = buf[(i-1) * (j-1)] + 2; - // int k = buf[(i-1) * (j-1)] - 2; - // printf ("%d ", n + m + j + k); - // buf[(i-1) * (j-1)] += n - m + j - k; - // } - // buf[i*j] = accum++; - // } - // - // return buf[(arrsize * arrsize) - 2] + printf ("%d\n", buf[(arrsize * - // arrsize) - 3]); - // } - // - // compiled 'clang -arch i386 -fomit-frame-pointer -Os' for i386-apple-macosx - - // simplified assembly version of the above function, which is used as the - // input - // data: - // - // .section __TEXT,__text,regular,pure_instructions - // .macosx_version_min 10, 12 - // .globl _main - // .align 4, 0x90 - // _main: ## @main - // ## BB#0: - // pushl %ebp - // pushl %ebx - // pushl %edi - // pushl %esi - // L0$pb: - // subl $0x386c, %esp - // calll L1 - // L1: - // popl %ecx - // movl %ecx, 0x8(%esp) - // subl $0x8, %esp - // pushl %eax - // pushl 0x20(%esp) - // calll _puts - // addl $0x10, %esp - // incl %ebx - // addl $0x386c, %esp - // popl %esi - // popl %edi - // popl %ebx - // popl %ebp - // retl - // - // .section __TEXT,__cstring,cstring_literals - // L_.str: ## @.str - // .asciz "HI" - // - // - // .subsections_via_symbols - - uint8_t data[] = { - 0x55, - // offset 0 -- pushl %ebp - - 0x53, - // offset 1 -- pushl %ebx - - 0x57, - // offset 2 -- pushl %edi - - 0x56, - // offset 3 -- pushl %esi - - 0x81, 0xec, 0x6c, 0x38, 0x00, 0x00, - // offset 4 -- subl $0x386c, %esp - - 0xe8, 0x00, 0x00, 0x00, 0x00, - // offset 10 -- calll 0 - // call the next instruction, to put the pc on the stack - - 0x59, - // offset 15 -- popl %ecx - // pop the saved pc address into ecx - - 0x89, 0x4c, 0x24, 0x08, - // offset 16 -- movl %ecx, 0x8(%esp) - - // .... - - 0x83, 0xec, 0x08, - // offset 20 -- subl $0x8, %esp - - 0x50, - // offset 23 -- pushl %eax - - 0xff, 0x74, 0x24, 0x20, - // offset 24 -- pushl 0x20(%esp) - - 0xe8, 0x8c, 0x00, 0x00, 0x00, - // offset 28 -- calll puts - - 0x83, 0xc4, 0x10, - // offset 33 -- addl $0x10, %esp - // get esp back to the value it was before the - // alignment & argument saves for the puts call - - 0x43, - // offset 36 -- incl %ebx - - // .... - - 0x81, 0xc4, 0x6c, 0x38, 0x00, 0x00, - // offset 37 -- addl $0x386c, %esp - - 0x5e, - // offset 43 -- popl %esi - - 0x5f, - // offset 44 -- popl %edi - - 0x5b, - // offset 45 -- popl %ebx - - 0x5d, - // offset 46 -- popl %ebp - - 0xc3, - // offset 47 -- retl - - 0xe8, 0x12, 0x34, 0x56, 0x78, - // offset 48 -- calll __stack_chk_fail - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Unwind rules should look like - // - // 0: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - // 1: CFA=esp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - // 2: CFA=esp+12 => ebx=[CFA-12] ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - // 3: CFA=esp+16 => ebx=[CFA-12] edi=[CFA-16] ebp=[CFA-8] esp=CFA+0 - // eip=[CFA-4] - // 4: CFA=esp+20 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 10: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 15: CFA=esp+14468 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 16: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // - // .... - // - // 23: CFA=esp+14472 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 24: CFA=esp+14476 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 28: CFA=esp+14480 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 36: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // - // ..... - // - // 37: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 43: CFA=esp+20 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - // 44: CFA=esp+16 => ebx=[CFA-12] edi=[CFA-16] ebp=[CFA-8] esp=CFA+0 - // eip=[CFA-4] - // 45: CFA=esp+12 => ebx=[CFA-12] ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - // 46: CFA=esp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4] - // 47: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - // 48: CFA=esp+14480 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - // Check that we get the CFA correct for the pic base setup sequence - - // CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(10); - EXPECT_EQ(10ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(14464, row_sp->GetCFAValue().GetOffset()); - - // 15: CFA=esp+14468 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(15); - EXPECT_EQ(15ull, row_sp->GetOffset()); - EXPECT_EQ(14468, row_sp->GetCFAValue().GetOffset()); - - // 16: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_EQ(14464, row_sp->GetCFAValue().GetOffset()); - - // Check that the row for offset 16 has the registers saved that we expect - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-4, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebx, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-12, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_edi, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_esi, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-20, regloc.GetOffset()); - - // - // Check the pushing & popping around the call printf instruction - - // 23: CFA=esp+14472 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(23); - EXPECT_EQ(23ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(14472, row_sp->GetCFAValue().GetOffset()); - - // 24: CFA=esp+14476 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(24); - EXPECT_EQ(24ull, row_sp->GetOffset()); - EXPECT_EQ(14476, row_sp->GetCFAValue().GetOffset()); - - // 28: CFA=esp+14480 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(28); - EXPECT_EQ(28ull, row_sp->GetOffset()); - EXPECT_EQ(14480, row_sp->GetCFAValue().GetOffset()); - - // 36: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8] - // esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_EQ(36ull, row_sp->GetOffset()); - EXPECT_EQ(14464, row_sp->GetCFAValue().GetOffset()); - - // Check that the epilogue gets us back to the original unwind state - - // 47: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(47); - EXPECT_EQ(47ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-4, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_esp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - // Check that no unexpected registers were saved - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_eax, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ecx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_edx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_esi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_edi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, Test64bitFramelessSmallStackFrame) { - std::unique_ptr engine = Getx86_64Inspector(); - - // this source file: - // #include - // int main () { - // puts ("HI"); - // } - // - // compiled 'clang -fomit-frame-pointer' for x86_64-apple-macosx - - uint8_t data[] = { - 0x50, - // offset 0 -- pushq %rax - - 0x48, 0x8d, 0x3d, 0x32, 0x00, 0x00, 0x00, - // offset 1 -- leaq 0x32(%rip), %rdi ; "HI" - - 0xe8, 0x0b, 0x00, 0x00, 0x00, - // offset 8 -- callq 0x100000f58 ; puts - - 0x31, 0xc9, - // offset 13 -- xorl %ecx, %ecx - - 0x89, 0x44, 0x24, 0x04, - // offset 15 -- movl %eax, 0x4(%rsp) - - 0x89, 0xc8, - // offset 19 -- movl %ecx, %eax - - 0x59, - // offset 21 -- popq %rcx - - 0xc3 - // offset 22 -- retq - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Unwind rules should look like - // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 1: CFA=rsp+16 => rsp=CFA+0 rip=[CFA-8] - // 22: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - - UnwindPlan::Row::RegisterLocation regloc; - - // grab the Row for when the prologue has finished executing: - // 1: CFA=rsp+16 => rsp=CFA+0 rip=[CFA-8] - - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(13); - - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // none of these were spilled - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rax, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rcx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rdx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rsi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rdi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r8, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r9, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r10, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r11, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r12, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r13, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r14, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r15, regloc)); - - // grab the Row for when the epilogue has finished executing: - // 22: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - - row_sp = unwind_plan.GetRowForFunctionOffset(22); - - EXPECT_EQ(22ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, Test32bitFramelessSmallStackFrame) { - std::unique_ptr engine = Geti386Inspector(); - - // this source file: - // #include - // int main () { - // puts ("HI"); - // } - // - // compiled 'clang -arch i386 -fomit-frame-pointer' for i386-apple-macosx - - uint8_t data[] = { - 0x83, 0xec, 0x0c, - // offset 0 -- subl $0xc, %esp - - 0xe8, 0x00, 0x00, 0x00, 0x00, - // offset 3 -- calll 0 {call the next instruction, to put the pc on - // the stack} - - 0x58, - // offset 8 -- popl %eax {pop the saved pc value off stack, into eax} - - 0x8d, 0x80, 0x3a, 0x00, 0x00, 0x00, - // offset 9 -- leal 0x3a(%eax),%eax - - 0x89, 0x04, 0x24, - // offset 15 -- movl %eax, (%esp) - - 0xe8, 0x0d, 0x00, 0x00, 0x00, - // offset 18 -- calll 0x1f94 (puts) - - 0x31, 0xc9, - // offset 23 -- xorl %ecx, %ecx - - 0x89, 0x44, 0x24, 0x08, - // offset 25 -- movl %eax, 0x8(%esp) - - 0x89, 0xc8, - // offset 29 -- movl %ecx, %eax - - 0x83, 0xc4, 0x0c, - // offset 31 -- addl $0xc, %esp - - 0xc3 - // offset 34 -- retl - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Unwind rules should look like - // row[0]: 0: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - // row[1]: 3: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] - // row[2]: 8: CFA=esp+20 => esp=CFA+0 eip=[CFA-4] - // row[3]: 9: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] - // row[4]: 34: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - - UnwindPlan::Row::RegisterLocation regloc; - - // Check unwind state before we set up the picbase register - // 3: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] - - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(3); - - EXPECT_EQ(3ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - // Check unwind state after we call the next instruction - // 8: CFA=esp+20 => esp=CFA+0 eip=[CFA-4] - - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(8ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(20, row_sp->GetCFAValue().GetOffset()); - - // Check unwind state after we pop the pic base value off the stack - // row[3]: 9: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] - - row_sp = unwind_plan.GetRowForFunctionOffset(9); - EXPECT_EQ(9ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - // Check that no unexpected registers were saved - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_eax, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ecx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_edx, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_esi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_edi, regloc)); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc)); - - // verify that we get back to the original unwind state before the ret - // 34: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - - row_sp = unwind_plan.GetRowForFunctionOffset(34); - EXPECT_EQ(34ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushRBP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x55, // pushq %rbp - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - std::unique_ptr engine32 = Geti386Inspector(); - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushImm) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x68, 0xff, 0xff, 0x01, 0x69, // pushq $0x6901ffff - 0x6a, 0x7d, // pushl $0x7d - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(5); - EXPECT_EQ(5ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(24, row_sp->GetCFAValue().GetOffset()); - - std::unique_ptr engine32 = Geti386Inspector(); - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(5); - EXPECT_EQ(5ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(12, row_sp->GetCFAValue().GetOffset()); -} - -// We treat 'pushq $0' / 'pushl $0' specially - this shows up -// in the first function called in a new thread and it needs to -// put a 0 as the saved pc. We pretend it didn't change the CFA. -TEST_F(Testx86AssemblyInspectionEngine, TestPush0) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x6a, 0x00, // pushq $0 - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - // We're verifying that no row was created for the 'pushq $0' - EXPECT_EQ(0ull, row_sp->GetOffset()); - - std::unique_ptr engine32 = Geti386Inspector(); - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - // We're verifying that no row was created for the 'pushq $0' - EXPECT_EQ(0ull, row_sp->GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushExtended) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0xff, 0x74, 0x24, 0x20, // pushl 0x20(%esp) - 0xff, 0xb6, 0xce, 0x01, 0xf0, 0x00, // pushl 0xf001ce(%esi) - 0xff, 0x30, // pushl (%eax) - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - std::unique_ptr engine32 = Geti386Inspector(); - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(10); - EXPECT_EQ(10ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(12, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushR15) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x41, 0x57, // pushq %r15 - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r15, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushR14) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x41, 0x56, // pushq %r14 - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r14, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushR13) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x41, 0x55, // pushq %r13 - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r13, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushR12) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x41, 0x54, // pushq %r13 - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r12, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushRBX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x53, // pushq %rbx - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbx, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); -} - -// The ABI is hardcoded in x86AssemblyInspectionEngine such that -// eax, ecx, edx are all considered volatile and push/pops of them are -// not tracked (except to keep track of stack pointer movement) -TEST_F(Testx86AssemblyInspectionEngine, TestPushEAX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x50, // pushl %eax - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_eax, regloc)); -} - -// The ABI is hardcoded in x86AssemblyInspectionEngine such that -// eax, ecx, edx are all considered volatile and push/pops of them are -// not tracked (except to keep track of stack pointer movement) -TEST_F(Testx86AssemblyInspectionEngine, TestPushECX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x51, // pushl %ecx - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ecx, regloc)); -} - -// The ABI is hardcoded in x86AssemblyInspectionEngine such that -// eax, ecx, edx are all considered volatile and push/pops of them are -// not tracked (except to keep track of stack pointer movement) -TEST_F(Testx86AssemblyInspectionEngine, TestPushEDX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x52, // pushl %edx - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_edx, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushEBX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x53, // pushl %ebx - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebx, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushEBP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x55, // pushl %ebp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushRBPWithREX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data[] = { - 0x40, 0x55, // pushq %rbp - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushESI) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x56, // pushl %esi - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_esi, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPushEDI) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x57, // pushl %edi - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_edi, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestMovRSPtoRBP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - - uint8_t data64_1[] = { - 0x48, 0x8b, 0xec, // movq %rsp, %rbp - 0x90 // nop - }; - - AddressRange sample_range(0x1000, sizeof(data64_1)); - UnwindPlan unwind_plan(eRegisterKindLLDB); - - std::unique_ptr engine64 = Getx86_64Inspector(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data64_1, sizeof(data64_1), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(3); - - EXPECT_EQ(3ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - uint8_t data64_2[] = { - 0x48, 0x89, 0xe5, // movq %rsp, %rbp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data64_2)); - unwind_plan.Clear(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data64_2, sizeof(data64_2), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(3); - EXPECT_EQ(3ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - uint8_t data32_1[] = { - 0x8b, 0xec, // movl %rsp, %rbp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data32_1)); - unwind_plan.Clear(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data32_1, sizeof(data32_1), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_ebp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - uint8_t data32_2[] = { - 0x89, 0xe5, // movl %rsp, %rbp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data32_2)); - unwind_plan.Clear(); - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data32_2, sizeof(data32_2), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_ebp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSubRSP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data1[] = { - 0x48, 0x81, 0xec, 0x00, 0x01, 0x00, 0x00, // subq $0x100, $rsp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data1)); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data1, sizeof(data1), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(264, row_sp->GetCFAValue().GetOffset()); - - uint8_t data2[] = { - 0x48, 0x83, 0xec, 0x10, // subq $0x10, %rsp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data2)); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data2, sizeof(data2), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(24, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSubESP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data1[] = { - 0x81, 0xec, 0x00, 0x01, 0x00, 0x00, // subl $0x100, %esp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data1)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data1, sizeof(data1), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(6); - EXPECT_EQ(6ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(260, row_sp->GetCFAValue().GetOffset()); - - uint8_t data2[] = { - 0x83, 0xec, 0x10, // subq $0x10, %esp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data2)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data2, sizeof(data2), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(3); - EXPECT_EQ(3ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(20, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestAddRSP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data1[] = { - 0x48, 0x81, 0xc4, 0x00, 0x01, 0x00, 0x00, // addq $0x100, %rsp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data1)); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data1, sizeof(data1), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8 - 256, row_sp->GetCFAValue().GetOffset()); - - uint8_t data2[] = { - 0x48, 0x83, 0xc4, 0x10, // addq $0x10, %rsp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data2)); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data2, sizeof(data2), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8 - 16, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestAddESP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data1[] = { - 0x81, 0xc4, 0x00, 0x01, 0x00, 0x00, // addl $0x100, %esp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data1)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data1, sizeof(data1), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(6); - EXPECT_EQ(6ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4 - 256, row_sp->GetCFAValue().GetOffset()); - - uint8_t data2[] = { - 0x83, 0xc4, 0x10, // addq $0x10, %esp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data2)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data2, sizeof(data2), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(3); - EXPECT_EQ(3ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4 - 16, row_sp->GetCFAValue().GetOffset()); -} - -// FIXME add test for lea_rsp_pattern_p - -TEST_F(Testx86AssemblyInspectionEngine, TestPopRBX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x53, // pushq %rbx - 0x5b, // popq %rbx - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbx, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopRBP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x55, // pushq %rbp - 0x5d, // popq %rbp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopR12) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x41, 0x54, // pushq %r12 - 0x41, 0x5c, // popq %r12 - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r12, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopR13) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x41, 0x55, // pushq %r13 - 0x41, 0x5d, // popq %r13 - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r13, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopR14) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x41, 0x56, // pushq %r14 - 0x41, 0x5e, // popq %r14 - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r14, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopR15) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x41, 0x57, // pushq %r15 - 0x41, 0x5f, // popq %r15 - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_r15, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopEBX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x53, // pushl %ebx - 0x5b, // popl %ebx - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebx, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopEBP) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x55, // pushl %ebp - 0x5d, // popl %ebp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopRBPWithREX) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x40, 0x55, // pushq %rbp - 0x40, 0x5d, // popq %rbp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopESI) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x56, // pushl %esi - 0x5e, // popl %esi - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_esi, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestPopEDI) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x57, // pushl %edi - 0x5f, // popl %edi - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_edi, regloc)); -} - -// We don't track these registers, but make sure the CFA address is updated -// if we're defining the CFA in term of esp. -TEST_F(Testx86AssemblyInspectionEngine, Testi386IgnoredRegisters) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x0e, // push cs - 0x16, // push ss - 0x1e, // push ds - 0x06, // push es - - 0x07, // pop es - 0x1f, // pop ds - 0x17, // pop ss - - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(20, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestLEAVE) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine64 = Getx86_64Inspector(); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x55, // push %rbp/ebp - 0xc9, // leave - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc)); -} - -// In i386, which lacks pc-relative addressing, a common code sequence -// is to call the next instruction (i.e. call imm32, value of 0) which -// pushes the addr of the next insn on the stack, and then pop that value -// into a register (the "pic base" register). -TEST_F(Testx86AssemblyInspectionEngine, TestCALLNextInsn) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0xe8, 0x00, 0x00, 0x00, 0x00, // call 0 - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(5); - EXPECT_EQ(5ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSpillRegToStackViaMOVx86_64) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data[] = { - 0x55, // pushq %rbp - 0x48, 0x89, 0xe5, // movq %rsp, %rbp - 0x4c, 0x89, 0x75, 0xc0, // movq %r14, -0x40(%rbp) - 0x4c, 0x89, 0xbd, 0x28, 0xfa, 0xff, 0xff, // movq %r15, -0x5d8(%rbp) - 0x48, 0x89, 0x5d, 0xb8, // movq %rbx, -0x48(%rbp) - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(19); - EXPECT_EQ(19ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r14, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-80, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_r15, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-1512, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbx, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-88, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSpillRegToStackViaMOVi386) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x55, // pushl %ebp - 0x89, 0xe5, // movl %esp, %ebp - 0x89, 0x9d, 0xb0, 0xfe, 0xff, 0xff, // movl %ebx, -0x150(%ebp) - 0x89, 0x75, 0xe0, // movl %esi, -0x20(%ebp) - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebx, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-344, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_esi, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-40, regloc.GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSpArithx86_64Augmented) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data[] = { - 0x55, // pushq %rbp - 0x48, 0x89, 0xe5, // movq %rsp, %rbp - - // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite - // has a bug where it can't augment a function that is just - // prologue+epilogue - it needs at least one other instruction - // in between. - - 0x90, // nop - 0x48, 0x81, 0xec, 0x88, 0, 0, 0, // subq $0x88, %rsp - 0x90, // nop - 0x48, 0x81, 0xc4, 0x88, 0, 0, 0, // addq $0x88, %rsp - - 0x5d, // popq %rbp - 0xc3 // retq - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - unwind_plan.SetSourceName("unit testing hand-created unwind plan"); - unwind_plan.SetPlanValidAddressRange(sample_range); - unwind_plan.SetRegisterKind(eRegisterKindLLDB); - - row_sp = std::make_shared(); - - // Describe offset 0 - row_sp->SetOffset(0); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 8); - - regloc.SetAtCFAPlusOffset(-8); - row_sp->SetRegisterInfo(k_rip, regloc); - - unwind_plan.AppendRow(row_sp); - - // Allocate a new Row, populate it with the existing Row contents. - UnwindPlan::Row *new_row = new UnwindPlan::Row; - *new_row = *row_sp.get(); - row_sp.reset(new_row); - - // Describe offset 1 - row_sp->SetOffset(1); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 16); - regloc.SetAtCFAPlusOffset(-16); - row_sp->SetRegisterInfo(k_rbp, regloc); - unwind_plan.AppendRow(row_sp); - - // Allocate a new Row, populate it with the existing Row contents. - new_row = new UnwindPlan::Row; - *new_row = *row_sp.get(); - row_sp.reset(new_row); - - // Describe offset 4 - row_sp->SetOffset(4); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 16); - unwind_plan.AppendRow(row_sp); - - RegisterContextSP reg_ctx_sp; - EXPECT_TRUE(engine64->AugmentUnwindPlanFromCallSite( - data, sizeof(data), sample_range, unwind_plan, reg_ctx_sp)); - - // Before we touch the stack pointer, we should still refer to the - // row from after the prologue. - row_sp = unwind_plan.GetRowForFunctionOffset(5); - EXPECT_EQ(4ull, row_sp->GetOffset()); - - // Check the first stack pointer update. - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_EQ(152, row_sp->GetCFAValue().GetOffset()); - - // After the nop, we should still refer to the same row. - row_sp = unwind_plan.GetRowForFunctionOffset(13); - EXPECT_EQ(12ull, row_sp->GetOffset()); - - // Check that the second stack pointer update is reflected in the - // unwind plan. - row_sp = unwind_plan.GetRowForFunctionOffset(20); - EXPECT_EQ(20ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSimplex86_64Augmented) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data[] = { - 0x55, // pushq %rbp - 0x48, 0x89, 0xe5, // movq %rsp, %rbp - - // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite - // has a bug where it can't augment a function that is just - // prologue+epilogue - it needs at least one other instruction - // in between. - 0x90, // nop - - 0x5d, // popq %rbp - 0xc3 // retq - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - unwind_plan.SetSourceName("unit testing hand-created unwind plan"); - unwind_plan.SetPlanValidAddressRange(sample_range); - unwind_plan.SetRegisterKind(eRegisterKindLLDB); - - row_sp = std::make_shared(); - - // Describe offset 0 - row_sp->SetOffset(0); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 8); - - regloc.SetAtCFAPlusOffset(-8); - row_sp->SetRegisterInfo(k_rip, regloc); - - unwind_plan.AppendRow(row_sp); - - // Allocate a new Row, populate it with the existing Row contents. - UnwindPlan::Row *new_row = new UnwindPlan::Row; - *new_row = *row_sp.get(); - row_sp.reset(new_row); - - // Describe offset 1 - row_sp->SetOffset(1); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 16); - regloc.SetAtCFAPlusOffset(-16); - row_sp->SetRegisterInfo(k_rbp, regloc); - unwind_plan.AppendRow(row_sp); - - // Allocate a new Row, populate it with the existing Row contents. - new_row = new UnwindPlan::Row; - *new_row = *row_sp.get(); - row_sp.reset(new_row); - - // Describe offset 4 - row_sp->SetOffset(4); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rbp, 16); - unwind_plan.AppendRow(row_sp); - - RegisterContextSP reg_ctx_sp; - EXPECT_TRUE(engine64->AugmentUnwindPlanFromCallSite( - data, sizeof(data), sample_range, unwind_plan, reg_ctx_sp)); - - row_sp = unwind_plan.GetRowForFunctionOffset(6); - EXPECT_EQ(6ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite - // doesn't track register restores (pop'ing a reg value back from - // the stack) - it was just written to make stepping work correctly. - // Technically we should be able to do the following test, but it - // won't work today - the unwind plan will still say that the caller's - // rbp is on the stack. - // EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSimplei386ugmented) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - - uint8_t data[] = { - 0x55, // pushl %ebp - 0x89, 0xe5, // movl %esp, %ebp - - // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite - // has a bug where it can't augment a function that is just - // prologue+epilogue - it needs at least one other instruction - // in between. - 0x90, // nop - - 0x5d, // popl %ebp - 0xc3 // retl - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - unwind_plan.SetSourceName("unit testing hand-created unwind plan"); - unwind_plan.SetPlanValidAddressRange(sample_range); - unwind_plan.SetRegisterKind(eRegisterKindLLDB); - - row_sp = std::make_shared(); - - // Describe offset 0 - row_sp->SetOffset(0); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_esp, 4); - - regloc.SetAtCFAPlusOffset(-4); - row_sp->SetRegisterInfo(k_eip, regloc); - - unwind_plan.AppendRow(row_sp); - - // Allocate a new Row, populate it with the existing Row contents. - UnwindPlan::Row *new_row = new UnwindPlan::Row; - *new_row = *row_sp.get(); - row_sp.reset(new_row); - - // Describe offset 1 - row_sp->SetOffset(1); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_esp, 8); - regloc.SetAtCFAPlusOffset(-8); - row_sp->SetRegisterInfo(k_ebp, regloc); - unwind_plan.AppendRow(row_sp); - - // Allocate a new Row, populate it with the existing Row contents. - new_row = new UnwindPlan::Row; - *new_row = *row_sp.get(); - row_sp.reset(new_row); - - // Describe offset 3 - row_sp->SetOffset(3); - row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_ebp, 8); - unwind_plan.AppendRow(row_sp); - - RegisterContextSP reg_ctx_sp; - EXPECT_TRUE(engine32->AugmentUnwindPlanFromCallSite( - data, sizeof(data), sample_range, unwind_plan, reg_ctx_sp)); - - row_sp = unwind_plan.GetRowForFunctionOffset(5); - EXPECT_EQ(5ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset()); - - // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite - // doesn't track register restores (pop'ing a reg value back from - // the stack) - it was just written to make stepping work correctly. - // Technically we should be able to do the following test, but it - // won't work today - the unwind plan will still say that the caller's - // ebp is on the stack. - // EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc)); -} - -// Check that the i386 disassembler disassembles past an opcode that -// is only valid in 32-bit mode (non-long mode), and the x86_64 disassembler -// stops -// disassembling at that point (long-mode). -TEST_F(Testx86AssemblyInspectionEngine, Test32BitOnlyInstruction) { - UnwindPlan::Row::RegisterLocation regloc; - UnwindPlan::RowSP row_sp; - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data[] = { - 0x43, // incl $ebx --- an invalid opcode in 64-bit mode - 0x55, // pushl %ebp - 0x90 // nop - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(2ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - unwind_plan.Clear(); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - row_sp = unwind_plan.GetRowForFunctionOffset(2); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc)); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestStackRealign8BitDisp_i386) { - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x55, // pushl %ebp - 0x89, 0xe5, // movl %esp, %ebp - 0x53, // pushl %ebx - 0x83, 0xe4, 0xf0, // andl $-16, %esp - 0x83, 0xec, 0x10, // subl $16, %esp - 0x8d, 0x65, 0xfc, // leal -4(%ebp), %esp - 0x5b, // popl %ebx - 0x5d, // popl %ebp - 0xc3, // retl - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan plan(eRegisterKindLLDB); - ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), - sample_range, plan)); - - UnwindPlan::Row::FAValue esp_plus_4, esp_plus_8, ebp_plus_8; - esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); - esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); - ebp_plus_8.SetIsRegisterPlusOffset(k_ebp, 8); - - EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(0)->GetCFAValue()); - EXPECT_EQ(esp_plus_8, plan.GetRowForFunctionOffset(1)->GetCFAValue()); - for (size_t i = 3; i < sizeof(data) - 2; ++i) - EXPECT_EQ(ebp_plus_8, plan.GetRowForFunctionOffset(i)->GetCFAValue()) - << "i: " << i; - EXPECT_EQ(esp_plus_4, - plan.GetRowForFunctionOffset(sizeof(data) - 1)->GetCFAValue()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestStackRealign32BitDisp_x86_64) { - std::unique_ptr engine = Getx86_64Inspector(); - - uint8_t data[] = { - 0x55, // pushq %rbp - 0x48, 0x89, 0xe5, // movq %rsp, %rbp - 0x53, // pushl %rbx - 0x48, 0x83, 0xe4, 0xf0, // andq $-16, %rsp - 0x48, 0x81, 0xec, 0x00, 0x01, 0x00, 0x00, // subq $256, %rsp - 0x48, 0x8d, 0x65, 0xf8, // leaq -8(%rbp), %rsp - 0x5b, // popq %rbx - 0x5d, // popq %rbp - 0xc3, // retq - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan plan(eRegisterKindLLDB); - ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), - sample_range, plan)); - - UnwindPlan::Row::FAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; - rsp_plus_8.SetIsRegisterPlusOffset(k_rsp, 8); - rsp_plus_16.SetIsRegisterPlusOffset(k_rsp, 16); - rbp_plus_16.SetIsRegisterPlusOffset(k_rbp, 16); - - EXPECT_EQ(rsp_plus_8, plan.GetRowForFunctionOffset(0)->GetCFAValue()); - EXPECT_EQ(rsp_plus_16, plan.GetRowForFunctionOffset(1)->GetCFAValue()); - for (size_t i = 4; i < sizeof(data) - 2; ++i) - EXPECT_EQ(rbp_plus_16, plan.GetRowForFunctionOffset(i)->GetCFAValue()) - << "i: " << i; - EXPECT_EQ(rsp_plus_8, - plan.GetRowForFunctionOffset(sizeof(data) - 1)->GetCFAValue()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestStackRealignMSVC_i386) { - std::unique_ptr engine = Geti386Inspector(); - - uint8_t data[] = { - 0x53, // offset 00 -- pushl %ebx - 0x8b, 0xdc, // offset 01 -- movl %esp, %ebx - 0x83, 0xec, 0x08, // offset 03 -- subl $8, %esp - 0x81, 0xe4, 0x00, 0xff, 0xff, 0xff, // offset 06 -- andl $-256, %esp - 0x83, 0xc4, 0x04, // offset 12 -- addl $4, %esp - 0x55, // offset 15 -- pushl %ebp - 0x8b, 0xec, // offset 16 -- movl %esp, %ebp - 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // offset 18 -- subl $512, %esp - 0x89, 0x7d, 0xfc, // offset 24 -- movl %edi, -4(%ebp) - 0x8b, 0xe5, // offset 27 -- movl %ebp, %esp - 0x5d, // offset 29 -- popl %ebp - 0x8b, 0xe3, // offset 30 -- movl %ebx, %esp - 0x5b, // offset 32 -- popl %ebx - 0xc3 // offset 33 -- retl - }; - - AddressRange sample_range(0x1000, sizeof(data)); - UnwindPlan plan(eRegisterKindLLDB); - ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), - sample_range, plan)); - - UnwindPlan::Row::FAValue esp_minus_4, esp_plus_0, esp_plus_4, esp_plus_8, - ebx_plus_8, ebp_plus_0; - esp_minus_4.SetIsRegisterPlusOffset(k_esp, -4); - esp_plus_0.SetIsRegisterPlusOffset(k_esp, 0); - esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); - esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); - ebx_plus_8.SetIsRegisterPlusOffset(k_ebx, 8); - ebp_plus_0.SetIsRegisterPlusOffset(k_ebp, 0); - - // Test CFA - EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(0)->GetCFAValue()); - EXPECT_EQ(esp_plus_8, plan.GetRowForFunctionOffset(1)->GetCFAValue()); - for (size_t i = 3; i < 33; ++i) - EXPECT_EQ(ebx_plus_8, plan.GetRowForFunctionOffset(i)->GetCFAValue()) - << "i: " << i; - EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(33)->GetCFAValue()); - - // Test AFA - EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(12)->GetAFAValue()); - EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOffset(15)->GetAFAValue()); - EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(16)->GetAFAValue()); - for (size_t i = 18; i < 30; ++i) - EXPECT_EQ(ebp_plus_0, plan.GetRowForFunctionOffset(i)->GetAFAValue()) - << "i: " << i; - EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOffset(30)->GetAFAValue()); - - // Test saved register - UnwindPlan::Row::RegisterLocation reg_loc; - EXPECT_TRUE( - plan.GetRowForFunctionOffset(27)->GetRegisterInfo(k_edi, reg_loc)); - EXPECT_TRUE(reg_loc.IsAtAFAPlusOffset()); - EXPECT_EQ(-4, reg_loc.GetOffset()); -} - -// Give the disassembler random bytes to test that it doesn't exceed -// the bounds of the array when run under clang's address sanitizer. -TEST_F(Testx86AssemblyInspectionEngine, TestDisassemblyJunkBytes) { - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data[] = { - 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - unwind_plan.Clear(); - - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - -} - -TEST_F(Testx86AssemblyInspectionEngine, TestRetguard64bitFrameFunction) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for amd64-unknown-openbsd6.4 with -fret-protector - uint8_t data[] = { - 0x4c, 0x8b, 0x1d, 0xf1, 0x0c, 0x00, 0x00, // offset 0 -- movq 3313(%rip), %r11 - 0x4c, 0x33, 0x1c, 0x24, // offset 7 -- xorq (%rsp), %r11 - 0x55, // offset 11 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 12 -- movq %rsp, %rbp - 0x41, 0x53, // offset 15 -- pushq %r11 - 0x31, 0xc0, // offset 17 -- xorl %eax, %eax - 0x41, 0x5b, // offset 19 -- popq %r11 - 0x5d, // offset 21 -- popq %rbp - 0x4c, 0x33, 0x1c, 0x24, // offset 22 -- xorq (%rsp), %r11 - 0x4c, 0x3b, 0x1d, 0xd7, 0x0c, 0x00, 0x00, // offset 26 -- cmp 3287(%rsp), %r11 - 0x0f, 0x84, 0x02, 0x00, 0x00, 0x00, // offset 33 -- je +2 - 0xcc, // offset 39 -- int3 - 0xcc, // offset 40 -- int3 - 0xc3 // offset 41 -- retq - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // We expect 4 rows in the unwind plan, corresponding to offsets - // 0: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - // 12: CFA=rsp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - // 15: CFA=rbp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - // 22: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - - EXPECT_TRUE(unwind_plan.GetInitialCFARegister() == k_rsp); - EXPECT_TRUE(unwind_plan.GetUnwindPlanValidAtAllInstructions() == - eLazyBoolYes); - EXPECT_TRUE(unwind_plan.GetSourcedFromCompiler() == eLazyBoolNo); - - UnwindPlan::Row::RegisterLocation regloc; - - // 0: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(0ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(11); - EXPECT_EQ(0ull, row_sp->GetOffset()); - - // 12: CFA=rsp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - // 15: CFA=rbp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - row_sp = unwind_plan.GetRowForFunctionOffset(15); - EXPECT_EQ(15ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(17); - EXPECT_EQ(15ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(19); - EXPECT_EQ(15ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(21); - EXPECT_EQ(15ull, row_sp->GetOffset()); - - // 22: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(22); - EXPECT_EQ(22ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(26); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(33); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(39); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(41); - EXPECT_EQ(22ull, row_sp->GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSimple64bitPrologueDetection) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for x86_64-apple-macosx with clang - uint8_t data[] = { - 0x55, // offset 0 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp - 0x31, 0xc0, // offset 4 -- xorl %eax, %eax - 0x5d, // offset 6 -- popq %rbp - 0xc3 // offset 7 -- retq - }; - - size_t offset = 0; - EXPECT_TRUE(engine->FindFirstNonPrologueInstruction(data, sizeof(data), offset)); - EXPECT_EQ(4ull, offset); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestRetguard64bitPrologueDetection) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for amd64-unknown-openbsd6.4 with -fret-protector - uint8_t data[] = { - 0x4c, 0x8b, 0x1d, 0xf1, 0x0c, 0x00, 0x00, // offset 0 -- movq 3313(%rip), %r11 - 0x4c, 0x33, 0x1c, 0x24, // offset 7 -- xorq (%rsp), %r11 - 0x55, // offset 11 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 12 -- movq %rsp, %rbp - 0x41, 0x53, // offset 15 -- pushq %r11 - 0x31, 0xc0, // offset 17 -- xorl %eax, %eax - 0x41, 0x5b, // offset 19 -- popq %r11 - 0x5d, // offset 21 -- popq %rbp - 0x4c, 0x33, 0x1c, 0x24, // offset 22 -- xorq (%rsp), %r11 - 0x4c, 0x3b, 0x1d, 0xd7, 0x0c, 0x00, 0x00, // offset 26 -- cmp 3287(%rsp), %r11 - 0x0f, 0x84, 0x02, 0x00, 0x00, 0x00, // offset 33 -- je +2 - 0xcc, // offset 39 -- int3 - 0xcc, // offset 40 -- int3 - 0xc3 // offset 41 -- retq - }; - - size_t offset = 0; - EXPECT_TRUE(engine->FindFirstNonPrologueInstruction(data, sizeof(data), offset)); - EXPECT_EQ(17ull, offset); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestReturnDetect) { - std::unique_ptr engine = Getx86_64Inspector(); - - // Single fragment with all four return forms. - // We want to verify that the unwind state is reset after each ret. - uint8_t data[] = { - 0x55, // offset 0 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp - 0x31, 0xc0, // offset 4 -- xorl %eax, %eax - 0x5d, // offset 6 -- popq %rbp - 0xc3, // offset 7 -- retq - 0x31, 0xc0, // offset 8 -- xorl %eax, %eax - 0x5d, // offset 10 -- popq %rbp - 0xcb, // offset 11 -- retf - 0x31, 0xc0, // offset 12 -- xorl %eax, %eax - 0x5d, // offset 14 -- popq %rbp - 0xc2, 0x22, 0x11, // offset 15 -- retq 0x1122 - 0x31, 0xc0, // offset 18 -- xorl %eax, %eax - 0x5d, // offset 20 -- popq %rbp - 0xca, 0x44, 0x33, // offset 21 -- retf 0x3344 - 0x31, 0xc0, // offset 24 -- xorl %eax, %eax - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - data, sizeof(data), sample_range, unwind_plan)); - - // Expect following unwind rows: - // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 4: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 7: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 8: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 11: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 12: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 15: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 18: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - // 21: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - // 24: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - - EXPECT_TRUE(unwind_plan.GetInitialCFARegister() == k_rsp); - EXPECT_TRUE(unwind_plan.GetUnwindPlanValidAtAllInstructions() == - eLazyBoolYes); - EXPECT_TRUE(unwind_plan.GetSourcedFromCompiler() == eLazyBoolNo); - - UnwindPlan::Row::RegisterLocation regloc; - - // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(1); - EXPECT_EQ(1ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 4: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(4ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 7: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(7ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 8: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(8ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 11: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(11); - EXPECT_EQ(11ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 12: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 15: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(15); - EXPECT_EQ(15ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 18: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(18); - EXPECT_EQ(18ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 21: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(21); - EXPECT_EQ(21ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - // 24: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(24); - EXPECT_EQ(24ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); -} - - -// Test mid-function epilogues - the unwind state post-prologue -// should be re-instated. - -TEST_F(Testx86AssemblyInspectionEngine, TestDisassemblyMidFunctionEpilogues) { - AddressRange sample_range; - UnwindPlan unwind_plan(eRegisterKindLLDB); - std::unique_ptr engine32 = Geti386Inspector(); - std::unique_ptr engine64 = Getx86_64Inspector(); - - uint8_t data[] = { - 0x55, // <+0>: pushq %rbp - 0x48, 0x89, 0xe5, // <+1>: movq %rsp, %rbp - 0x48, 0x83, 0xec, 0x70, // <+4>: subq $0x70, %rsp - 0x90, // <+8>: nop // prologue set up - - 0x74, 0x7, // <+9>: je 7 <+18> - 0x48, 0x83, 0xc4, 0x70, // <+11>: addq $0x70, %rsp - 0x5d, // <+15>: popq %rbp - 0xff, 0xe0, // <+16>: jmpq *%rax // epilogue completed - - 0x90, // <+18>: nop // prologue setup back - - 0x74, 0x7, // <+19>: je 6 <+27> - 0x48, 0x83, 0xc4, 0x70, // <+21>: addq $0x70, %rsp - 0x5d, // <+25>: popq %rbp - 0xc3, // <+26>: retq // epilogue completed - - 0x90, // <+27>: nop // prologue setup back - - 0x48, 0x83, 0xc4, 0x70, // <+28>: addq $0x70, %rsp - 0x5d, // <+32>: popq %rbp - 0xc3, // <+33>: retq // epilogue completed - - }; - - sample_range = AddressRange(0x1000, sizeof(data)); - - int wordsize = 4; - EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Check that we've unwound the stack after the first mid-function epilogue - // row: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize, row_sp->GetCFAValue().GetOffset()); - - // Check that we've reinstated the stack frame setup - // unwind instructions after a jmpq *%eax - // row: CFA=ebp +8 => esp=CFA+0 eip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(18); - EXPECT_EQ(18ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_ebp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize * 2, row_sp->GetCFAValue().GetOffset()); - - // Check that we've reinstated the stack frame setup - // unwind instructions after a mid-function retq - // row: CFA=ebp +8 => esp=CFA+0 eip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(27); - EXPECT_EQ(27ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_ebp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize * 2, row_sp->GetCFAValue().GetOffset()); - - // After last instruction in the function, verify that - // the stack frame has been unwound - // row: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] - row_sp = unwind_plan.GetRowForFunctionOffset(33); - EXPECT_EQ(33ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize, row_sp->GetCFAValue().GetOffset()); - - - unwind_plan.Clear(); - - wordsize = 8; - EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // Check that we've unwound the stack after the first mid-function epilogue - // row: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize, row_sp->GetCFAValue().GetOffset()); - - // Check that we've reinstated the stack frame setup - // unwind instructions after a jmpq *%eax - // row: CFA=rbp+16 => rsp=CFA+0 rip=[CFA-16] - row_sp = unwind_plan.GetRowForFunctionOffset(18); - EXPECT_EQ(18ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize * 2, row_sp->GetCFAValue().GetOffset()); - - // Check that we've reinstated the stack frame setup - // unwind instructions after a mid-function retq - // row: CFA=rbp+16 => rsp=CFA+0 rip=[CFA-16] - row_sp = unwind_plan.GetRowForFunctionOffset(27); - EXPECT_EQ(27ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize * 2, row_sp->GetCFAValue().GetOffset()); - - // After last instruction in the function, verify that - // the stack frame has been unwound - // row: CFA=rsp +8 => esp=CFA+0 rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(33); - EXPECT_EQ(33ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(wordsize, row_sp->GetCFAValue().GetOffset()); - - -} diff --git a/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp b/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp deleted file mode 100644 index a6dbfd61061..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===-- AnsiTerminalTest.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 "gtest/gtest.h" - -#include "lldb/Utility/AnsiTerminal.h" - -using namespace lldb_private; - -TEST(AnsiTerminal, Empty) { EXPECT_EQ("", ansi::FormatAnsiTerminalCodes("")); } - -TEST(AnsiTerminal, WhiteSpace) { - EXPECT_EQ(" ", ansi::FormatAnsiTerminalCodes(" ")); -} - -TEST(AnsiTerminal, AtEnd) { - EXPECT_EQ("abc\x1B[30m", - ansi::FormatAnsiTerminalCodes("abc${ansi.fg.black}")); -} - -TEST(AnsiTerminal, AtStart) { - EXPECT_EQ("\x1B[30mabc", - ansi::FormatAnsiTerminalCodes("${ansi.fg.black}abc")); -} - -TEST(AnsiTerminal, KnownPrefix) { - EXPECT_EQ("${ansi.fg.redish}abc", - ansi::FormatAnsiTerminalCodes("${ansi.fg.redish}abc")); -} - -TEST(AnsiTerminal, Unknown) { - EXPECT_EQ("${ansi.fg.foo}abc", - ansi::FormatAnsiTerminalCodes("${ansi.fg.foo}abc")); -} - -TEST(AnsiTerminal, Incomplete) { - EXPECT_EQ("abc${ansi.", ansi::FormatAnsiTerminalCodes("abc${ansi.")); -} - -TEST(AnsiTerminal, Twice) { - EXPECT_EQ("\x1B[30m\x1B[31mabc", - ansi::FormatAnsiTerminalCodes("${ansi.fg.black}${ansi.fg.red}abc")); -} - -TEST(AnsiTerminal, Basic) { - EXPECT_EQ( - "abc\x1B[31mabc\x1B[0mabc", - ansi::FormatAnsiTerminalCodes("abc${ansi.fg.red}abc${ansi.normal}abc")); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp b/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp deleted file mode 100644 index 1ef646acdef..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp +++ /dev/null @@ -1,490 +0,0 @@ -//===-- ArchSpecTest.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 "gtest/gtest.h" - -#include "lldb/Utility/ArchSpec.h" -#include "llvm/BinaryFormat/ELF.h" -#include "llvm/BinaryFormat/MachO.h" -#include "llvm/Support/YAMLParser.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleSimple) { - - // Success conditions. Valid cpu/subtype combinations using both - and . - ArchSpec AS; - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(10u, AS.GetMachOCPUSubType()); - - AS = ArchSpec(); - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(15u, AS.GetMachOCPUSubType()); - - AS = ArchSpec(); - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12.15", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(15u, AS.GetMachOCPUSubType()); - - // Failure conditions. - - // Valid string, unknown cpu/subtype. - AS = ArchSpec(); - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("13.11", AS)); - EXPECT_EQ(0u, AS.GetMachOCPUType()); - EXPECT_EQ(0u, AS.GetMachOCPUSubType()); - - // Missing / invalid cpu or subtype - AS = ArchSpec(); - EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13", AS)); - - AS = ArchSpec(); - EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13.A", AS)); - - AS = ArchSpec(); - EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("A.13", AS)); - - // Empty string. - AS = ArchSpec(); - EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("", AS)); -} - -TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleExtra) { - ArchSpec AS; - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor-os", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(15u, AS.GetMachOCPUSubType()); - EXPECT_EQ("vendor", AS.GetTriple().getVendorName()); - EXPECT_EQ("os", AS.GetTriple().getOSName()); - - AS = ArchSpec(); - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor-os-name", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(10u, AS.GetMachOCPUSubType()); - EXPECT_EQ("vendor", AS.GetTriple().getVendorName()); - EXPECT_EQ("os", AS.GetTriple().getOSName()); - - AS = ArchSpec(); - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor.os-name", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(15u, AS.GetMachOCPUSubType()); - EXPECT_EQ("vendor.os", AS.GetTriple().getVendorName()); - EXPECT_EQ("name", AS.GetTriple().getOSName()); - - // These there should parse correctly, but the vendor / OS should be defaulted - // since they are unrecognized. - AS = ArchSpec(); - EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor", AS)); - EXPECT_EQ(12u, AS.GetMachOCPUType()); - EXPECT_EQ(10u, AS.GetMachOCPUSubType()); - EXPECT_EQ("apple", AS.GetTriple().getVendorName()); - EXPECT_EQ("", AS.GetTriple().getOSName()); - - AS = ArchSpec(); - EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12.10.10", AS)); - - AS = ArchSpec(); - EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12-10.10", AS)); -} - -TEST(ArchSpecTest, TestSetTriple) { - ArchSpec AS; - - // Various flavors of valid triples. - EXPECT_TRUE(AS.SetTriple("12-10-apple-darwin")); - EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_ARM), AS.GetMachOCPUType()); - EXPECT_EQ(10u, AS.GetMachOCPUSubType()); - EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str()) - .consume_front("armv7f-apple-darwin")); - EXPECT_EQ(ArchSpec::eCore_arm_armv7f, AS.GetCore()); - - AS = ArchSpec(); - EXPECT_TRUE(AS.SetTriple("18.100-apple-darwin")); - EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_POWERPC), AS.GetMachOCPUType()); - EXPECT_EQ(100u, AS.GetMachOCPUSubType()); - EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str()) - .consume_front("powerpc-apple-darwin")); - EXPECT_EQ(ArchSpec::eCore_ppc_ppc970, AS.GetCore()); - - AS = ArchSpec(); - EXPECT_TRUE(AS.SetTriple("i686-pc-windows")); - EXPECT_EQ(llvm::Triple::x86, AS.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::PC, AS.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::Win32, AS.GetTriple().getOS()); - EXPECT_TRUE( - llvm::StringRef(AS.GetTriple().str()).consume_front("i686-pc-windows")); - EXPECT_STREQ("i686", AS.GetArchitectureName()); - EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore()); - - // Various flavors of invalid triples. - AS = ArchSpec(); - EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown")); - - AS = ArchSpec(); - EXPECT_FALSE(AS.SetTriple("unknown")); - - AS = ArchSpec(); - EXPECT_FALSE(AS.SetTriple("")); -} - -TEST(ArchSpecTest, MergeFrom) { - { - ArchSpec A; - ArchSpec B("x86_64-pc-linux"); - - EXPECT_FALSE(A.IsValid()); - ASSERT_TRUE(B.IsValid()); - EXPECT_EQ(llvm::Triple::ArchType::x86_64, B.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::PC, B.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); - EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, B.GetCore()); - - A.MergeFrom(B); - ASSERT_TRUE(A.IsValid()); - EXPECT_EQ(llvm::Triple::ArchType::x86_64, A.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::PC, A.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); - EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, A.GetCore()); - } - { - ArchSpec A("aarch64"); - ArchSpec B("aarch64--linux-android"); - - ArchSpec C("arm64_32"); - ArchSpec D("arm64_32--watchos"); - - EXPECT_TRUE(A.IsValid()); - EXPECT_TRUE(B.IsValid()); - EXPECT_TRUE(C.IsValid()); - EXPECT_TRUE(D.IsValid()); - - EXPECT_EQ(llvm::Triple::ArchType::aarch64, B.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - B.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); - EXPECT_EQ(llvm::Triple::EnvironmentType::Android, - B.GetTriple().getEnvironment()); - - A.MergeFrom(B); - EXPECT_EQ(llvm::Triple::ArchType::aarch64, A.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - A.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); - EXPECT_EQ(llvm::Triple::EnvironmentType::Android, - A.GetTriple().getEnvironment()); - - EXPECT_EQ(llvm::Triple::ArchType::aarch64_32, D.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - D.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::WatchOS, D.GetTriple().getOS()); - - C.MergeFrom(D); - EXPECT_EQ(llvm::Triple::ArchType::aarch64_32, C.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - C.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::WatchOS, C.GetTriple().getOS()); - } - { - ArchSpec A, B; - A.SetArchitecture(eArchTypeELF, llvm::ELF::EM_ARM, - LLDB_INVALID_CPUTYPE, llvm::ELF::ELFOSABI_NONE); - B.SetArchitecture(eArchTypeELF, llvm::ELF::EM_ARM, - LLDB_INVALID_CPUTYPE, llvm::ELF::ELFOSABI_LINUX); - - EXPECT_TRUE(A.IsValid()); - EXPECT_TRUE(B.IsValid()); - - EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - B.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); - EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment, - B.GetTriple().getEnvironment()); - - A.MergeFrom(B); - EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - A.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); - EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment, - A.GetTriple().getEnvironment()); - } - { - ArchSpec A("arm--linux-eabihf"); - ArchSpec B("armv8l--linux-gnueabihf"); - - EXPECT_TRUE(A.IsValid()); - EXPECT_TRUE(B.IsValid()); - - EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch()); - EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch()); - - EXPECT_EQ(ArchSpec::eCore_arm_generic, A.GetCore()); - EXPECT_EQ(ArchSpec::eCore_arm_armv8l, B.GetCore()); - - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - A.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - B.GetTriple().getVendor()); - - EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); - EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); - - EXPECT_EQ(llvm::Triple::EnvironmentType::EABIHF, - A.GetTriple().getEnvironment()); - EXPECT_EQ(llvm::Triple::EnvironmentType::GNUEABIHF, - B.GetTriple().getEnvironment()); - - A.MergeFrom(B); - EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch()); - EXPECT_EQ(ArchSpec::eCore_arm_armv8l, A.GetCore()); - EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, - A.GetTriple().getVendor()); - EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); - EXPECT_EQ(llvm::Triple::EnvironmentType::EABIHF, - A.GetTriple().getEnvironment()); - } -} - -TEST(ArchSpecTest, MergeFromMachOUnknown) { - class MyArchSpec : public ArchSpec { - public: - MyArchSpec() { - this->SetTriple("unknown-mach-64"); - this->m_core = ArchSpec::eCore_uknownMach64; - this->m_byte_order = eByteOrderLittle; - this->m_flags = 0; - } - }; - - MyArchSpec A; - ASSERT_TRUE(A.IsValid()); - MyArchSpec B; - ASSERT_TRUE(B.IsValid()); - A.MergeFrom(B); - ASSERT_EQ(A.GetCore(), ArchSpec::eCore_uknownMach64); -} - -TEST(ArchSpecTest, Compatibility) { - { - ArchSpec A("x86_64-apple-macosx10.12"); - ArchSpec B("x86_64-apple-macosx10.12"); - ASSERT_TRUE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - } - { - // The version information is auxiliary to support availability but - // doesn't affect compatibility. - ArchSpec A("x86_64-apple-macosx10.11"); - ArchSpec B("x86_64-apple-macosx10.12"); - ASSERT_TRUE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-apple-macosx10.13"); - ArchSpec B("x86_64h-apple-macosx10.13"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-apple-macosx"); - ArchSpec B("x86_64-apple-ios-simulator"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_FALSE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-*-*"); - ArchSpec B("x86_64-apple-ios-simulator"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_FALSE(A.IsCompatibleMatch(B)); - ASSERT_FALSE(B.IsExactMatch(A)); - ASSERT_FALSE(B.IsCompatibleMatch(A)); - } - { - ArchSpec A("x86_64-apple-ios"); - ArchSpec B("x86_64-apple-ios-simulator"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_FALSE(A.IsCompatibleMatch(B)); - ASSERT_FALSE(B.IsExactMatch(A)); - ASSERT_FALSE(B.IsCompatibleMatch(A)); - } - { - // FIXME: This is surprisingly not equivalent to "x86_64-*-*". - ArchSpec A("x86_64"); - ArchSpec B("x86_64-apple-ios-simulator"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - ASSERT_FALSE(B.IsExactMatch(A)); - ASSERT_TRUE(B.IsCompatibleMatch(A)); - } - { - ArchSpec A("arm64-apple-ios"); - ArchSpec B("arm64-apple-ios-simulator"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_FALSE(A.IsCompatibleMatch(B)); - ASSERT_FALSE(B.IsCompatibleMatch(A)); - ASSERT_FALSE(B.IsCompatibleMatch(A)); - } - { - ArchSpec A("arm64-*-*"); - ArchSpec B("arm64-apple-ios"); - ASSERT_FALSE(A.IsExactMatch(B)); - // FIXME: This looks unintuitive and we should investigate whether - // this is the desired behavior. - ASSERT_FALSE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-*-*"); - ArchSpec B("x86_64-apple-ios-simulator"); - ASSERT_FALSE(A.IsExactMatch(B)); - // FIXME: See above, though the extra environment complicates things. - ASSERT_FALSE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64"); - ArchSpec B("x86_64-apple-macosx10.14"); - // FIXME: The exact match also looks unintuitive. - ASSERT_TRUE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64"); - ArchSpec B("x86_64-apple-ios12.0.0-macabi"); - // FIXME: The exact match also looks unintuitive. - ASSERT_TRUE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-apple-ios12.0.0"); - ArchSpec B("x86_64-apple-ios12.0.0-macabi"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_FALSE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-apple-macosx10.14.2"); - ArchSpec B("x86_64-apple-ios12.0.0-macabi"); - ASSERT_FALSE(A.IsExactMatch(B)); - ASSERT_TRUE(A.IsCompatibleMatch(B)); - } - { - ArchSpec A("x86_64-apple-macosx10.14.2"); - ArchSpec B("x86_64-apple-ios12.0.0-macabi"); - // ios-macabi wins. - A.MergeFrom(B); - ASSERT_TRUE(A.IsExactMatch(B)); - } - { - ArchSpec A("x86_64-apple-macosx10.14.2"); - ArchSpec B("x86_64-apple-ios12.0.0-macabi"); - ArchSpec C(B); - // ios-macabi wins. - B.MergeFrom(A); - ASSERT_TRUE(B.IsExactMatch(C)); - } -} - -TEST(ArchSpecTest, OperatorBool) { - EXPECT_FALSE(ArchSpec()); - EXPECT_TRUE(ArchSpec("x86_64-pc-linux")); -} - -TEST(ArchSpecTest, TripleComponentsWereSpecified) { - { - ArchSpec A(""); - ArchSpec B("-"); - ArchSpec C("--"); - ArchSpec D("---"); - - ASSERT_FALSE(A.TripleVendorWasSpecified()); - ASSERT_FALSE(A.TripleOSWasSpecified()); - ASSERT_FALSE(A.TripleEnvironmentWasSpecified()); - - ASSERT_FALSE(B.TripleVendorWasSpecified()); - ASSERT_FALSE(B.TripleOSWasSpecified()); - ASSERT_FALSE(B.TripleEnvironmentWasSpecified()); - - ASSERT_FALSE(C.TripleVendorWasSpecified()); - ASSERT_FALSE(C.TripleOSWasSpecified()); - ASSERT_FALSE(C.TripleEnvironmentWasSpecified()); - - ASSERT_FALSE(D.TripleVendorWasSpecified()); - ASSERT_FALSE(D.TripleOSWasSpecified()); - ASSERT_FALSE(D.TripleEnvironmentWasSpecified()); - } - { - // TODO: llvm::Triple::normalize treats the missing components from these - // triples as specified unknown components instead of unspecified - // components. We need to either change the behavior in llvm or work around - // this in lldb. - ArchSpec A("armv7"); - ArchSpec B("armv7-"); - ArchSpec C("armv7--"); - ArchSpec D("armv7---"); - - ASSERT_FALSE(A.TripleVendorWasSpecified()); - ASSERT_FALSE(A.TripleOSWasSpecified()); - ASSERT_FALSE(A.TripleEnvironmentWasSpecified()); - - ASSERT_TRUE(B.TripleVendorWasSpecified()); - ASSERT_FALSE(B.TripleOSWasSpecified()); - ASSERT_FALSE(B.TripleEnvironmentWasSpecified()); - - ASSERT_TRUE(C.TripleVendorWasSpecified()); - ASSERT_TRUE(C.TripleOSWasSpecified()); - ASSERT_FALSE(C.TripleEnvironmentWasSpecified()); - - ASSERT_TRUE(D.TripleVendorWasSpecified()); - ASSERT_TRUE(D.TripleOSWasSpecified()); - ASSERT_TRUE(D.TripleEnvironmentWasSpecified()); - } - { - ArchSpec A("x86_64-unknown"); - ArchSpec B("powerpc-unknown-linux"); - ArchSpec C("i386-pc-windows-msvc"); - ArchSpec D("aarch64-unknown-linux-android"); - - ASSERT_TRUE(A.TripleVendorWasSpecified()); - ASSERT_FALSE(A.TripleOSWasSpecified()); - ASSERT_FALSE(A.TripleEnvironmentWasSpecified()); - - ASSERT_TRUE(B.TripleVendorWasSpecified()); - ASSERT_TRUE(B.TripleOSWasSpecified()); - ASSERT_FALSE(B.TripleEnvironmentWasSpecified()); - - ASSERT_TRUE(C.TripleVendorWasSpecified()); - ASSERT_TRUE(C.TripleOSWasSpecified()); - ASSERT_TRUE(C.TripleEnvironmentWasSpecified()); - - ASSERT_TRUE(D.TripleVendorWasSpecified()); - ASSERT_TRUE(D.TripleOSWasSpecified()); - ASSERT_TRUE(D.TripleEnvironmentWasSpecified()); - } -} - -TEST(ArchSpecTest, YAML) { - std::string buffer; - llvm::raw_string_ostream os(buffer); - - // Serialize. - llvm::yaml::Output yout(os); - std::vector archs = {ArchSpec("x86_64-pc-linux"), - ArchSpec("x86_64-apple-macosx10.12"), - ArchSpec("i686-pc-windows")}; - yout << archs; - os.flush(); - - // Deserialize. - std::vector deserialized; - llvm::yaml::Input yin(buffer); - yin >> deserialized; - - EXPECT_EQ(archs, deserialized); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp b/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp deleted file mode 100644 index 0b153a8d593..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp +++ /dev/null @@ -1,344 +0,0 @@ -//===-- ArgsTest.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 "gtest/gtest.h" - -#include "lldb/Utility/Args.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/StringList.h" - -#include -#include - -using namespace lldb_private; - -TEST(ArgsTest, TestSingleArg) { - Args args; - args.SetCommandString("arg"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg"); -} - -TEST(ArgsTest, TestSingleQuotedArgWithSpace) { - Args args; - args.SetCommandString("\"arg with space\""); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg with space"); -} - -TEST(ArgsTest, TestSingleArgWithQuotedSpace) { - Args args; - args.SetCommandString("arg\\ with\\ space"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg with space"); -} - -TEST(ArgsTest, TestTrailingBackslash) { - Args args; - args.SetCommandString("arg\\"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\"); -} - -TEST(ArgsTest, TestQuotedTrailingBackslash) { - Args args; - args.SetCommandString("\"arg\\"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\"); -} - -TEST(ArgsTest, TestUnknownEscape) { - Args args; - args.SetCommandString("arg\\y"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\y"); -} - -TEST(ArgsTest, TestQuotedUnknownEscape) { - Args args; - args.SetCommandString("\"arg\\y"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\y"); -} - -TEST(ArgsTest, TestMultipleArgs) { - Args args; - args.SetCommandString("this has multiple args"); - EXPECT_EQ(4u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "this"); - EXPECT_STREQ(args.GetArgumentAtIndex(1), "has"); - EXPECT_STREQ(args.GetArgumentAtIndex(2), "multiple"); - EXPECT_STREQ(args.GetArgumentAtIndex(3), "args"); -} - -TEST(ArgsTest, TestOverwriteArgs) { - Args args; - args.SetCommandString("this has multiple args"); - EXPECT_EQ(4u, args.GetArgumentCount()); - args.SetCommandString("arg"); - EXPECT_EQ(1u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg"); -} - -TEST(ArgsTest, TestAppendArg) { - Args args; - args.SetCommandString("first_arg"); - EXPECT_EQ(1u, args.GetArgumentCount()); - args.AppendArgument(llvm::StringRef("second_arg")); - EXPECT_EQ(2u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "first_arg"); - EXPECT_STREQ(args.GetArgumentAtIndex(1), "second_arg"); -} - -TEST(ArgsTest, TestInsertArg) { - Args args; - args.AppendArgument("1"); - args.AppendArgument("2"); - args.AppendArgument("3"); - args.InsertArgumentAtIndex(1, "1.5"); - args.InsertArgumentAtIndex(4, "3.5"); - - ASSERT_EQ(5u, args.GetArgumentCount()); - EXPECT_STREQ("1", args.GetArgumentAtIndex(0)); - EXPECT_STREQ("1.5", args.GetArgumentAtIndex(1)); - EXPECT_STREQ("2", args.GetArgumentAtIndex(2)); - EXPECT_STREQ("3", args.GetArgumentAtIndex(3)); - EXPECT_STREQ("3.5", args.GetArgumentAtIndex(4)); -} - -TEST(ArgsTest, TestArgv) { - Args args; - EXPECT_EQ(nullptr, args.GetArgumentVector()); - - args.AppendArgument("1"); - EXPECT_NE(nullptr, args.GetArgumentVector()[0]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[1]); - - args.AppendArgument("2"); - EXPECT_NE(nullptr, args.GetArgumentVector()[0]); - EXPECT_NE(nullptr, args.GetArgumentVector()[1]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[2]); - - args.AppendArgument("3"); - EXPECT_NE(nullptr, args.GetArgumentVector()[0]); - EXPECT_NE(nullptr, args.GetArgumentVector()[1]); - EXPECT_NE(nullptr, args.GetArgumentVector()[2]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[3]); - - args.InsertArgumentAtIndex(1, "1.5"); - EXPECT_NE(nullptr, args.GetArgumentVector()[0]); - EXPECT_NE(nullptr, args.GetArgumentVector()[1]); - EXPECT_NE(nullptr, args.GetArgumentVector()[2]); - EXPECT_NE(nullptr, args.GetArgumentVector()[3]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[4]); - - args.InsertArgumentAtIndex(4, "3.5"); - EXPECT_NE(nullptr, args.GetArgumentVector()[0]); - EXPECT_NE(nullptr, args.GetArgumentVector()[1]); - EXPECT_NE(nullptr, args.GetArgumentVector()[2]); - EXPECT_NE(nullptr, args.GetArgumentVector()[3]); - EXPECT_NE(nullptr, args.GetArgumentVector()[4]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[5]); -} - -TEST(ArgsTest, StringListConstructor) { - StringList list; - list << "foo" - << "bar" - << "baz"; - Args args(list); - ASSERT_EQ(3u, args.GetArgumentCount()); - EXPECT_EQ("foo", args[0].ref()); - EXPECT_EQ("bar", args[1].ref()); - EXPECT_EQ("baz", args[2].ref()); -} - -TEST(ArgsTest, GetQuotedCommandString) { - Args args; - const char *str = "process launch -o stdout.txt -- \"a b c\""; - args.SetCommandString(str); - - std::string stdstr; - ASSERT_TRUE(args.GetQuotedCommandString(stdstr)); - EXPECT_EQ(str, stdstr); -} - -TEST(ArgsTest, BareSingleQuote) { - Args args; - args.SetCommandString("a\\'b"); - EXPECT_EQ(1u, args.GetArgumentCount()); - - EXPECT_STREQ("a'b", args.GetArgumentAtIndex(0)); -} - -TEST(ArgsTest, DoubleQuotedItem) { - Args args; - args.SetCommandString("\"a b c\""); - EXPECT_EQ(1u, args.GetArgumentCount()); - - EXPECT_STREQ("a b c", args.GetArgumentAtIndex(0)); -} - -TEST(ArgsTest, AppendArguments) { - Args args; - const char *argv[] = {"1", "2", nullptr}; - const char *argv2[] = {"3", "4", nullptr}; - - args.AppendArguments(argv); - ASSERT_EQ(2u, args.GetArgumentCount()); - EXPECT_STREQ("1", args.GetArgumentVector()[0]); - EXPECT_STREQ("2", args.GetArgumentVector()[1]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[2]); - EXPECT_STREQ("1", args.GetArgumentAtIndex(0)); - EXPECT_STREQ("2", args.GetArgumentAtIndex(1)); - - args.AppendArguments(argv2); - ASSERT_EQ(4u, args.GetArgumentCount()); - EXPECT_STREQ("1", args.GetArgumentVector()[0]); - EXPECT_STREQ("2", args.GetArgumentVector()[1]); - EXPECT_STREQ("3", args.GetArgumentVector()[2]); - EXPECT_STREQ("4", args.GetArgumentVector()[3]); - EXPECT_EQ(nullptr, args.GetArgumentVector()[4]); - EXPECT_STREQ("1", args.GetArgumentAtIndex(0)); - EXPECT_STREQ("2", args.GetArgumentAtIndex(1)); - EXPECT_STREQ("3", args.GetArgumentAtIndex(2)); - EXPECT_STREQ("4", args.GetArgumentAtIndex(3)); -} - -TEST(ArgsTest, GetArgumentArrayRef) { - Args args("foo bar"); - auto ref = args.GetArgumentArrayRef(); - ASSERT_EQ(2u, ref.size()); - EXPECT_STREQ("foo", ref[0]); - EXPECT_STREQ("bar", ref[1]); -} - -TEST(ArgsTest, EscapeLLDBCommandArgument) { - const std::string foo = "foo'"; - EXPECT_EQ("foo\\'", Args::EscapeLLDBCommandArgument(foo, '\0')); - EXPECT_EQ("foo'", Args::EscapeLLDBCommandArgument(foo, '\'')); - EXPECT_EQ("foo'", Args::EscapeLLDBCommandArgument(foo, '`')); - EXPECT_EQ("foo'", Args::EscapeLLDBCommandArgument(foo, '"')); - - const std::string bar = "bar\""; - EXPECT_EQ("bar\\\"", Args::EscapeLLDBCommandArgument(bar, '\0')); - EXPECT_EQ("bar\"", Args::EscapeLLDBCommandArgument(bar, '\'')); - EXPECT_EQ("bar\"", Args::EscapeLLDBCommandArgument(bar, '`')); - EXPECT_EQ("bar\\\"", Args::EscapeLLDBCommandArgument(bar, '"')); - - const std::string baz = "baz`"; - EXPECT_EQ("baz\\`", Args::EscapeLLDBCommandArgument(baz, '\0')); - EXPECT_EQ("baz`", Args::EscapeLLDBCommandArgument(baz, '\'')); - EXPECT_EQ("baz`", Args::EscapeLLDBCommandArgument(baz, '`')); - EXPECT_EQ("baz\\`", Args::EscapeLLDBCommandArgument(baz, '"')); - - const std::string quux = "quux\t"; - EXPECT_EQ("quux\\\t", Args::EscapeLLDBCommandArgument(quux, '\0')); - EXPECT_EQ("quux\t", Args::EscapeLLDBCommandArgument(quux, '\'')); - EXPECT_EQ("quux\t", Args::EscapeLLDBCommandArgument(quux, '`')); - EXPECT_EQ("quux\t", Args::EscapeLLDBCommandArgument(quux, '"')); -} - -TEST(ArgsTest, ReplaceArgumentAtIndexShort) { - Args args; - args.SetCommandString("foo ba b"); - args.ReplaceArgumentAtIndex(0, "f"); - EXPECT_EQ(3u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "f"); -} - -TEST(ArgsTest, ReplaceArgumentAtIndexEqual) { - Args args; - args.SetCommandString("foo ba b"); - args.ReplaceArgumentAtIndex(0, "bar"); - EXPECT_EQ(3u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "bar"); -} - -TEST(ArgsTest, ReplaceArgumentAtIndexLonger) { - Args args; - args.SetCommandString("foo ba b"); - args.ReplaceArgumentAtIndex(0, "baar"); - EXPECT_EQ(3u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(0), "baar"); -} - -TEST(ArgsTest, ReplaceArgumentAtIndexOutOfRange) { - Args args; - args.SetCommandString("foo ba b"); - args.ReplaceArgumentAtIndex(3, "baar"); - EXPECT_EQ(3u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(2), "b"); -} - -TEST(ArgsTest, ReplaceArgumentAtIndexFarOutOfRange) { - Args args; - args.SetCommandString("foo ba b"); - args.ReplaceArgumentAtIndex(4, "baar"); - EXPECT_EQ(3u, args.GetArgumentCount()); - EXPECT_STREQ(args.GetArgumentAtIndex(2), "b"); -} - -TEST(ArgsTest, Yaml) { - std::string buffer; - llvm::raw_string_ostream os(buffer); - - // Serialize. - Args args; - args.SetCommandString("this 'has' \"multiple\" args"); - llvm::yaml::Output yout(os); - yout << args; - os.flush(); - - llvm::outs() << buffer; - - // Deserialize. - Args deserialized; - llvm::yaml::Input yin(buffer); - yin >> deserialized; - - EXPECT_EQ(4u, deserialized.GetArgumentCount()); - EXPECT_STREQ(deserialized.GetArgumentAtIndex(0), "this"); - EXPECT_STREQ(deserialized.GetArgumentAtIndex(1), "has"); - EXPECT_STREQ(deserialized.GetArgumentAtIndex(2), "multiple"); - EXPECT_STREQ(deserialized.GetArgumentAtIndex(3), "args"); - - llvm::ArrayRef entries = deserialized.entries(); - EXPECT_EQ(entries[0].GetQuoteChar(), '\0'); - EXPECT_EQ(entries[1].GetQuoteChar(), '\''); - EXPECT_EQ(entries[2].GetQuoteChar(), '"'); - EXPECT_EQ(entries[3].GetQuoteChar(), '\0'); -} - -TEST(ArgsTest, GetShellSafeArgument) { - // Try escaping with bash at start/middle/end of the argument. - FileSpec bash("/bin/bash", FileSpec::Style::posix); - EXPECT_EQ(Args::GetShellSafeArgument(bash, "\"b"), "\\\"b"); - EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\""), "a\\\""); - EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\"b"), "a\\\"b"); - - FileSpec zsh("/bin/zsh", FileSpec::Style::posix); - EXPECT_EQ(Args::GetShellSafeArgument(zsh, R"('";()<>&|\)"), - R"(\'\"\;\(\)\<\>\&\|\\)"); - // Normal characters and expressions that shouldn't be escaped. - EXPECT_EQ(Args::GetShellSafeArgument(zsh, "aA$1*"), "aA$1*"); - - // String that doesn't need to be escaped - EXPECT_EQ(Args::GetShellSafeArgument(bash, "a"), "a"); - - // Try escaping with tcsh and the tcsh-specific "$" escape. - FileSpec tcsh("/bin/tcsh", FileSpec::Style::posix); - EXPECT_EQ(Args::GetShellSafeArgument(tcsh, "a$b"), "a\\$b"); - // Bash however doesn't need escaping for "$". - EXPECT_EQ(Args::GetShellSafeArgument(bash, "a$b"), "a$b"); - - // Try escaping with an unknown shell. - FileSpec unknown_shell("/bin/unknown_shell", FileSpec::Style::posix); - EXPECT_EQ(Args::GetShellSafeArgument(unknown_shell, "a'b"), "a\\'b"); - EXPECT_EQ(Args::GetShellSafeArgument(unknown_shell, "a\"b"), "a\\\"b"); -} diff --git a/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp b/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp deleted file mode 100644 index 8ff45399893..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp +++ /dev/null @@ -1,74 +0,0 @@ -//===-- BroadcasterTest.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 "gtest/gtest.h" - -#include "lldb/Utility/Broadcaster.h" -#include "lldb/Utility/Event.h" -#include "lldb/Utility/Listener.h" -#include "lldb/Utility/Predicate.h" - -#include - -using namespace lldb; -using namespace lldb_private; - -TEST(BroadcasterTest, BroadcastEvent) { - EventSP event_sp; - Broadcaster broadcaster(nullptr, "test-broadcaster"); - std::chrono::seconds timeout(0); - - // Create a listener, sign it up, make sure it receives an event. - ListenerSP listener1_sp = Listener::MakeListener("test-listener1"); - const uint32_t event_mask1 = 1; - EXPECT_EQ(event_mask1, - listener1_sp->StartListeningForEvents(&broadcaster, event_mask1)); - broadcaster.BroadcastEvent(event_mask1, nullptr); - EXPECT_TRUE(listener1_sp->GetEvent(event_sp, timeout)); - EXPECT_EQ(event_mask1, event_sp->GetType()); - - { - // Add one more listener, make sure it works as well. - ListenerSP listener2_sp = Listener::MakeListener("test-listener2"); - const uint32_t event_mask2 = 1; - EXPECT_EQ(event_mask2, listener2_sp->StartListeningForEvents( - &broadcaster, event_mask1 | event_mask2)); - broadcaster.BroadcastEvent(event_mask2, nullptr); - EXPECT_TRUE(listener2_sp->GetEvent(event_sp, timeout)); - EXPECT_EQ(event_mask2, event_sp->GetType()); - - // Both listeners should get this event. - broadcaster.BroadcastEvent(event_mask1, nullptr); - EXPECT_TRUE(listener1_sp->GetEvent(event_sp, timeout)); - EXPECT_EQ(event_mask1, event_sp->GetType()); - EXPECT_TRUE(listener2_sp->GetEvent(event_sp, timeout)); - EXPECT_EQ(event_mask2, event_sp->GetType()); - } - - // Now again only one listener should be active. - broadcaster.BroadcastEvent(event_mask1, nullptr); - EXPECT_TRUE(listener1_sp->GetEvent(event_sp, timeout)); - EXPECT_EQ(event_mask1, event_sp->GetType()); -} - -TEST(BroadcasterTest, EventTypeHasListeners) { - EventSP event_sp; - Broadcaster broadcaster(nullptr, "test-broadcaster"); - - const uint32_t event_mask = 1; - EXPECT_FALSE(broadcaster.EventTypeHasListeners(event_mask)); - - { - ListenerSP listener_sp = Listener::MakeListener("test-listener"); - EXPECT_EQ(event_mask, - listener_sp->StartListeningForEvents(&broadcaster, event_mask)); - EXPECT_TRUE(broadcaster.EventTypeHasListeners(event_mask)); - } - - EXPECT_FALSE(broadcaster.EventTypeHasListeners(event_mask)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt b/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt deleted file mode 100644 index 3dd910412e6..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -add_lldb_unittest(UtilityTests - AnsiTerminalTest.cpp - ArgsTest.cpp - OptionsWithRawTest.cpp - ArchSpecTest.cpp - BroadcasterTest.cpp - ConstStringTest.cpp - CompletionRequestTest.cpp - DataExtractorTest.cpp - EnvironmentTest.cpp - EventTest.cpp - FileSpecTest.cpp - FlagsTest.cpp - ListenerTest.cpp - LogTest.cpp - NameMatchesTest.cpp - PredicateTest.cpp - ProcessInfoTest.cpp - ProcessInstanceInfoTest.cpp - RangeMapTest.cpp - RangeTest.cpp - RegisterValueTest.cpp - RegularExpressionTest.cpp - ReproducerInstrumentationTest.cpp - ReproducerTest.cpp - ScalarTest.cpp - SharedClusterTest.cpp - StateTest.cpp - StatusTest.cpp - StreamTeeTest.cpp - StreamTest.cpp - StringExtractorGDBRemoteTest.cpp - StringExtractorTest.cpp - StringLexerTest.cpp - StringListTest.cpp - StructuredDataTest.cpp - SubsystemRAIITest.cpp - TildeExpressionResolverTest.cpp - TimeoutTest.cpp - TimerTest.cpp - UriParserTest.cpp - UserIDResolverTest.cpp - UUIDTest.cpp - VASprintfTest.cpp - VMRangeTest.cpp - XcodeSDKTest.cpp - - LINK_LIBS - lldbUtility - lldbUtilityHelpers - LLVMTestingSupport - LINK_COMPONENTS - Support - ) - -add_unittest_inputs(UtilityTests - StructuredData-basic.json - ) diff --git a/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp b/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp deleted file mode 100644 index 02a5f5366a4..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp +++ /dev/null @@ -1,276 +0,0 @@ -//===-- CompletionRequestTest.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 "gtest/gtest.h" - -#include "lldb/Utility/CompletionRequest.h" -using namespace lldb_private; - -TEST(CompletionRequest, Constructor) { - std::string command = "a bad c"; - const unsigned cursor_pos = 3; - const size_t arg_index = 1; - StringList matches; - CompletionResult result; - - CompletionRequest request(command, cursor_pos, result); - result.GetMatches(matches); - - EXPECT_EQ(request.GetRawLine(), "a b"); - EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); - EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); - EXPECT_EQ(request.GetCursorIndex(), arg_index); - - EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 2u); - EXPECT_EQ(request.GetCursorArgumentPrefix().str(), "b"); -} - -TEST(CompletionRequest, FakeLastArg) { - // We insert an empty fake argument into the argument list when the - // cursor is after a space. - std::string command = "a bad c "; - const unsigned cursor_pos = command.size(); - CompletionResult result; - - CompletionRequest request(command, cursor_pos, result); - - EXPECT_EQ(request.GetRawLine(), command); - EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); - EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); - EXPECT_EQ(request.GetCursorIndex(), 3U); - - EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 4U); - EXPECT_EQ(request.GetCursorArgumentPrefix().str(), ""); -} - -TEST(CompletionRequest, TryCompleteCurrentArgGood) { - std::string command = "a bad c"; - StringList matches, descriptions; - CompletionResult result; - - CompletionRequest request(command, 3, result); - request.TryCompleteCurrentArg("boo", "car"); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(1U, result.GetResults().size()); - EXPECT_STREQ("boo", matches.GetStringAtIndex(0U)); - EXPECT_EQ(1U, descriptions.GetSize()); - EXPECT_STREQ("car", descriptions.GetStringAtIndex(0U)); -} - -TEST(CompletionRequest, TryCompleteCurrentArgBad) { - std::string command = "a bad c"; - CompletionResult result; - - CompletionRequest request(command, 3, result); - request.TryCompleteCurrentArg("car", "card"); - - EXPECT_EQ(0U, result.GetResults().size()); -} - -TEST(CompletionRequest, TryCompleteCurrentArgMode) { - std::string command = "a bad c"; - CompletionResult result; - - CompletionRequest request(command, 3, result); - request.TryCompleteCurrentArg("bar", "bard"); - - EXPECT_EQ(1U, result.GetResults().size()); - EXPECT_EQ(CompletionMode::Partial, result.GetResults()[0].GetMode()); -} - -TEST(CompletionRequest, ShiftArguments) { - std::string command = "a bad c"; - const unsigned cursor_pos = 3; - const size_t arg_index = 1; - StringList matches; - CompletionResult result; - - CompletionRequest request(command, cursor_pos, result); - result.GetMatches(matches); - - EXPECT_EQ(request.GetRawLine(), "a b"); - EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); - EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); - EXPECT_EQ(request.GetCursorIndex(), arg_index); - - EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 2u); - EXPECT_STREQ(request.GetParsedLine().GetArgumentAtIndex(1), "b"); - - // Shift away the 'a' argument. - request.ShiftArguments(); - - // The raw line/cursor stays identical. - EXPECT_EQ(request.GetRawLine(), "a b"); - EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); - EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); - - // Partially parsed line and cursor should be updated. - EXPECT_EQ(request.GetCursorIndex(), arg_index - 1U); - EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 1u); - EXPECT_EQ(request.GetCursorArgumentPrefix().str(), "b"); -} - -TEST(CompletionRequest, DuplicateFiltering) { - std::string command = "a bad c"; - const unsigned cursor_pos = 3; - StringList matches; - - CompletionResult result; - CompletionRequest request(command, cursor_pos, result); - result.GetMatches(matches); - - EXPECT_EQ(0U, result.GetNumberOfResults()); - - // Add foo twice - request.AddCompletion("foo"); - result.GetMatches(matches); - - EXPECT_EQ(1U, result.GetNumberOfResults()); - EXPECT_EQ(1U, matches.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - - request.AddCompletion("foo"); - result.GetMatches(matches); - - EXPECT_EQ(1U, result.GetNumberOfResults()); - EXPECT_EQ(1U, matches.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - - // Add bar twice - request.AddCompletion("bar"); - result.GetMatches(matches); - - EXPECT_EQ(2U, result.GetNumberOfResults()); - EXPECT_EQ(2U, matches.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - - request.AddCompletion("bar"); - result.GetMatches(matches); - - EXPECT_EQ(2U, result.GetNumberOfResults()); - EXPECT_EQ(2U, matches.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - - // Add foo again. - request.AddCompletion("foo"); - result.GetMatches(matches); - - EXPECT_EQ(2U, result.GetNumberOfResults()); - EXPECT_EQ(2U, matches.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - - // Add something with an existing prefix - request.AddCompletion("foobar"); - result.GetMatches(matches); - - EXPECT_EQ(3U, result.GetNumberOfResults()); - EXPECT_EQ(3U, matches.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - EXPECT_STREQ("foobar", matches.GetStringAtIndex(2)); -} - -TEST(CompletionRequest, DuplicateFilteringWithComments) { - std::string command = "a bad c"; - const unsigned cursor_pos = 3; - StringList matches, descriptions; - - CompletionResult result; - CompletionRequest request(command, cursor_pos, result); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(0U, result.GetNumberOfResults()); - - // Add foo twice with same comment - request.AddCompletion("foo", "comment"); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(1U, result.GetNumberOfResults()); - EXPECT_EQ(1U, matches.GetSize()); - EXPECT_EQ(1U, descriptions.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0)); - - request.AddCompletion("foo", "comment"); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(1U, result.GetNumberOfResults()); - EXPECT_EQ(1U, matches.GetSize()); - EXPECT_EQ(1U, descriptions.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0)); - - // Add bar twice with different comments - request.AddCompletion("bar", "comment"); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(2U, result.GetNumberOfResults()); - EXPECT_EQ(2U, matches.GetSize()); - EXPECT_EQ(2U, descriptions.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - - request.AddCompletion("bar", "another comment"); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(3U, result.GetNumberOfResults()); - EXPECT_EQ(3U, matches.GetSize()); - EXPECT_EQ(3U, descriptions.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - EXPECT_STREQ("comment", descriptions.GetStringAtIndex(1)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(2)); - EXPECT_STREQ("another comment", descriptions.GetStringAtIndex(2)); - - // Add foo again with no comment - request.AddCompletion("foo"); - result.GetMatches(matches); - result.GetDescriptions(descriptions); - - EXPECT_EQ(4U, result.GetNumberOfResults()); - EXPECT_EQ(4U, matches.GetSize()); - EXPECT_EQ(4U, descriptions.GetSize()); - EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); - EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); - EXPECT_STREQ("comment", descriptions.GetStringAtIndex(1)); - EXPECT_STREQ("bar", matches.GetStringAtIndex(2)); - EXPECT_STREQ("another comment", descriptions.GetStringAtIndex(2)); - EXPECT_STREQ("foo", matches.GetStringAtIndex(3)); - EXPECT_STREQ("", descriptions.GetStringAtIndex(3)); -} - -TEST(CompletionRequest, TestCompletionOwnership) { - std::string command = "a bad c"; - const unsigned cursor_pos = 3; - StringList matches; - - CompletionResult result; - CompletionRequest request(command, cursor_pos, result); - - std::string Temporary = "bar"; - request.AddCompletion(Temporary); - // Manipulate our completion. The request should have taken a copy, so that - // shouldn't influence anything. - Temporary[0] = 'f'; - - result.GetMatches(matches); - EXPECT_EQ(1U, result.GetNumberOfResults()); - EXPECT_STREQ("bar", matches.GetStringAtIndex(0)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp b/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp deleted file mode 100644 index 96624b39130..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//===-- ConstStringTest.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 "lldb/Utility/ConstString.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/YAMLParser.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(ConstStringTest, format_provider) { - EXPECT_EQ("foo", llvm::formatv("{0}", ConstString("foo")).str()); -} - -TEST(ConstStringTest, MangledCounterpart) { - ConstString uvw("uvw"); - ConstString counterpart; - EXPECT_FALSE(uvw.GetMangledCounterpart(counterpart)); - EXPECT_EQ("", counterpart.GetStringRef()); - - ConstString xyz; - xyz.SetStringWithMangledCounterpart("xyz", uvw); - EXPECT_EQ("xyz", xyz.GetStringRef()); - - EXPECT_TRUE(xyz.GetMangledCounterpart(counterpart)); - EXPECT_EQ("uvw", counterpart.GetStringRef()); - - EXPECT_TRUE(uvw.GetMangledCounterpart(counterpart)); - EXPECT_EQ("xyz", counterpart.GetStringRef()); -} - -TEST(ConstStringTest, UpdateMangledCounterpart) { - { // Add counterpart - ConstString some1; - some1.SetStringWithMangledCounterpart("some", ConstString("")); - } - { // Overwrite empty string - ConstString some2; - some2.SetStringWithMangledCounterpart("some", ConstString("one")); - } - { // Overwrite with identical value - ConstString some2; - some2.SetStringWithMangledCounterpart("some", ConstString("one")); - } - { // Check counterpart is set - ConstString counterpart; - EXPECT_TRUE(ConstString("some").GetMangledCounterpart(counterpart)); - EXPECT_EQ("one", counterpart.GetStringRef()); - } -} - -TEST(ConstStringTest, FromMidOfBufferStringRef) { - // StringRef's into bigger buffer: no null termination - const char *buffer = "abcdefghi"; - llvm::StringRef foo_ref(buffer, 3); - llvm::StringRef bar_ref(buffer + 3, 3); - - ConstString foo(foo_ref); - - ConstString bar; - bar.SetStringWithMangledCounterpart(bar_ref, foo); - EXPECT_EQ("def", bar.GetStringRef()); - - ConstString counterpart; - EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); - EXPECT_EQ("abc", counterpart.GetStringRef()); - - EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); - EXPECT_EQ("def", counterpart.GetStringRef()); -} - -TEST(ConstStringTest, NullAndEmptyStates) { - ConstString foo("foo"); - EXPECT_FALSE(!foo); - EXPECT_FALSE(foo.IsEmpty()); - EXPECT_FALSE(foo.IsNull()); - - ConstString empty(""); - EXPECT_TRUE(!empty); - EXPECT_TRUE(empty.IsEmpty()); - EXPECT_FALSE(empty.IsNull()); - - ConstString null; - EXPECT_TRUE(!null); - EXPECT_TRUE(null.IsEmpty()); - EXPECT_TRUE(null.IsNull()); -} - -TEST(ConstStringTest, CompareConstString) { - ConstString foo("foo"); - ConstString foo2("foo"); - ConstString bar("bar"); - - EXPECT_TRUE(foo == foo2); - EXPECT_TRUE(foo2 == foo); - EXPECT_TRUE(foo == ConstString("foo")); - - EXPECT_FALSE(foo == bar); - EXPECT_FALSE(foo2 == bar); - EXPECT_FALSE(foo == ConstString("bar")); - EXPECT_FALSE(foo == ConstString("different")); - EXPECT_FALSE(foo == ConstString("")); - EXPECT_FALSE(foo == ConstString()); - - ConstString empty(""); - EXPECT_FALSE(empty == ConstString("bar")); - EXPECT_FALSE(empty == ConstString()); - EXPECT_TRUE(empty == ConstString("")); - - ConstString null; - EXPECT_FALSE(null == ConstString("bar")); - EXPECT_TRUE(null == ConstString()); - EXPECT_FALSE(null == ConstString("")); -} - -TEST(ConstStringTest, CompareStringRef) { - ConstString foo("foo"); - - EXPECT_TRUE(foo == "foo"); - EXPECT_TRUE(foo != ""); - EXPECT_FALSE(foo == static_cast(nullptr)); - EXPECT_TRUE(foo != "bar"); - - ConstString empty(""); - EXPECT_FALSE(empty == "foo"); - EXPECT_FALSE(empty != ""); - EXPECT_FALSE(empty == static_cast(nullptr)); - EXPECT_TRUE(empty != "bar"); - - ConstString null; - EXPECT_FALSE(null == "foo"); - EXPECT_TRUE(null != ""); - EXPECT_TRUE(null == static_cast(nullptr)); - EXPECT_TRUE(null != "bar"); -} - -TEST(ConstStringTest, YAML) { - std::string buffer; - llvm::raw_string_ostream os(buffer); - - // Serialize. - std::vector strings = {ConstString("foo"), ConstString("bar"), - ConstString("")}; - llvm::yaml::Output yout(os); - yout << strings; - os.flush(); - - // Deserialize. - std::vector deserialized; - llvm::yaml::Input yin(buffer); - yin >> deserialized; - - EXPECT_EQ(strings, deserialized); -} diff --git a/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp b/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp deleted file mode 100644 index 536e69755d1..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp +++ /dev/null @@ -1,403 +0,0 @@ -//===-- DataExtractorTest.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 "gtest/gtest.h" - -#include "lldb/Utility/DataExtractor.h" - -using namespace lldb_private; - -TEST(DataExtractorTest, GetBitfield) { - uint8_t buffer[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - offset = 0; - ASSERT_EQ(buffer[1], LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8)); - offset = 0; - ASSERT_EQ(buffer[1], BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8)); - offset = 0; - ASSERT_EQ(static_cast(0xEFCDAB8967452301), - LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 64, 0)); - offset = 0; - ASSERT_EQ(static_cast(0x0123456789ABCDEF), - BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 64, 0)); - offset = 0; - ASSERT_EQ(static_cast(0x01234567), - BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 32, 0)); - offset = 0; - ASSERT_EQ(static_cast(0x012345678), - BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 36, 0)); - - offset = 0; - ASSERT_EQ(int8_t(buffer[1]), - LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8)); - offset = 0; - ASSERT_EQ(int8_t(buffer[1]), - BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8)); - offset = 0; - ASSERT_EQ(static_cast(0xEFCDAB8967452301), - LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 64, 0)); - offset = 0; - ASSERT_EQ(static_cast(0x0123456789ABCDEF), - BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 64, 0)); -} - -TEST(DataExtractorTest, PeekData) { - uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04}; - DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4); - - EXPECT_EQ(buffer + 0, E.PeekData(0, 0)); - EXPECT_EQ(buffer + 0, E.PeekData(0, 4)); - EXPECT_EQ(nullptr, E.PeekData(0, 5)); - - EXPECT_EQ(buffer + 2, E.PeekData(2, 0)); - EXPECT_EQ(buffer + 2, E.PeekData(2, 2)); - EXPECT_EQ(nullptr, E.PeekData(2, 3)); - - EXPECT_EQ(buffer + 4, E.PeekData(4, 0)); - EXPECT_EQ(nullptr, E.PeekData(4, 1)); -} - -TEST(DataExtractorTest, GetCStr) { - uint8_t buffer[] = {'X', 'f', 'o', 'o', '\0'}; - DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4); - - lldb::offset_t offset = 1; - EXPECT_STREQ("foo", E.GetCStr(&offset)); - EXPECT_EQ(5U, offset); -} - -TEST(DataExtractorTest, GetCStrEmpty) { - uint8_t buffer[] = {'X', '\0'}; - DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4); - - lldb::offset_t offset = 1; - EXPECT_STREQ("", E.GetCStr(&offset)); - EXPECT_EQ(2U, offset); -} - -TEST(DataExtractorTest, GetCStrUnterminated) { - uint8_t buffer[] = {'X', 'f', 'o', 'o'}; - DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4); - - lldb::offset_t offset = 1; - EXPECT_EQ(nullptr, E.GetCStr(&offset)); - EXPECT_EQ(1U, offset); -} - -TEST(DataExtractorTest, GetCStrAtEnd) { - uint8_t buffer[] = {'X'}; - DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4); - - lldb::offset_t offset = 1; - EXPECT_EQ(nullptr, E.GetCStr(&offset)); - EXPECT_EQ(1U, offset); -} - -TEST(DataExtractorTest, GetCStrAtNullOffset) { - uint8_t buffer[] = {'f', 'o', 'o', '\0'}; - DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4); - - lldb::offset_t offset = 0; - EXPECT_STREQ("foo", E.GetCStr(&offset)); - EXPECT_EQ(4U, offset); -} - -TEST(DataExtractorTest, UncommonAddressSize) { - uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor E2(buffer, sizeof buffer, lldb::eByteOrderLittle, 2); - DataExtractor E5(buffer, sizeof buffer, lldb::eByteOrderLittle, 5); - DataExtractor E7(buffer, sizeof buffer, lldb::eByteOrderLittle, 7); - - lldb::offset_t offset; - - // Test 2-byte addresses (for AVR). - offset = 0; - EXPECT_EQ(0x0201U, E2.GetMaxU64(&offset, 2)); - EXPECT_EQ(2U, offset); - offset = 0; - EXPECT_EQ(0x0201U, E2.GetAddress(&offset)); - EXPECT_EQ(2U, offset); - - // Test 5-byte addresses. - offset = 0; - EXPECT_EQ(0x030201U, E5.GetMaxU64(&offset, 3)); - EXPECT_EQ(3U, offset); - offset = 3; - EXPECT_EQ(0x0807060504U, E5.GetAddress(&offset)); - EXPECT_EQ(8U, offset); - - // Test 7-byte addresses. - offset = 0; - EXPECT_EQ(0x0504030201U, E7.GetMaxU64(&offset, 5)); - EXPECT_EQ(5U, offset); - offset = 0; - EXPECT_EQ(0x07060504030201U, E7.GetAddress(&offset)); - EXPECT_EQ(7U, offset); -} - -TEST(DataExtractorTest, GetMaxU64) { - uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - // Check with the minimum allowed byte size. - offset = 0; - EXPECT_EQ(0x01U, LE.GetMaxU64(&offset, 1)); - EXPECT_EQ(1U, offset); - offset = 0; - EXPECT_EQ(0x01U, BE.GetMaxU64(&offset, 1)); - EXPECT_EQ(1U, offset); - - // Check with a non-zero offset. - offset = 1; - EXPECT_EQ(0x0302U, LE.GetMaxU64(&offset, 2)); - EXPECT_EQ(3U, offset); - offset = 1; - EXPECT_EQ(0x0203U, BE.GetMaxU64(&offset, 2)); - EXPECT_EQ(3U, offset); - - // Check with the byte size not being a multiple of 2. - offset = 0; - EXPECT_EQ(0x07060504030201U, LE.GetMaxU64(&offset, 7)); - EXPECT_EQ(7U, offset); - offset = 0; - EXPECT_EQ(0x01020304050607U, BE.GetMaxU64(&offset, 7)); - EXPECT_EQ(7U, offset); - - // Check with the maximum allowed byte size. - offset = 0; - EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64(&offset, 8)); - EXPECT_EQ(8U, offset); - offset = 0; - EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64(&offset, 8)); - EXPECT_EQ(8U, offset); -} - -TEST(DataExtractorTest, GetMaxS64) { - uint8_t buffer[] = {0x01, 0x02, 0x83, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - // Check with the minimum allowed byte size. - offset = 0; - EXPECT_EQ(0x01, LE.GetMaxS64(&offset, 1)); - EXPECT_EQ(1U, offset); - offset = 0; - EXPECT_EQ(0x01, BE.GetMaxS64(&offset, 1)); - EXPECT_EQ(1U, offset); - - // Check that sign extension works correctly. - offset = 0; - int64_t value = LE.GetMaxS64(&offset, 3); - EXPECT_EQ(0xffffffffff830201U, *reinterpret_cast(&value)); - EXPECT_EQ(3U, offset); - offset = 2; - value = BE.GetMaxS64(&offset, 3); - EXPECT_EQ(0xffffffffff830405U, *reinterpret_cast(&value)); - EXPECT_EQ(5U, offset); - - // Check with the maximum allowed byte size. - offset = 0; - EXPECT_EQ(0x0807060504830201, LE.GetMaxS64(&offset, 8)); - EXPECT_EQ(8U, offset); - offset = 0; - EXPECT_EQ(0x0102830405060708, BE.GetMaxS64(&offset, 8)); - EXPECT_EQ(8U, offset); -} - -TEST(DataExtractorTest, GetMaxU64_unchecked) { - uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - // Check with the minimum allowed byte size. - offset = 0; - EXPECT_EQ(0x01U, LE.GetMaxU64_unchecked(&offset, 1)); - EXPECT_EQ(1U, offset); - offset = 0; - EXPECT_EQ(0x01U, BE.GetMaxU64_unchecked(&offset, 1)); - EXPECT_EQ(1U, offset); - - // Check with a non-zero offset. - offset = 1; - EXPECT_EQ(0x0302U, LE.GetMaxU64_unchecked(&offset, 2)); - EXPECT_EQ(3U, offset); - offset = 1; - EXPECT_EQ(0x0203U, BE.GetMaxU64_unchecked(&offset, 2)); - EXPECT_EQ(3U, offset); - - // Check with the byte size not being a multiple of 2. - offset = 0; - EXPECT_EQ(0x07060504030201U, LE.GetMaxU64_unchecked(&offset, 7)); - EXPECT_EQ(7U, offset); - offset = 0; - EXPECT_EQ(0x01020304050607U, BE.GetMaxU64_unchecked(&offset, 7)); - EXPECT_EQ(7U, offset); - - // Check with the maximum allowed byte size. - offset = 0; - EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64_unchecked(&offset, 8)); - EXPECT_EQ(8U, offset); - offset = 0; - EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64_unchecked(&offset, 8)); - EXPECT_EQ(8U, offset); -} - -TEST(DataExtractorTest, GetSLEB128_bit63) { - uint8_t buffer[] = {0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x7f}; - - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - int64_t expected = - 0b1111111100000001111111000000011111110000000111111100000001111111; - offset = 0; - EXPECT_EQ(expected, LE.GetSLEB128(&offset)); - EXPECT_EQ(9U, offset); - offset = 0; - EXPECT_EQ(expected, BE.GetSLEB128(&offset)); - EXPECT_EQ(9U, offset); -} - -TEST(DataExtractorTest, GetULEB128_bit63) { - uint8_t buffer[] = {0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x7f}; - - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - uint64_t expected = - 0b0111111100000001111111000000011111110000000111111100000001111111; - offset = 0; - EXPECT_EQ(expected, LE.GetULEB128(&offset)); - EXPECT_EQ(9U, offset); - offset = 0; - EXPECT_EQ(expected, BE.GetULEB128(&offset)); - EXPECT_EQ(9U, offset); -} - -TEST(DataExtractorTest, GetFloat) { - float expected = 4.0f; - lldb::offset_t offset; - - { - uint8_t buffer[] = {0x00, 0x00, 0x80, 0x40}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - - offset = 0; - EXPECT_DOUBLE_EQ(expected, LE.GetFloat(&offset)); - EXPECT_EQ(4U, offset); - } - - { - uint8_t buffer[] = {0x40, 0x80, 0x00, 0x00}; - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, - sizeof(void *)); - offset = 0; - EXPECT_DOUBLE_EQ(expected, BE.GetFloat(&offset)); - EXPECT_EQ(4U, offset); - } -} - -TEST(DataExtractorTest, GetFloatUnaligned) { - float expected = 4.0f; - lldb::offset_t offset; - - { - uint8_t buffer[] = {0x00, 0x00, 0x00, 0x80, 0x40}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - - offset = 1; - EXPECT_DOUBLE_EQ(expected, LE.GetFloat(&offset)); - EXPECT_EQ(5U, offset); - } - - { - uint8_t buffer[] = {0x00, 0x40, 0x80, 0x00, 0x00}; - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, - sizeof(void *)); - offset = 1; - EXPECT_DOUBLE_EQ(expected, BE.GetFloat(&offset)); - EXPECT_EQ(5U, offset); - } -} - -TEST(DataExtractorTest, GetDouble) { - if (sizeof(double) != 8) - return; - - double expected = 4.0f; - lldb::offset_t offset; - - { - uint8_t buffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - - offset = 0; - EXPECT_DOUBLE_EQ(expected, LE.GetDouble(&offset)); - EXPECT_EQ(8U, offset); - } - - { - uint8_t buffer[] = {0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, - sizeof(void *)); - offset = 0; - EXPECT_DOUBLE_EQ(expected, BE.GetDouble(&offset)); - EXPECT_EQ(8U, offset); - } -} - -TEST(DataExtractorTest, GetDoubleUnaligned) { - if (sizeof(double) != 8) - return; - - float expected = 4.0f; - lldb::offset_t offset; - - { - uint8_t buffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - - offset = 1; - EXPECT_DOUBLE_EQ(expected, LE.GetDouble(&offset)); - EXPECT_EQ(9U, offset); - } - - { - uint8_t buffer[] = {0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, - sizeof(void *)); - offset = 1; - EXPECT_DOUBLE_EQ(expected, BE.GetDouble(&offset)); - EXPECT_EQ(9U, offset); - } -} diff --git a/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp b/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp deleted file mode 100644 index bbc9b124564..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===-- EnvironmentTest.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 "gtest/gtest.h" - -#include "lldb/Utility/Environment.h" - -using namespace lldb_private; - -TEST(EnvironmentTest, EnvpConstruction) { - const char **Envp1 = nullptr; - EXPECT_EQ(0u, Environment(Envp1).size()); - - const char *Envp2[] = {"FOO=BAR", nullptr}; - EXPECT_EQ("BAR", Environment(Envp2).lookup("FOO")); - - const char *Envp3[] = {"FOO=BAR", "FOO=BAZ", nullptr}; - EXPECT_EQ("BAR", Environment(Envp3).lookup("FOO")); - - const char *Envp4[] = {"FOO=", "BAR", nullptr}; - Environment Env4(Envp4); - ASSERT_EQ(2u, Env4.size()); - EXPECT_EQ("", Environment(Envp4).find("FOO")->second); - EXPECT_EQ("", Environment(Envp4).find("BAR")->second); - - const char *Envp5[] = {"FOO=BAR=BAZ", nullptr}; - EXPECT_EQ("BAR=BAZ", Environment(Envp5).lookup("FOO")); -} - -TEST(EnvironmentTest, EnvpConversion) { - std::string FOO_EQ_BAR("FOO=BAR"); - std::string BAR_EQ_BAZ("BAR=BAZ"); - - Environment Env; - Env.insert(FOO_EQ_BAR); - Env.insert(BAR_EQ_BAZ); - Environment::Envp Envp = Env.getEnvp(); - const char *const *Envp_ = Envp; - - EXPECT_TRUE(FOO_EQ_BAR == Envp_[0] || FOO_EQ_BAR == Envp_[1]); - EXPECT_TRUE(BAR_EQ_BAZ == Envp_[0] || BAR_EQ_BAZ == Envp_[1]); - EXPECT_EQ(nullptr, Envp_[2]); -} diff --git a/gnu/llvm/lldb/unittests/Utility/EventTest.cpp b/gnu/llvm/lldb/unittests/Utility/EventTest.cpp deleted file mode 100644 index 5f8f2b5ec89..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/EventTest.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//===-- EventTest.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 "lldb/Utility/Event.h" -#include "lldb/Utility/StreamString.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -static std::string to_string(const EventDataBytes &E) { - StreamString S; - E.Dump(&S); - return std::string(S.GetString()); -} - -TEST(EventTest, DumpEventDataBytes) { - EXPECT_EQ(R"("foo")", to_string(EventDataBytes("foo"))); - EXPECT_EQ("01 02 03", to_string(EventDataBytes("\x01\x02\x03"))); -} diff --git a/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp b/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp deleted file mode 100644 index 3dd355284ce..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp +++ /dev/null @@ -1,447 +0,0 @@ -//===-- FileSpecTest.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 "gtest/gtest.h" - -#include "lldb/Utility/FileSpec.h" - -using namespace lldb_private; - -static FileSpec PosixSpec(llvm::StringRef path) { - return FileSpec(path, FileSpec::Style::posix); -} - -static FileSpec WindowsSpec(llvm::StringRef path) { - return FileSpec(path, FileSpec::Style::windows); -} - -TEST(FileSpecTest, FileAndDirectoryComponents) { - FileSpec fs_posix("/foo/bar", FileSpec::Style::posix); - EXPECT_STREQ("/foo/bar", fs_posix.GetCString()); - EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString()); - EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString()); - - FileSpec fs_windows("F:\\bar", FileSpec::Style::windows); - EXPECT_STREQ("F:\\bar", fs_windows.GetCString()); - // EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetCString()); // It returns - // "F:/" - EXPECT_STREQ("bar", fs_windows.GetFilename().GetCString()); - - FileSpec fs_posix_root("/", FileSpec::Style::posix); - EXPECT_STREQ("/", fs_posix_root.GetCString()); - EXPECT_EQ(nullptr, fs_posix_root.GetDirectory().GetCString()); - EXPECT_STREQ("/", fs_posix_root.GetFilename().GetCString()); - - FileSpec fs_net_drive("//net", FileSpec::Style::posix); - EXPECT_STREQ("//net", fs_net_drive.GetCString()); - EXPECT_EQ(nullptr, fs_net_drive.GetDirectory().GetCString()); - EXPECT_STREQ("//net", fs_net_drive.GetFilename().GetCString()); - - FileSpec fs_net_root("//net/", FileSpec::Style::posix); - EXPECT_STREQ("//net/", fs_net_root.GetCString()); - EXPECT_STREQ("//net", fs_net_root.GetDirectory().GetCString()); - EXPECT_STREQ("/", fs_net_root.GetFilename().GetCString()); - - FileSpec fs_windows_drive("F:", FileSpec::Style::windows); - EXPECT_STREQ("F:", fs_windows_drive.GetCString()); - EXPECT_EQ(nullptr, fs_windows_drive.GetDirectory().GetCString()); - EXPECT_STREQ("F:", fs_windows_drive.GetFilename().GetCString()); - - FileSpec fs_windows_root("F:\\", FileSpec::Style::windows); - EXPECT_STREQ("F:\\", fs_windows_root.GetCString()); - EXPECT_STREQ("F:", fs_windows_root.GetDirectory().GetCString()); - // EXPECT_STREQ("\\", fs_windows_root.GetFilename().GetCString()); // It - // returns "/" - - FileSpec fs_posix_long("/foo/bar/baz", FileSpec::Style::posix); - EXPECT_STREQ("/foo/bar/baz", fs_posix_long.GetCString()); - EXPECT_STREQ("/foo/bar", fs_posix_long.GetDirectory().GetCString()); - EXPECT_STREQ("baz", fs_posix_long.GetFilename().GetCString()); - - FileSpec fs_windows_long("F:\\bar\\baz", FileSpec::Style::windows); - EXPECT_STREQ("F:\\bar\\baz", fs_windows_long.GetCString()); - // EXPECT_STREQ("F:\\bar", fs_windows_long.GetDirectory().GetCString()); // It - // returns "F:/bar" - EXPECT_STREQ("baz", fs_windows_long.GetFilename().GetCString()); - - FileSpec fs_posix_trailing_slash("/foo/bar/", FileSpec::Style::posix); - EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetCString()); - EXPECT_STREQ("/foo", fs_posix_trailing_slash.GetDirectory().GetCString()); - EXPECT_STREQ("bar", fs_posix_trailing_slash.GetFilename().GetCString()); - - FileSpec fs_windows_trailing_slash("F:\\bar\\", FileSpec::Style::windows); - EXPECT_STREQ("F:\\bar", fs_windows_trailing_slash.GetCString()); - EXPECT_STREQ("bar", fs_windows_trailing_slash.GetFilename().GetCString()); -} - -TEST(FileSpecTest, AppendPathComponent) { - FileSpec fs_posix("/foo", FileSpec::Style::posix); - fs_posix.AppendPathComponent("bar"); - EXPECT_STREQ("/foo/bar", fs_posix.GetCString()); - EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString()); - EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString()); - - FileSpec fs_posix_2("/foo", FileSpec::Style::posix); - fs_posix_2.AppendPathComponent("//bar/baz"); - EXPECT_STREQ("/foo/bar/baz", fs_posix_2.GetCString()); - EXPECT_STREQ("/foo/bar", fs_posix_2.GetDirectory().GetCString()); - EXPECT_STREQ("baz", fs_posix_2.GetFilename().GetCString()); - - FileSpec fs_windows("F:\\bar", FileSpec::Style::windows); - fs_windows.AppendPathComponent("baz"); - EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString()); - // EXPECT_STREQ("F:\\bar", fs_windows.GetDirectory().GetCString()); // It - // returns "F:/bar" - EXPECT_STREQ("baz", fs_windows.GetFilename().GetCString()); - - FileSpec fs_posix_root("/", FileSpec::Style::posix); - fs_posix_root.AppendPathComponent("bar"); - EXPECT_STREQ("/bar", fs_posix_root.GetCString()); - EXPECT_STREQ("/", fs_posix_root.GetDirectory().GetCString()); - EXPECT_STREQ("bar", fs_posix_root.GetFilename().GetCString()); - - FileSpec fs_windows_root("F:\\", FileSpec::Style::windows); - fs_windows_root.AppendPathComponent("bar"); - EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString()); - // EXPECT_STREQ("F:\\", fs_windows_root.GetDirectory().GetCString()); // It - // returns "F:/" - EXPECT_STREQ("bar", fs_windows_root.GetFilename().GetCString()); -} - -TEST(FileSpecTest, CopyByAppendingPathComponent) { - FileSpec fs = PosixSpec("/foo").CopyByAppendingPathComponent("bar"); - EXPECT_STREQ("/foo/bar", fs.GetCString()); - EXPECT_STREQ("/foo", fs.GetDirectory().GetCString()); - EXPECT_STREQ("bar", fs.GetFilename().GetCString()); -} - -TEST(FileSpecTest, PrependPathComponent) { - FileSpec fs_posix("foo", FileSpec::Style::posix); - fs_posix.PrependPathComponent("/bar"); - EXPECT_STREQ("/bar/foo", fs_posix.GetCString()); - - FileSpec fs_posix_2("foo/bar", FileSpec::Style::posix); - fs_posix_2.PrependPathComponent("/baz"); - EXPECT_STREQ("/baz/foo/bar", fs_posix_2.GetCString()); - - FileSpec fs_windows("baz", FileSpec::Style::windows); - fs_windows.PrependPathComponent("F:\\bar"); - EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString()); - - FileSpec fs_posix_root("bar", FileSpec::Style::posix); - fs_posix_root.PrependPathComponent("/"); - EXPECT_STREQ("/bar", fs_posix_root.GetCString()); - - FileSpec fs_windows_root("bar", FileSpec::Style::windows); - fs_windows_root.PrependPathComponent("F:\\"); - EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString()); -} - -TEST(FileSpecTest, EqualSeparator) { - EXPECT_EQ(WindowsSpec("C:\\foo\\bar"), WindowsSpec("C:/foo/bar")); -} - -TEST(FileSpecTest, EqualDotsWindows) { - std::pair tests[] = { - {R"(C:\foo\bar\baz)", R"(C:\foo\foo\..\bar\baz)"}, - {R"(C:\bar\baz)", R"(C:\foo\..\bar\baz)"}, - {R"(C:\bar\baz)", R"(C:/foo/../bar/baz)"}, - {R"(C:/bar/baz)", R"(C:\foo\..\bar\baz)"}, - {R"(C:\bar)", R"(C:\foo\..\bar)"}, - {R"(C:\foo\bar)", R"(C:\foo\.\bar)"}, - {R"(C:\foo\bar)", R"(C:\foo\bar\.)"}, - }; - - for (const auto &test : tests) { - SCOPED_TRACE(llvm::Twine(test.first) + " <=> " + test.second); - EXPECT_EQ(WindowsSpec(test.first), WindowsSpec(test.second)); - } -} - -TEST(FileSpecTest, EqualDotsPosix) { - std::pair tests[] = { - {R"(/foo/bar/baz)", R"(/foo/foo/../bar/baz)"}, - {R"(/bar/baz)", R"(/foo/../bar/baz)"}, - {R"(/bar)", R"(/foo/../bar)"}, - {R"(/foo/bar)", R"(/foo/./bar)"}, - {R"(/foo/bar)", R"(/foo/bar/.)"}, - }; - - for (const auto &test : tests) { - SCOPED_TRACE(llvm::Twine(test.first) + " <=> " + test.second); - EXPECT_EQ(PosixSpec(test.first), PosixSpec(test.second)); - } -} - -TEST(FileSpecTest, EqualDotsPosixRoot) { - std::pair tests[] = { - {R"(/)", R"(/..)"}, - {R"(/)", R"(/.)"}, - {R"(/)", R"(/foo/..)"}, - }; - - for (const auto &test : tests) { - SCOPED_TRACE(llvm::Twine(test.first) + " <=> " + test.second); - EXPECT_EQ(PosixSpec(test.first), PosixSpec(test.second)); - } -} - -TEST(FileSpecTest, GuessPathStyle) { - EXPECT_EQ(FileSpec::Style::posix, FileSpec::GuessPathStyle("/foo/bar.txt")); - EXPECT_EQ(FileSpec::Style::posix, FileSpec::GuessPathStyle("//net/bar.txt")); - EXPECT_EQ(FileSpec::Style::windows, - FileSpec::GuessPathStyle(R"(C:\foo.txt)")); - EXPECT_EQ(FileSpec::Style::windows, - FileSpec::GuessPathStyle(R"(\\net\foo.txt)")); - EXPECT_EQ(llvm::None, FileSpec::GuessPathStyle("foo.txt")); - EXPECT_EQ(llvm::None, FileSpec::GuessPathStyle("foo/bar.txt")); -} - -TEST(FileSpecTest, GetPath) { - std::pair posix_tests[] = { - {"/foo/.././bar", "/bar"}, - {"/foo/./../bar", "/bar"}, - {"/foo/../bar", "/bar"}, - {"/foo/./bar", "/foo/bar"}, - {"/foo/..", "/"}, - {"/foo/.", "/foo"}, - {"/foo//bar", "/foo/bar"}, - {"/foo//bar/baz", "/foo/bar/baz"}, - {"/foo//bar/./baz", "/foo/bar/baz"}, - {"/./foo", "/foo"}, - {"/", "/"}, - {"//", "/"}, - {"//net", "//net"}, - {"/..", "/"}, - {"/.", "/"}, - {"..", ".."}, - {".", "."}, - {"../..", "../.."}, - {"foo/..", "."}, - {"foo/../bar", "bar"}, - {"../foo/..", ".."}, - {"./foo", "foo"}, - {"././foo", "foo"}, - {"../foo", "../foo"}, - {"../../foo", "../../foo"}, - }; - for (auto test : posix_tests) { - SCOPED_TRACE(llvm::Twine("test.first = ") + test.first); - EXPECT_EQ(test.second, PosixSpec(test.first).GetPath()); - } - - std::pair windows_tests[] = { - {R"(c:\bar\..\bar)", R"(c:\bar)"}, - {R"(c:\bar\.\bar)", R"(c:\bar\bar)"}, - {R"(c:\bar\..)", R"(c:\)"}, - {R"(c:\bar\.)", R"(c:\bar)"}, - {R"(c:\.\bar)", R"(c:\bar)"}, - {R"(\)", R"(\)"}, - {R"(\\)", R"(\)"}, - {R"(\\net)", R"(\\net)"}, - {R"(c:\..)", R"(c:\)"}, - {R"(c:\.)", R"(c:\)"}, - {R"(\..)", R"(\)"}, - // {R"(c:..)", R"(c:..)"}, - {R"(..)", R"(..)"}, - {R"(.)", R"(.)"}, - {R"(c:..\..)", R"(c:)"}, - {R"(..\..)", R"(..\..)"}, - {R"(foo\..)", R"(.)"}, - {R"(foo\..\bar)", R"(bar)"}, - {R"(..\foo\..)", R"(..)"}, - {R"(.\foo)", R"(foo)"}, - {R"(.\.\foo)", R"(foo)"}, - {R"(..\foo)", R"(..\foo)"}, - {R"(..\..\foo)", R"(..\..\foo)"}, - }; - for (auto test : windows_tests) { - SCOPED_TRACE(llvm::Twine("test.first = ") + test.first); - EXPECT_EQ(test.second, WindowsSpec(test.first).GetPath()); - } -} - -TEST(FileSpecTest, FormatFileSpec) { - auto win = FileSpec::Style::windows; - - FileSpec F; - EXPECT_EQ("(empty)", llvm::formatv("{0}", F).str()); - EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str()); - EXPECT_EQ("(empty)", llvm::formatv("{0:F}", F).str()); - - F = FileSpec("C:\\foo\\bar.txt", win); - EXPECT_EQ("C:\\foo\\bar.txt", llvm::formatv("{0}", F).str()); - EXPECT_EQ("C:\\foo\\", llvm::formatv("{0:D}", F).str()); - EXPECT_EQ("bar.txt", llvm::formatv("{0:F}", F).str()); - - F = FileSpec("foo\\bar.txt", win); - EXPECT_EQ("foo\\bar.txt", llvm::formatv("{0}", F).str()); - EXPECT_EQ("foo\\", llvm::formatv("{0:D}", F).str()); - EXPECT_EQ("bar.txt", llvm::formatv("{0:F}", F).str()); - - F = FileSpec("foo", win); - EXPECT_EQ("foo", llvm::formatv("{0}", F).str()); - EXPECT_EQ("foo", llvm::formatv("{0:F}", F).str()); - EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str()); -} - -TEST(FileSpecTest, IsRelative) { - llvm::StringRef not_relative[] = { - "/", - "/a", - "/a/", - "/a/b", - "/a/b/", - "//", - "//a/", - "//a/b", - "//a/b/", - "~", - "~/", - "~/a", - "~/a/", - "~/a/b", - "~/a/b/", - "/foo/.", - "/foo/..", - "/foo/../", - "/foo/../.", - }; - for (const auto &path: not_relative) { - SCOPED_TRACE(path); - EXPECT_FALSE(PosixSpec(path).IsRelative()); - } - llvm::StringRef is_relative[] = { - ".", - "./", - ".///", - "a", - "./a", - "./a/", - "./a/", - "./a/b", - "./a/b/", - "../foo", - "foo/bar.c", - "./foo/bar.c" - }; - for (const auto &path: is_relative) { - SCOPED_TRACE(path); - EXPECT_TRUE(PosixSpec(path).IsRelative()); - } -} - -TEST(FileSpecTest, RemoveLastPathComponent) { - FileSpec fs_posix("/foo/bar/baz", FileSpec::Style::posix); - EXPECT_STREQ("/foo/bar/baz", fs_posix.GetCString()); - EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); - EXPECT_STREQ("/foo/bar", fs_posix.GetCString()); - EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); - EXPECT_STREQ("/foo", fs_posix.GetCString()); - EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); - EXPECT_STREQ("/", fs_posix.GetCString()); - EXPECT_FALSE(fs_posix.RemoveLastPathComponent()); - EXPECT_STREQ("/", fs_posix.GetCString()); - - FileSpec fs_posix_relative("./foo/bar/baz", FileSpec::Style::posix); - EXPECT_STREQ("foo/bar/baz", fs_posix_relative.GetCString()); - EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent()); - EXPECT_STREQ("foo/bar", fs_posix_relative.GetCString()); - EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent()); - EXPECT_STREQ("foo", fs_posix_relative.GetCString()); - EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent()); - EXPECT_STREQ("foo", fs_posix_relative.GetCString()); - - FileSpec fs_posix_relative2("./", FileSpec::Style::posix); - EXPECT_STREQ(".", fs_posix_relative2.GetCString()); - EXPECT_FALSE(fs_posix_relative2.RemoveLastPathComponent()); - EXPECT_STREQ(".", fs_posix_relative2.GetCString()); - EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent()); - EXPECT_STREQ(".", fs_posix_relative2.GetCString()); - - FileSpec fs_windows("C:\\foo\\bar\\baz", FileSpec::Style::windows); - EXPECT_STREQ("C:\\foo\\bar\\baz", fs_windows.GetCString()); - EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); - EXPECT_STREQ("C:\\foo\\bar", fs_windows.GetCString()); - EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); - EXPECT_STREQ("C:\\foo", fs_windows.GetCString()); - EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); - EXPECT_STREQ("C:\\", fs_windows.GetCString()); - EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); - EXPECT_STREQ("C:", fs_windows.GetCString()); - EXPECT_FALSE(fs_windows.RemoveLastPathComponent()); - EXPECT_STREQ("C:", fs_windows.GetCString()); -} - -TEST(FileSpecTest, Equal) { - auto Eq = [](const char *a, const char *b, bool full) { - return FileSpec::Equal(PosixSpec(a), PosixSpec(b), full); - }; - EXPECT_TRUE(Eq("/foo/bar", "/foo/bar", true)); - EXPECT_TRUE(Eq("/foo/bar", "/foo/bar", false)); - - EXPECT_FALSE(Eq("/foo/bar", "/foo/baz", true)); - EXPECT_FALSE(Eq("/foo/bar", "/foo/baz", false)); - - EXPECT_FALSE(Eq("/bar/foo", "/baz/foo", true)); - EXPECT_FALSE(Eq("/bar/foo", "/baz/foo", false)); - - EXPECT_FALSE(Eq("/bar/foo", "foo", true)); - EXPECT_TRUE(Eq("/bar/foo", "foo", false)); - - EXPECT_FALSE(Eq("foo", "/bar/foo", true)); - EXPECT_TRUE(Eq("foo", "/bar/foo", false)); -} - -TEST(FileSpecTest, Match) { - auto Match = [](const char *pattern, const char *file) { - return FileSpec::Match(PosixSpec(pattern), PosixSpec(file)); - }; - EXPECT_TRUE(Match("/foo/bar", "/foo/bar")); - EXPECT_FALSE(Match("/foo/bar", "/oof/bar")); - EXPECT_FALSE(Match("/foo/bar", "/foo/baz")); - EXPECT_FALSE(Match("/foo/bar", "bar")); - EXPECT_FALSE(Match("/foo/bar", "")); - - EXPECT_TRUE(Match("bar", "/foo/bar")); - EXPECT_FALSE(Match("bar", "/foo/baz")); - EXPECT_TRUE(Match("bar", "bar")); - EXPECT_FALSE(Match("bar", "baz")); - EXPECT_FALSE(Match("bar", "")); - - EXPECT_TRUE(Match("", "/foo/bar")); - EXPECT_TRUE(Match("", "")); - -} - -TEST(FileSpecTest, Yaml) { - std::string buffer; - llvm::raw_string_ostream os(buffer); - - // Serialize. - FileSpec fs_windows("F:\\bar", FileSpec::Style::windows); - llvm::yaml::Output yout(os); - yout << fs_windows; - os.flush(); - - // Deserialize. - FileSpec deserialized; - llvm::yaml::Input yin(buffer); - yin >> deserialized; - - EXPECT_EQ(deserialized.GetPathStyle(), fs_windows.GetPathStyle()); - EXPECT_EQ(deserialized.GetFilename(), fs_windows.GetFilename()); - EXPECT_EQ(deserialized.GetDirectory(), fs_windows.GetDirectory()); - EXPECT_EQ(deserialized, fs_windows); -} - -TEST(FileSpecTest, OperatorBool) { - EXPECT_FALSE(FileSpec()); - EXPECT_FALSE(FileSpec("")); - EXPECT_TRUE(FileSpec("/foo/bar")); -} diff --git a/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp b/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp deleted file mode 100644 index c33a19547a6..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp +++ /dev/null @@ -1,163 +0,0 @@ -//===-- FlagsTest.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 "gtest/gtest.h" - -#include "lldb/Utility/Flags.h" - -using namespace lldb_private; - -enum DummyFlags { - eFlag0 = 1 << 0, - eFlag1 = 1 << 1, - eFlag2 = 1 << 2, - eAllFlags = (eFlag0 | eFlag1 | eFlag2) -}; - -TEST(Flags, GetBitSize) { - Flags f; - // Methods like ClearCount depend on this specific value, so we test - // against it here. - EXPECT_EQ(32U, f.GetBitSize()); -} - -TEST(Flags, Reset) { - Flags f; - f.Reset(0x3); - EXPECT_EQ(0x3U, f.Get()); -} - -TEST(Flags, Clear) { - Flags f; - f.Reset(0x3); - EXPECT_EQ(0x3U, f.Get()); - - f.Clear(0x5); - EXPECT_EQ(0x2U, f.Get()); - - f.Clear(); - EXPECT_EQ(0x0U, f.Get()); -} - -TEST(Flags, AllSet) { - Flags f; - - EXPECT_FALSE(f.AllSet(eFlag0 | eFlag1)); - - f.Set(eFlag0); - EXPECT_FALSE(f.AllSet(eFlag0 | eFlag1)); - - f.Set(eFlag1); - EXPECT_TRUE(f.AllSet(eFlag0 | eFlag1)); - - f.Clear(eFlag1); - EXPECT_FALSE(f.AllSet(eFlag0 | eFlag1)); - - f.Clear(eFlag0); - EXPECT_FALSE(f.AllSet(eFlag0 | eFlag1)); -} - -TEST(Flags, AnySet) { - Flags f; - - EXPECT_FALSE(f.AnySet(eFlag0 | eFlag1)); - - f.Set(eFlag0); - EXPECT_TRUE(f.AnySet(eFlag0 | eFlag1)); - - f.Set(eFlag1); - EXPECT_TRUE(f.AnySet(eFlag0 | eFlag1)); - - f.Clear(eFlag1); - EXPECT_TRUE(f.AnySet(eFlag0 | eFlag1)); - - f.Clear(eFlag0); - EXPECT_FALSE(f.AnySet(eFlag0 | eFlag1)); -} - -TEST(Flags, Test) { - Flags f; - - EXPECT_FALSE(f.Test(eFlag0)); - EXPECT_FALSE(f.Test(eFlag1)); - EXPECT_FALSE(f.Test(eFlag2)); - - f.Set(eFlag0); - EXPECT_TRUE(f.Test(eFlag0)); - EXPECT_FALSE(f.Test(eFlag1)); - EXPECT_FALSE(f.Test(eFlag2)); - - f.Set(eFlag1); - EXPECT_TRUE(f.Test(eFlag0)); - EXPECT_TRUE(f.Test(eFlag1)); - EXPECT_FALSE(f.Test(eFlag2)); - - f.Clear(eFlag0); - EXPECT_FALSE(f.Test(eFlag0)); - EXPECT_TRUE(f.Test(eFlag1)); - EXPECT_FALSE(f.Test(eFlag2)); - - // FIXME: Should Flags assert on Test(eFlag0 | eFlag1) (more than one bit)? -} - -TEST(Flags, AllClear) { - Flags f; - - EXPECT_TRUE(f.AllClear(eFlag0 | eFlag1)); - - f.Set(eFlag0); - EXPECT_FALSE(f.AllClear(eFlag0 | eFlag1)); - - f.Set(eFlag1); - f.Clear(eFlag0); - EXPECT_FALSE(f.AllClear(eFlag0 | eFlag1)); - - f.Clear(eFlag1); - EXPECT_TRUE(f.AnyClear(eFlag0 | eFlag1)); -} - -TEST(Flags, AnyClear) { - Flags f; - EXPECT_TRUE(f.AnyClear(eFlag0 | eFlag1)); - - f.Set(eFlag0); - EXPECT_TRUE(f.AnyClear(eFlag0 | eFlag1)); - - f.Set(eFlag1); - f.Set(eFlag0); - EXPECT_FALSE(f.AnyClear(eFlag0 | eFlag1)); - - f.Clear(eFlag1); - EXPECT_TRUE(f.AnyClear(eFlag0 | eFlag1)); - - f.Clear(eFlag0); - EXPECT_TRUE(f.AnyClear(eFlag0 | eFlag1)); -} - -TEST(Flags, IsClear) { - Flags f; - - EXPECT_TRUE(f.IsClear(eFlag0)); - EXPECT_TRUE(f.IsClear(eFlag1)); - - f.Set(eFlag0); - EXPECT_FALSE(f.IsClear(eFlag0)); - EXPECT_TRUE(f.IsClear(eFlag1)); - - f.Set(eFlag1); - EXPECT_FALSE(f.IsClear(eFlag0)); - EXPECT_FALSE(f.IsClear(eFlag1)); - - f.Clear(eFlag0); - EXPECT_TRUE(f.IsClear(eFlag0)); - EXPECT_FALSE(f.IsClear(eFlag1)); - - f.Clear(eFlag1); - EXPECT_TRUE(f.IsClear(eFlag0)); - EXPECT_TRUE(f.IsClear(eFlag1)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/Inputs/StructuredData-basic.json b/gnu/llvm/lldb/unittests/Utility/Inputs/StructuredData-basic.json deleted file mode 100644 index b5d8bb58d9b..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/Inputs/StructuredData-basic.json +++ /dev/null @@ -1 +0,0 @@ -[1, 2, 3] diff --git a/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp b/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp deleted file mode 100644 index bf38955a8e7..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//===-- ListenerTest.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 "gtest/gtest.h" - -#include "lldb/Utility/Broadcaster.h" -#include "lldb/Utility/Listener.h" -#include -#include - -using namespace lldb; -using namespace lldb_private; - -TEST(ListenerTest, GetEventImmediate) { - EventSP event_sp; - Broadcaster broadcaster(nullptr, "test-broadcaster"); - - // Create a listener, sign it up, make sure it receives an event. - ListenerSP listener_sp = Listener::MakeListener("test-listener"); - const uint32_t event_mask = 1; - ASSERT_EQ(event_mask, - listener_sp->StartListeningForEvents(&broadcaster, event_mask)); - - const std::chrono::seconds timeout(0); - // Without any events sent, these should return false. - EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout)); - EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); - EXPECT_FALSE( - listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); - EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask, event_sp, timeout)); - - // Now send events and make sure they get it. - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout)); - - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); - - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_TRUE( - listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); - - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask * 2, event_sp, timeout)); - EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask, event_sp, timeout)); -} - -TEST(ListenerTest, GetEventWait) { - EventSP event_sp; - Broadcaster broadcaster(nullptr, "test-broadcaster"); - - // Create a listener, sign it up, make sure it receives an event. - ListenerSP listener_sp = Listener::MakeListener("test-listener"); - const uint32_t event_mask = 1; - ASSERT_EQ(event_mask, - listener_sp->StartListeningForEvents(&broadcaster, event_mask)); - - // Without any events sent, these should make a short wait and return false. - std::chrono::microseconds timeout(10); - EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout)); - EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); - EXPECT_FALSE( - listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); - EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask, event_sp, timeout)); - - // Now send events and make sure they get it. - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout)); - - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); - - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_TRUE( - listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); - - broadcaster.BroadcastEvent(event_mask, nullptr); - EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask * 2, event_sp, timeout)); - EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask, event_sp, timeout)); - - auto delayed_broadcast = [&] { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - broadcaster.BroadcastEvent(event_mask, nullptr); - }; - - // These should do an infinite wait at return the event our asynchronous - // broadcast sends. - std::future async_broadcast = - std::async(std::launch::async, delayed_broadcast); - EXPECT_TRUE(listener_sp->GetEvent(event_sp, llvm::None)); - async_broadcast.get(); - - async_broadcast = std::async(std::launch::async, delayed_broadcast); - EXPECT_TRUE( - listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, llvm::None)); - async_broadcast.get(); - - async_broadcast = std::async(std::launch::async, delayed_broadcast); - EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType( - &broadcaster, event_mask, event_sp, llvm::None)); - async_broadcast.get(); -} diff --git a/gnu/llvm/lldb/unittests/Utility/LogTest.cpp b/gnu/llvm/lldb/unittests/Utility/LogTest.cpp deleted file mode 100644 index dfbb1f09214..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/LogTest.cpp +++ /dev/null @@ -1,313 +0,0 @@ -//===-- LogTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "lldb/Utility/Log.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Threading.h" -#include - -using namespace lldb; -using namespace lldb_private; - -enum { FOO = 1, BAR = 2 }; -static constexpr Log::Category test_categories[] = { - {{"foo"}, {"log foo"}, FOO}, {{"bar"}, {"log bar"}, BAR}, -}; -static constexpr uint32_t default_flags = FOO; - -static Log::Channel test_channel(test_categories, default_flags); - -// Wrap enable, disable and list functions to make them easier to test. -static bool EnableChannel(std::shared_ptr stream_sp, - uint32_t log_options, llvm::StringRef channel, - llvm::ArrayRef categories, - std::string &error) { - error.clear(); - llvm::raw_string_ostream error_stream(error); - return Log::EnableLogChannel(stream_sp, log_options, channel, categories, - error_stream); -} - -static bool DisableChannel(llvm::StringRef channel, - llvm::ArrayRef categories, - std::string &error) { - error.clear(); - llvm::raw_string_ostream error_stream(error); - return Log::DisableLogChannel(channel, categories, error_stream); -} - -static bool ListCategories(llvm::StringRef channel, std::string &result) { - result.clear(); - llvm::raw_string_ostream result_stream(result); - return Log::ListChannelCategories(channel, result_stream); -} - -namespace { -// A test fixture which provides tests with a pre-registered channel. -struct LogChannelTest : public ::testing::Test { - void TearDown() override { Log::DisableAllLogChannels(); } - - static void SetUpTestCase() { - Log::Register("chan", test_channel); - } - - static void TearDownTestCase() { - Log::Unregister("chan"); - llvm::llvm_shutdown(); - } -}; - -// A test fixture which provides tests with a pre-registered and pre-enabled -// channel. Additionally, the messages written to that channel are captured and -// made available via getMessage(). -class LogChannelEnabledTest : public LogChannelTest { - llvm::SmallString<0> m_messages; - std::shared_ptr m_stream_sp = - std::make_shared(m_messages); - Log *m_log; - size_t m_consumed_bytes = 0; - -protected: - std::shared_ptr getStream() { return m_stream_sp; } - Log *getLog() { return m_log; } - llvm::StringRef takeOutput(); - llvm::StringRef logAndTakeOutput(llvm::StringRef Message); - -public: - void SetUp() override; -}; -} // end anonymous namespace - -void LogChannelEnabledTest::SetUp() { - LogChannelTest::SetUp(); - - std::string error; - ASSERT_TRUE(EnableChannel(m_stream_sp, 0, "chan", {}, error)); - - m_log = test_channel.GetLogIfAll(FOO); - ASSERT_NE(nullptr, m_log); -} - -llvm::StringRef LogChannelEnabledTest::takeOutput() { - llvm::StringRef result = m_stream_sp->str().drop_front(m_consumed_bytes); - m_consumed_bytes+= result.size(); - return result; -} - -llvm::StringRef LogChannelEnabledTest::logAndTakeOutput(llvm::StringRef Message) { - LLDB_LOG(m_log, "{0}", Message); - return takeOutput(); -} - -TEST(LogTest, LLDB_LOG_nullptr) { - Log *log = nullptr; - LLDB_LOG(log, "{0}", 0); // Shouldn't crash -} - -TEST(LogTest, Register) { - llvm::llvm_shutdown_obj obj; - Log::Register("chan", test_channel); - Log::Unregister("chan"); - Log::Register("chan", test_channel); - Log::Unregister("chan"); -} - -TEST(LogTest, Unregister) { - llvm::llvm_shutdown_obj obj; - Log::Register("chan", test_channel); - EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO)); - std::string message; - std::shared_ptr stream_sp( - new llvm::raw_string_ostream(message)); - EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {"foo"}, llvm::nulls())); - EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO)); - Log::Unregister("chan"); - EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO)); -} - -TEST_F(LogChannelTest, Enable) { - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); - std::string message; - std::shared_ptr stream_sp( - new llvm::raw_string_ostream(message)); - std::string error; - ASSERT_FALSE(EnableChannel(stream_sp, 0, "chanchan", {}, error)); - EXPECT_EQ("Invalid log channel 'chanchan'.\n", error); - - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); - - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"bar"}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); - - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"baz"}, error)); - EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'")) - << "error: " << error; - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); -} - -TEST_F(LogChannelTest, EnableOptions) { - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); - std::string message; - std::shared_ptr stream_sp( - new llvm::raw_string_ostream(message)); - std::string error; - EXPECT_TRUE( - EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", {}, error)); - - Log *log = test_channel.GetLogIfAll(FOO); - ASSERT_NE(nullptr, log); - EXPECT_TRUE(log->GetVerbose()); -} - -TEST_F(LogChannelTest, Disable) { - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); - std::string message; - std::shared_ptr stream_sp( - new llvm::raw_string_ostream(message)); - std::string error; - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"foo", "bar"}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); - - EXPECT_TRUE(DisableChannel("chan", {"bar"}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); - - EXPECT_TRUE(DisableChannel("chan", {"baz"}, error)); - EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'")) - << "error: " << error; - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); - - EXPECT_TRUE(DisableChannel("chan", {}, error)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR)); -} - -TEST_F(LogChannelTest, List) { - std::string list; - EXPECT_TRUE(ListCategories("chan", list)); - std::string expected = - R"(Logging categories for 'chan': - all - all available logging categories - default - default set of logging categories - foo - log foo - bar - log bar -)"; - EXPECT_EQ(expected, list); - - EXPECT_FALSE(ListCategories("chanchan", list)); - EXPECT_EQ("Invalid log channel 'chanchan'.\n", list); -} - -TEST_F(LogChannelEnabledTest, log_options) { - std::string Err; - EXPECT_EQ("Hello World\n", logAndTakeOutput("Hello World")); - EXPECT_TRUE(EnableChannel(getStream(), LLDB_LOG_OPTION_THREADSAFE, "chan", {}, - Err)); - EXPECT_EQ("Hello World\n", logAndTakeOutput("Hello World")); - - { - EXPECT_TRUE(EnableChannel(getStream(), LLDB_LOG_OPTION_PREPEND_SEQUENCE, - "chan", {}, Err)); - llvm::StringRef Msg = logAndTakeOutput("Hello World"); - int seq_no; - EXPECT_EQ(1, sscanf(Msg.str().c_str(), "%d Hello World", &seq_no)); - } - - { - EXPECT_TRUE(EnableChannel(getStream(), LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, - "chan", {}, Err)); - llvm::StringRef Msg = logAndTakeOutput("Hello World"); - char File[12]; - char Function[17]; - - sscanf(Msg.str().c_str(), "%[^:]:%s Hello World", File, Function); - EXPECT_STRCASEEQ("LogTest.cpp", File); - EXPECT_STREQ("logAndTakeOutput", Function); - } - - EXPECT_TRUE(EnableChannel( - getStream(), LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD, "chan", {}, Err)); - EXPECT_EQ(llvm::formatv("[{0,0+4}/{1,0+4}] Hello World\n", ::getpid(), - llvm::get_threadid()) - .str(), - logAndTakeOutput("Hello World")); -} - -TEST_F(LogChannelEnabledTest, LLDB_LOG_ERROR) { - LLDB_LOG_ERROR(getLog(), llvm::Error::success(), "Foo failed: {0}"); - ASSERT_EQ("", takeOutput()); - - LLDB_LOG_ERROR(getLog(), - llvm::make_error( - "My Error", llvm::inconvertibleErrorCode()), - "Foo failed: {0}"); - ASSERT_EQ("Foo failed: My Error\n", takeOutput()); - - // Doesn't log, but doesn't assert either - LLDB_LOG_ERROR(nullptr, - llvm::make_error( - "My Error", llvm::inconvertibleErrorCode()), - "Foo failed: {0}"); -} - -TEST_F(LogChannelEnabledTest, LogThread) { - // Test that we are able to concurrently write to a log channel and disable - // it. - std::string err; - - // Start logging on one thread. Concurrently, try disabling the log channel. - std::thread log_thread([this] { LLDB_LOG(getLog(), "Hello World"); }); - EXPECT_TRUE(DisableChannel("chan", {}, err)); - log_thread.join(); - - // The log thread either managed to write to the log in time, or it didn't. In - // either case, we should not trip any undefined behavior (run the test under - // TSAN to verify this). - EXPECT_THAT(takeOutput(), testing::AnyOf("", "Hello World\n")); -} - -TEST_F(LogChannelEnabledTest, LogVerboseThread) { - // Test that we are able to concurrently check the verbose flag of a log - // channel and enable it. - std::string err; - - // Start logging on one thread. Concurrently, try enabling the log channel - // (with different log options). - std::thread log_thread([this] { LLDB_LOGV(getLog(), "Hello World"); }); - EXPECT_TRUE( - EnableChannel(getStream(), LLDB_LOG_OPTION_VERBOSE, "chan", {}, err)); - log_thread.join(); - - // The log thread either managed to write to the log, or it didn't. In either - // case, we should not trip any undefined behavior (run the test under TSAN to - // verify this). - EXPECT_THAT(takeOutput(), testing::AnyOf("", "Hello World\n")); -} - -TEST_F(LogChannelEnabledTest, LogGetLogThread) { - // Test that we are able to concurrently get mask of a Log object and disable - // it. - std::string err; - - // Try fetching the log mask on one thread. Concurrently, try disabling the - // log channel. - uint32_t mask; - std::thread log_thread([this, &mask] { mask = getLog()->GetMask().Get(); }); - EXPECT_TRUE(DisableChannel("chan", {}, err)); - log_thread.join(); - - // The mask should be either zero of "FOO". In either case, we should not trip - // any undefined behavior (run the test under TSAN to verify this). - EXPECT_THAT(mask, testing::AnyOf(0, FOO)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp b/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp deleted file mode 100644 index 9992f2ff8c3..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//===-- NameMatchesTest.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 "lldb/Utility/NameMatches.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(NameMatchesTest, Ignore) { - EXPECT_TRUE(NameMatches("foo", NameMatch::Ignore, "bar")); -} - -TEST(NameMatchesTest, Equals) { - EXPECT_TRUE(NameMatches("foo", NameMatch::Equals, "foo")); - EXPECT_FALSE(NameMatches("foo", NameMatch::Equals, "bar")); -} - -TEST(NameMatchesTest, Contains) { - EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "foo")); - EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "oob")); - EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "bar")); - EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "foobar")); - EXPECT_TRUE(NameMatches("", NameMatch::Contains, "")); - EXPECT_FALSE(NameMatches("", NameMatch::Contains, "foo")); - EXPECT_FALSE(NameMatches("foobar", NameMatch::Contains, "baz")); -} - -TEST(NameMatchesTest, StartsWith) { - EXPECT_TRUE(NameMatches("foo", NameMatch::StartsWith, "f")); - EXPECT_TRUE(NameMatches("foo", NameMatch::StartsWith, "")); - EXPECT_TRUE(NameMatches("", NameMatch::StartsWith, "")); - EXPECT_FALSE(NameMatches("foo", NameMatch::StartsWith, "b")); - EXPECT_FALSE(NameMatches("", NameMatch::StartsWith, "b")); -} - -TEST(NameMatchesTest, EndsWith) { - EXPECT_TRUE(NameMatches("foo", NameMatch::EndsWith, "o")); - EXPECT_TRUE(NameMatches("foo", NameMatch::EndsWith, "")); - EXPECT_TRUE(NameMatches("", NameMatch::EndsWith, "")); - EXPECT_FALSE(NameMatches("foo", NameMatch::EndsWith, "b")); - EXPECT_FALSE(NameMatches("", NameMatch::EndsWith, "b")); -} - -TEST(NameMatchesTest, RegularExpression) { - EXPECT_TRUE(NameMatches("foobar", NameMatch::RegularExpression, "foo")); - EXPECT_TRUE(NameMatches("foobar", NameMatch::RegularExpression, "f[oa]o")); - EXPECT_FALSE(NameMatches("foo", NameMatch::RegularExpression, "")); - EXPECT_FALSE(NameMatches("", NameMatch::RegularExpression, "")); - EXPECT_FALSE(NameMatches("foo", NameMatch::RegularExpression, "b")); - EXPECT_FALSE(NameMatches("", NameMatch::RegularExpression, "b")); - EXPECT_FALSE(NameMatches("^a", NameMatch::RegularExpression, "^a")); -} diff --git a/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp b/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp deleted file mode 100644 index e7b159b8d40..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp +++ /dev/null @@ -1,182 +0,0 @@ -//===-- OptionsWithRawTest.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 "gtest/gtest.h" - -#include "lldb/Utility/Args.h" -#include "lldb/Utility/StringList.h" - -using namespace lldb_private; - -TEST(OptionsWithRawTest, EmptyInput) { - // An empty string is just an empty suffix without any arguments. - OptionsWithRaw args(""); - ASSERT_FALSE(args.HasArgs()); - ASSERT_STREQ(args.GetRawPart().c_str(), ""); -} - -TEST(OptionsWithRawTest, SingleWhitespaceInput) { - // Only whitespace is just a suffix. - OptionsWithRaw args(" "); - ASSERT_FALSE(args.HasArgs()); - ASSERT_STREQ(args.GetRawPart().c_str(), " "); -} - -TEST(OptionsWithRawTest, WhitespaceInput) { - // Only whitespace is just a suffix. - OptionsWithRaw args(" "); - ASSERT_FALSE(args.HasArgs()); - ASSERT_STREQ(args.GetRawPart().c_str(), " "); -} - -TEST(OptionsWithRawTest, ArgsButNoDelimiter) { - // This counts as a suffix because there is no -- at the end. - OptionsWithRaw args("-foo bar"); - ASSERT_FALSE(args.HasArgs()); - ASSERT_STREQ(args.GetRawPart().c_str(), "-foo bar"); -} - -TEST(OptionsWithRawTest, ArgsButNoLeadingDash) { - // No leading dash means we have no arguments. - OptionsWithRaw args("foo bar --"); - ASSERT_FALSE(args.HasArgs()); - ASSERT_STREQ(args.GetRawPart().c_str(), "foo bar --"); -} - -TEST(OptionsWithRawTest, QuotedSuffix) { - // We need to have a way to escape the -- to make it usable as an argument. - OptionsWithRaw args("-foo \"--\" bar"); - ASSERT_FALSE(args.HasArgs()); - ASSERT_STREQ(args.GetRawPart().c_str(), "-foo \"--\" bar"); -} - -TEST(OptionsWithRawTest, EmptySuffix) { - // An empty suffix with arguments. - OptionsWithRaw args("-foo --"); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo --"); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), ""); -} - -TEST(OptionsWithRawTest, EmptySuffixSingleWhitespace) { - // A single whitespace also countas as an empty suffix (because that usually - // separates the suffix from the double dash. - OptionsWithRaw args("-foo -- "); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), ""); -} - -TEST(OptionsWithRawTest, WhitespaceSuffix) { - // A single whtiespace character as a suffix. - OptionsWithRaw args("-foo -- "); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), " "); -} - -TEST(OptionsWithRawTest, LeadingSpaceArgs) { - // Whitespace before the first dash needs to be ignored. - OptionsWithRaw args(" -foo -- bar"); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), " -foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), " -foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), "bar"); -} - -TEST(OptionsWithRawTest, SingleWordSuffix) { - // A single word as a suffix. - OptionsWithRaw args("-foo -- bar"); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), "bar"); -} - -TEST(OptionsWithRawTest, MultiWordSuffix) { - // Multiple words as a suffix. - OptionsWithRaw args("-foo -- bar baz"); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), "bar baz"); -} - -TEST(OptionsWithRawTest, UnterminatedQuote) { - // A quote character in the suffix shouldn't influence the parsing. - OptionsWithRaw args("-foo -- bar \" "); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), "bar \" "); -} - -TEST(OptionsWithRawTest, TerminatedQuote) { - // A part of the suffix is quoted, which shouldn't influence the parsing. - OptionsWithRaw args("-foo -- bar \"a\" "); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), "-foo "); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-foo -- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(1u, ref.size()); - EXPECT_STREQ("-foo", ref[0]); - - ASSERT_STREQ(args.GetRawPart().c_str(), "bar \"a\" "); -} - -TEST(OptionsWithRawTest, EmptyArgsOnlySuffix) { - // Empty argument list, but we have a suffix. - OptionsWithRaw args("-- bar"); - ASSERT_TRUE(args.HasArgs()); - ASSERT_EQ(args.GetArgString(), ""); - ASSERT_EQ(args.GetArgStringWithDelimiter(), "-- "); - - auto ref = args.GetArgs().GetArgumentArrayRef(); - ASSERT_EQ(0u, ref.size()); - - ASSERT_STREQ(args.GetRawPart().c_str(), "bar"); -} diff --git a/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp b/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp deleted file mode 100644 index 8752e9361ca..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp +++ /dev/null @@ -1,33 +0,0 @@ -//===-- PredicateTest.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 "lldb/Utility/Predicate.h" -#include "gtest/gtest.h" -#include - -using namespace lldb_private; - -TEST(Predicate, WaitForValueEqualTo) { - Predicate P(0); - EXPECT_TRUE(P.WaitForValueEqualTo(0)); - EXPECT_FALSE(P.WaitForValueEqualTo(1, std::chrono::milliseconds(10))); - - std::thread Setter([&P] { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - P.SetValue(1, eBroadcastAlways); - }); - EXPECT_TRUE(P.WaitForValueEqualTo(1)); - Setter.join(); -} - -TEST(Predicate, WaitForValueNotEqualTo) { - Predicate P(0); - EXPECT_EQ(0, P.WaitForValueNotEqualTo(1)); - EXPECT_EQ(llvm::None, - P.WaitForValueNotEqualTo(0, std::chrono::milliseconds(10))); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp b/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp deleted file mode 100644 index b2fdbde70da..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//===-- ProcessInfoTest.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 "lldb/Utility/ProcessInfo.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(ProcessInfoTest, Constructor) { - ProcessInfo Info("foo", ArchSpec("x86_64-pc-linux"), 47); - EXPECT_STREQ("foo", Info.GetName()); - EXPECT_EQ(ArchSpec("x86_64-pc-linux"), Info.GetArchitecture()); - EXPECT_EQ(47u, Info.GetProcessID()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp b/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp deleted file mode 100644 index a3f850cfb9b..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp +++ /dev/null @@ -1,167 +0,0 @@ -//===-- ProcessInstanceInfoTest.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 "lldb/Target/Process.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -/// A very simple resolver which fails for even ids and returns a simple string -/// for odd ones. -class DummyUserIDResolver : public UserIDResolver { -protected: - llvm::Optional DoGetUserName(id_t uid) override { - if (uid % 2) - return ("user" + llvm::Twine(uid)).str(); - return llvm::None; - } - - llvm::Optional DoGetGroupName(id_t gid) override { - if (gid % 2) - return ("group" + llvm::Twine(gid)).str(); - return llvm::None; - } -}; -} // namespace - -TEST(ProcessInstanceInfo, Dump) { - ProcessInstanceInfo info("a.out", ArchSpec("x86_64-pc-linux"), 47); - info.SetUserID(1); - info.SetEffectiveUserID(2); - info.SetGroupID(3); - info.SetEffectiveGroupID(4); - - DummyUserIDResolver resolver; - StreamString s; - info.Dump(s, resolver); - EXPECT_STREQ(R"( pid = 47 - name = a.out - file = a.out - arch = x86_64-pc-linux - uid = 1 (user1) - gid = 3 (group3) - euid = 2 () - egid = 4 () -)", - s.GetData()); -} - -TEST(ProcessInstanceInfo, DumpTable) { - ProcessInstanceInfo info("a.out", ArchSpec("x86_64-pc-linux"), 47); - info.SetUserID(1); - info.SetEffectiveUserID(2); - info.SetGroupID(3); - info.SetEffectiveGroupID(4); - - DummyUserIDResolver resolver; - StreamString s; - - const bool show_args = false; - const bool verbose = true; - ProcessInstanceInfo::DumpTableHeader(s, show_args, verbose); - info.DumpAsTableRow(s, resolver, show_args, verbose); - EXPECT_STREQ( - R"(PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE ARGUMENTS -====== ====== ========== ========== ========== ========== ============================== ============================ -47 0 user1 group3 2 4 x86_64-pc-linux -)", - s.GetData()); -} - -TEST(ProcessInstanceInfo, DumpTable_invalidUID) { - ProcessInstanceInfo info("a.out", ArchSpec("aarch64-unknown-linux-android"), 47); - - DummyUserIDResolver resolver; - StreamString s; - - const bool show_args = false; - const bool verbose = false; - ProcessInstanceInfo::DumpTableHeader(s, show_args, verbose); - info.DumpAsTableRow(s, resolver, show_args, verbose); - EXPECT_STREQ( - R"(PID PARENT USER TRIPLE NAME -====== ====== ========== ============================== ============================ -47 0 aarch64-unknown-linux-android a.out -)", - s.GetData()); -} - -TEST(ProcessInstanceInfoMatch, Name) { - ProcessInstanceInfo info_bar, info_empty; - info_bar.GetExecutableFile().SetFile("/foo/bar", FileSpec::Style::posix); - - ProcessInstanceInfoMatch match; - match.SetNameMatchType(NameMatch::Equals); - match.GetProcessInfo().GetExecutableFile().SetFile("bar", - FileSpec::Style::posix); - - EXPECT_TRUE(match.Matches(info_bar)); - EXPECT_FALSE(match.Matches(info_empty)); - - match.GetProcessInfo().GetExecutableFile() = FileSpec(); - EXPECT_TRUE(match.Matches(info_bar)); - EXPECT_TRUE(match.Matches(info_empty)); -} - -TEST(ProcessInstanceInfo, Yaml) { - std::string buffer; - llvm::raw_string_ostream os(buffer); - - // Serialize. - ProcessInstanceInfo info("a.out", ArchSpec("x86_64-pc-linux"), 47); - info.SetUserID(1); - info.SetEffectiveUserID(2); - info.SetGroupID(3); - info.SetEffectiveGroupID(4); - llvm::yaml::Output yout(os); - yout << info; - os.flush(); - - // Deserialize. - ProcessInstanceInfo deserialized; - llvm::yaml::Input yin(buffer); - yin >> deserialized; - - EXPECT_EQ(deserialized.GetNameAsStringRef(), info.GetNameAsStringRef()); - EXPECT_EQ(deserialized.GetArchitecture(), info.GetArchitecture()); - EXPECT_EQ(deserialized.GetUserID(), info.GetUserID()); - EXPECT_EQ(deserialized.GetGroupID(), info.GetGroupID()); - EXPECT_EQ(deserialized.GetEffectiveUserID(), info.GetEffectiveUserID()); - EXPECT_EQ(deserialized.GetEffectiveGroupID(), info.GetEffectiveGroupID()); -} - -TEST(ProcessInstanceInfoList, Yaml) { - std::string buffer; - llvm::raw_string_ostream os(buffer); - - // Serialize. - ProcessInstanceInfo info("a.out", ArchSpec("x86_64-pc-linux"), 47); - info.SetUserID(1); - info.SetEffectiveUserID(2); - info.SetGroupID(3); - info.SetEffectiveGroupID(4); - ProcessInstanceInfoList list; - list.push_back(info); - llvm::yaml::Output yout(os); - yout << list; - os.flush(); - - // Deserialize. - ProcessInstanceInfoList deserialized; - llvm::yaml::Input yin(buffer); - yin >> deserialized; - - ASSERT_EQ(deserialized.size(), static_cast(1)); - EXPECT_EQ(deserialized[0].GetNameAsStringRef(), info.GetNameAsStringRef()); - EXPECT_EQ(deserialized[0].GetArchitecture(), info.GetArchitecture()); - EXPECT_EQ(deserialized[0].GetUserID(), info.GetUserID()); - EXPECT_EQ(deserialized[0].GetGroupID(), info.GetGroupID()); - EXPECT_EQ(deserialized[0].GetEffectiveUserID(), info.GetEffectiveUserID()); - EXPECT_EQ(deserialized[0].GetEffectiveGroupID(), info.GetEffectiveGroupID()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp b/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp deleted file mode 100644 index 97432dca983..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp +++ /dev/null @@ -1,162 +0,0 @@ -//===-- RangeTest.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 "lldb/Utility/RangeMap.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(RangeVector, CombineConsecutiveRanges) { - using RangeVector = RangeVector; - using Entry = RangeVector::Entry; - - RangeVector V; - V.Append(0, 1); - V.Append(5, 1); - V.Append(6, 1); - V.Append(10, 9); - V.Append(15, 1); - V.Append(20, 9); - V.Append(21, 9); - V.Sort(); - V.CombineConsecutiveRanges(); - EXPECT_THAT(V, testing::ElementsAre(Entry(0, 1), Entry(5, 2), Entry(10, 9), - Entry(20, 10))); - - V.Clear(); - V.Append(0, 20); - V.Append(5, 1); - V.Append(10, 1); - V.Sort(); - V.CombineConsecutiveRanges(); - EXPECT_THAT(V, testing::ElementsAre(Entry(0, 20))); -} - -using RangeDataVectorT = RangeDataVector; -using EntryT = RangeDataVectorT::Entry; - -static testing::Matcher EntryIs(uint32_t ID) { - return testing::Pointee(testing::Field(&EntryT::data, ID)); -} - -std::vector FindEntryIndexes(uint32_t address, RangeDataVectorT map) { - std::vector result; - map.FindEntryIndexesThatContain(address, result); - return result; -} - -TEST(RangeDataVector, FindEntryThatContains) { - RangeDataVectorT Map; - uint32_t NextID = 0; - Map.Append(EntryT(0, 10, NextID++)); - Map.Append(EntryT(10, 10, NextID++)); - Map.Append(EntryT(20, 10, NextID++)); - Map.Sort(); - - EXPECT_THAT(Map.FindEntryThatContains(0), EntryIs(0)); - EXPECT_THAT(Map.FindEntryThatContains(9), EntryIs(0)); - EXPECT_THAT(Map.FindEntryThatContains(10), EntryIs(1)); - EXPECT_THAT(Map.FindEntryThatContains(19), EntryIs(1)); - EXPECT_THAT(Map.FindEntryThatContains(20), EntryIs(2)); - EXPECT_THAT(Map.FindEntryThatContains(29), EntryIs(2)); - EXPECT_THAT(Map.FindEntryThatContains(30), nullptr); -} - -TEST(RangeDataVector, FindEntryThatContains_Overlap) { - RangeDataVectorT Map; - uint32_t NextID = 0; - Map.Append(EntryT(0, 40, NextID++)); - Map.Append(EntryT(10, 20, NextID++)); - Map.Append(EntryT(20, 10, NextID++)); - Map.Sort(); - - // With overlapping intervals, the intention seems to be to return the first - // interval which contains the address. - EXPECT_THAT(Map.FindEntryThatContains(25), EntryIs(0)); - - // However, this does not always succeed. - // TODO: This should probably return the range (0, 40) as well. - EXPECT_THAT(Map.FindEntryThatContains(35), nullptr); -} - -TEST(RangeDataVector, CustomSort) { - // First the default ascending order sorting of the data field. - auto Map = RangeDataVectorT(); - Map.Append(EntryT(0, 10, 50)); - Map.Append(EntryT(0, 10, 52)); - Map.Append(EntryT(0, 10, 53)); - Map.Append(EntryT(0, 10, 51)); - Map.Sort(); - - EXPECT_THAT(Map.GetSize(), 4); - EXPECT_THAT(Map.GetEntryRef(0).data, 50); - EXPECT_THAT(Map.GetEntryRef(1).data, 51); - EXPECT_THAT(Map.GetEntryRef(2).data, 52); - EXPECT_THAT(Map.GetEntryRef(3).data, 53); - - // And then a custom descending order sorting of the data field. - class CtorParam {}; - class CustomSort { - public: - CustomSort(CtorParam) {} - bool operator()(const uint32_t a_data, const uint32_t b_data) { - return a_data > b_data; - } - }; - using RangeDataVectorCustomSortT = - RangeDataVector; - using EntryT = RangeDataVectorT::Entry; - - auto MapC = RangeDataVectorCustomSortT(CtorParam()); - MapC.Append(EntryT(0, 10, 50)); - MapC.Append(EntryT(0, 10, 52)); - MapC.Append(EntryT(0, 10, 53)); - MapC.Append(EntryT(0, 10, 51)); - MapC.Sort(); - - EXPECT_THAT(MapC.GetSize(), 4); - EXPECT_THAT(MapC.GetEntryRef(0).data, 53); - EXPECT_THAT(MapC.GetEntryRef(1).data, 52); - EXPECT_THAT(MapC.GetEntryRef(2).data, 51); - EXPECT_THAT(MapC.GetEntryRef(3).data, 50); -} - -TEST(RangeDataVector, FindEntryIndexesThatContain) { - RangeDataVectorT Map; - Map.Append(EntryT(0, 10, 10)); - Map.Append(EntryT(10, 10, 11)); - Map.Append(EntryT(20, 10, 12)); - Map.Sort(); - - EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10)); - EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10)); - EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(11)); - EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(11)); - EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(12)); - EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(12)); - EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre()); -} - -TEST(RangeDataVector, FindEntryIndexesThatContain_Overlap) { - RangeDataVectorT Map; - Map.Append(EntryT(0, 40, 10)); - Map.Append(EntryT(10, 20, 11)); - Map.Append(EntryT(20, 10, 12)); - Map.Sort(); - - EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10)); - EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10)); - EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(10, 11)); - EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(10, 11)); - EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(10, 11, 12)); - EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(10, 11, 12)); - EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre(10)); - EXPECT_THAT(FindEntryIndexes(39, Map), testing::ElementsAre(10)); - EXPECT_THAT(FindEntryIndexes(40, Map), testing::ElementsAre()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp b/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp deleted file mode 100644 index cfc281c8fd6..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp +++ /dev/null @@ -1,328 +0,0 @@ -//===-- RangeTest.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 "lldb/Utility/RangeMap.h" -#include -#include - -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(RangeTest, SizeTypes) { - Range r; - static_assert(std::is_same::value, - "RangeBase type is not equal to the given one."); - static_assert(std::is_same::value, - "RangeEnd type is not equal to the given one."); - static_assert(std::is_same::value, - "Size type is not equal to the given one."); -} - -typedef Range RangeT; - -TEST(RangeTest, DefaultConstructor) { - RangeT r; - EXPECT_FALSE(r.IsValid()); - EXPECT_EQ(0U, r.GetByteSize()); - EXPECT_EQ(0U, r.GetRangeBase()); - EXPECT_EQ(0U, r.GetRangeEnd()); -} - -TEST(RangeTest, Constructor) { - RangeT r(3, 5); - EXPECT_TRUE(r.IsValid()); - EXPECT_EQ(5U, r.GetByteSize()); - EXPECT_EQ(3U, r.GetRangeBase()); - EXPECT_EQ(8U, r.GetRangeEnd()); -} - -TEST(RangeTest, Copy) { - RangeT orig(3, 5); - RangeT r = orig; - EXPECT_TRUE(r.IsValid()); - EXPECT_EQ(5U, r.GetByteSize()); - EXPECT_EQ(3U, r.GetRangeBase()); - EXPECT_EQ(8U, r.GetRangeEnd()); -} - -TEST(RangeTest, Clear) { - RangeT r(3, 5); - r.Clear(); - EXPECT_TRUE(r == RangeT()); -} - -TEST(RangeTest, ClearWithStarAddress) { - RangeT r(3, 5); - r.Clear(4); - EXPECT_TRUE(r == RangeT(4, 0)); -} - -TEST(RangeTest, SetRangeBase) { - RangeT r(3, 5); - r.SetRangeBase(6); - EXPECT_EQ(6U, r.GetRangeBase()); - EXPECT_EQ(11U, r.GetRangeEnd()); - EXPECT_EQ(5U, r.GetByteSize()); -} - -TEST(RangeTest, Slide) { - RangeT r(3, 5); - r.Slide(1); - EXPECT_EQ(4U, r.GetRangeBase()); - EXPECT_EQ(9U, r.GetRangeEnd()); - EXPECT_EQ(5U, r.GetByteSize()); - - r.Slide(2); - EXPECT_EQ(6U, r.GetRangeBase()); - EXPECT_EQ(11U, r.GetRangeEnd()); - EXPECT_EQ(5U, r.GetByteSize()); -} - -TEST(RangeTest, SlideZero) { - RangeT r(3, 5); - r.Slide(0); - EXPECT_EQ(3U, r.GetRangeBase()); - EXPECT_EQ(8U, r.GetRangeEnd()); - EXPECT_EQ(5U, r.GetByteSize()); -} - -TEST(RangeTest, ContainsAddr) { - RangeT r(3, 5); - EXPECT_FALSE(r.Contains(0)); - EXPECT_FALSE(r.Contains(1)); - EXPECT_FALSE(r.Contains(2)); - EXPECT_TRUE(r.Contains(3)); - EXPECT_TRUE(r.Contains(4)); - EXPECT_TRUE(r.Contains(5)); - EXPECT_TRUE(r.Contains(6)); - EXPECT_TRUE(r.Contains(7)); - EXPECT_FALSE(r.Contains(8)); - EXPECT_FALSE(r.Contains(9)); - EXPECT_FALSE(r.Contains(10)); -} - -TEST(RangeTest, ContainsAddrInvalid) { - RangeT r; - EXPECT_FALSE(r.Contains(0)); - EXPECT_FALSE(r.Contains(1)); - EXPECT_FALSE(r.Contains(2)); - EXPECT_FALSE(r.Contains(3)); - EXPECT_FALSE(r.Contains(4)); -} - -TEST(RangeTest, ContainsEndInclusive) { - RangeT r(3, 5); - EXPECT_FALSE(r.ContainsEndInclusive(0)); - EXPECT_FALSE(r.ContainsEndInclusive(1)); - EXPECT_FALSE(r.ContainsEndInclusive(2)); - EXPECT_TRUE(r.ContainsEndInclusive(3)); - EXPECT_TRUE(r.ContainsEndInclusive(4)); - EXPECT_TRUE(r.ContainsEndInclusive(5)); - EXPECT_TRUE(r.ContainsEndInclusive(6)); - EXPECT_TRUE(r.ContainsEndInclusive(7)); - EXPECT_TRUE(r.ContainsEndInclusive(8)); - EXPECT_FALSE(r.ContainsEndInclusive(9)); - EXPECT_FALSE(r.ContainsEndInclusive(10)); -} - -TEST(RangeTest, ContainsEndInclusiveInvalid) { - RangeT r; - // FIXME: This is probably not intended. - EXPECT_TRUE(r.ContainsEndInclusive(0)); - - EXPECT_FALSE(r.ContainsEndInclusive(1)); - EXPECT_FALSE(r.ContainsEndInclusive(2)); -} - -TEST(RangeTest, ContainsRange) { - RangeT r(3, 5); - - // Range always contains itself. - EXPECT_TRUE(r.Contains(r)); - // Invalid range. - EXPECT_FALSE(r.Contains(RangeT())); - // Range starts and ends before. - EXPECT_FALSE(r.Contains(RangeT(0, 3))); - // Range starts before but contains beginning. - EXPECT_FALSE(r.Contains(RangeT(0, 4))); - // Range starts before but contains beginning and more. - EXPECT_FALSE(r.Contains(RangeT(0, 5))); - // Range starts before and contains the other. - EXPECT_FALSE(r.Contains(RangeT(0, 9))); - // Range is fully inside. - EXPECT_TRUE(r.Contains(RangeT(4, 3))); - // Range has same start, but not as large. - EXPECT_TRUE(r.Contains(RangeT(3, 4))); - // Range has same end, but starts earlier. - EXPECT_TRUE(r.Contains(RangeT(4, 4))); - // Range starts inside, but stops after the end of r. - EXPECT_FALSE(r.Contains(RangeT(4, 5))); - // Range starts directly after r. - EXPECT_FALSE(r.Contains(RangeT(8, 2))); - // Range starts directly after r. - EXPECT_FALSE(r.Contains(RangeT(9, 2))); - - // Invalid range with different start. - // FIXME: The first two probably not intended. - EXPECT_TRUE(r.Contains(RangeT(3, 0))); - EXPECT_TRUE(r.Contains(RangeT(4, 0))); - EXPECT_FALSE(r.Contains(RangeT(8, 0))); -} - -TEST(RangeTest, ContainsRangeStartingFromZero) { - RangeT r(0, 3); - EXPECT_TRUE(r.Contains(r)); - - // FIXME: This is probably not intended. - EXPECT_TRUE(r.Contains(RangeT())); -} - -TEST(RangeTest, Union) { - RangeT r(3, 5); - - // Ranges that we can't merge because it's not adjoin/intersecting. - EXPECT_FALSE(r.Union(RangeT(9, 1))); - // Check that we didn't modify our range. - EXPECT_EQ(r, RangeT(3, 5)); - - // Another range we can't merge, but before r. - EXPECT_FALSE(r.Union(RangeT(1, 1))); - EXPECT_EQ(r, RangeT(3, 5)); - - // Merge an adjoin range after. - EXPECT_TRUE(r.Union(RangeT(8, 2))); - EXPECT_EQ(r, RangeT(3, 7)); - - // Merge an adjoin range before. - EXPECT_TRUE(r.Union(RangeT(1, 2))); - EXPECT_EQ(r, RangeT(1, 9)); - - // Merge an intersecting range after. - EXPECT_TRUE(r.Union(RangeT(8, 3))); - EXPECT_EQ(r, RangeT(1, 10)); - - // Merge an intersecting range before. - EXPECT_TRUE(r.Union(RangeT(0, 1))); - EXPECT_EQ(r, RangeT(0, 11)); - - // Merge a few ranges inside that shouldn't do anything. - EXPECT_TRUE(r.Union(RangeT(0, 3))); - EXPECT_EQ(r, RangeT(0, 11)); - EXPECT_TRUE(r.Union(RangeT(5, 1))); - EXPECT_EQ(r, RangeT(0, 11)); - EXPECT_TRUE(r.Union(RangeT(9, 2))); - EXPECT_EQ(r, RangeT(0, 11)); -} - -TEST(RangeTest, DoesAdjoinOrIntersect) { - RangeT r(3, 4); - - EXPECT_FALSE(r.DoesAdjoinOrIntersect(RangeT(1, 1))); - EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(1, 2))); - EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(2, 2))); - EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(4, 2))); - EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(6, 2))); - EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(7, 2))); - EXPECT_FALSE(r.DoesAdjoinOrIntersect(RangeT(8, 2))); -} - -TEST(RangeTest, DoesIntersect) { - RangeT r(3, 4); - - EXPECT_FALSE(r.DoesIntersect(RangeT(1, 1))); - EXPECT_FALSE(r.DoesIntersect(RangeT(1, 2))); - EXPECT_TRUE(r.DoesIntersect(RangeT(2, 2))); - EXPECT_TRUE(r.DoesIntersect(RangeT(4, 2))); - EXPECT_TRUE(r.DoesIntersect(RangeT(6, 2))); - EXPECT_FALSE(r.DoesIntersect(RangeT(7, 2))); - EXPECT_FALSE(r.DoesIntersect(RangeT(8, 2))); -} - -TEST(RangeTest, LessThan) { - RangeT r(10, 20); - - // Equal range. - EXPECT_FALSE(r < RangeT(10, 20)); - EXPECT_FALSE(RangeT(10, 20) < r); - - auto expect_ordered_less_than = [](RangeT r1, RangeT r2) { - EXPECT_TRUE(r1 < r2); - EXPECT_FALSE(r2 < r1); - }; - - // Same start, but bigger size. - expect_ordered_less_than(r, RangeT(10, 21)); - - // Start before and ends before. - expect_ordered_less_than(RangeT(9, 20), r); - - // Start before and equal size. - expect_ordered_less_than(RangeT(9, 21), r); - - // Start before and bigger size. - expect_ordered_less_than(RangeT(9, 22), r); - - // Start after and ends before. - expect_ordered_less_than(r, RangeT(11, 18)); - - // Start after and equal size. - expect_ordered_less_than(r, RangeT(11, 19)); - - // Start after and bigger size. - expect_ordered_less_than(r, RangeT(11, 20)); -} - -TEST(RangeTest, Equal) { - RangeT r(10, 20); - - // Equal range. - EXPECT_TRUE(r == RangeT(10, 20)); - - // Same start, different size. - EXPECT_FALSE(r == RangeT(10, 21)); - - // Different start, same size. - EXPECT_FALSE(r == RangeT(9, 20)); - - // Different start, different size. - EXPECT_FALSE(r == RangeT(9, 21)); - EXPECT_FALSE(r == RangeT(11, 19)); -} - -TEST(RangeTest, NotEqual) { - RangeT r(10, 20); - - EXPECT_FALSE(r != RangeT(10, 20)); - - EXPECT_TRUE(r != RangeT(10, 21)); - EXPECT_TRUE(r != RangeT(9, 20)); - EXPECT_TRUE(r != RangeT(9, 21)); -} - -// Comparison tests for invalid ranges (size == 0). - -TEST(RangeTest, LessThanInvalid) { - EXPECT_TRUE(RangeT() < RangeT(1, 0)); - EXPECT_TRUE(RangeT() < RangeT(2, 0)); - EXPECT_TRUE(RangeT(1, 0) < RangeT(2, 0)); -} - -TEST(RangeTest, EqualInvalid) { - RangeT r; - EXPECT_TRUE(r == RangeT()); - // Another invalid range, but with a different start. - EXPECT_FALSE(r == RangeT(3, 0)); -} - -TEST(RangeTest, NotEqualInvalid) { - RangeT r; - EXPECT_FALSE(r != RangeT()); - EXPECT_FALSE(r == RangeT(3, 0)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp b/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp deleted file mode 100644 index 5dd39ca04a2..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===-- RegisterValueTest.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 "lldb/Utility/RegisterValue.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using llvm::APInt; - -TEST(RegisterValueTest, GetSet8) { - RegisterValue R8(uint8_t(47)); - EXPECT_EQ(47u, R8.GetAsUInt8()); - R8 = uint8_t(42); - EXPECT_EQ(42u, R8.GetAsUInt8()); - EXPECT_EQ(42u, R8.GetAsUInt16()); - EXPECT_EQ(42u, R8.GetAsUInt32()); - EXPECT_EQ(42u, R8.GetAsUInt64()); -} - -TEST(RegisterValueTest, GetScalarValue) { - using RV = RegisterValue; - const auto &Get = [](const RV &V) -> llvm::Optional { - Scalar S; - if (V.GetScalarValue(S)) - return S; - return llvm::None; - }; - EXPECT_EQ(Get(RV(uint8_t(47))), Scalar(47)); - EXPECT_EQ(Get(RV(uint16_t(4747))), Scalar(4747)); - EXPECT_EQ(Get(RV(uint32_t(47474242))), Scalar(47474242)); - EXPECT_EQ(Get(RV(uint64_t(4747424247474242))), Scalar(4747424247474242)); - EXPECT_EQ(Get(RV(APInt::getMaxValue(128))), Scalar(APInt::getMaxValue(128))); - EXPECT_EQ(Get(RV(47.5f)), Scalar(47.5f)); - EXPECT_EQ(Get(RV(47.5)), Scalar(47.5)); - EXPECT_EQ(Get(RV(47.5L)), Scalar(47.5L)); - EXPECT_EQ(Get(RV({0xff, 0xee, 0xdd, 0xcc}, lldb::eByteOrderLittle)), - Scalar(0xccddeeff)); - EXPECT_EQ(Get(RV({0xff, 0xee, 0xdd, 0xcc}, lldb::eByteOrderBig)), - Scalar(0xffeeddcc)); - EXPECT_EQ(Get(RV({0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, - 0x55, 0x44, 0x33, 0x22, 0x11, 0x00}, - lldb::eByteOrderLittle)), - Scalar((APInt(128, 0x0011223344556677ull) << 64) | - APInt(128, 0x8899aabbccddeeff))); - EXPECT_EQ(Get(RV({0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, - 0x55, 0x44, 0x33, 0x22, 0x11, 0x00}, - lldb::eByteOrderBig)), - Scalar((APInt(128, 0xffeeddccbbaa9988ull) << 64) | - APInt(128, 0x7766554433221100))); -} diff --git a/gnu/llvm/lldb/unittests/Utility/RegularExpressionTest.cpp b/gnu/llvm/lldb/unittests/Utility/RegularExpressionTest.cpp deleted file mode 100644 index 4ac8f4953aa..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/RegularExpressionTest.cpp +++ /dev/null @@ -1,65 +0,0 @@ -//===-- RegularExpressionTest.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 "lldb/Utility/RegularExpression.h" -#include "llvm/ADT/SmallVector.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace llvm; - -TEST(RegularExpression, Valid) { - RegularExpression r1("^[0-9]+$"); - cantFail(r1.GetError()); - EXPECT_TRUE(r1.IsValid()); - EXPECT_EQ("^[0-9]+$", r1.GetText()); - EXPECT_TRUE(r1.Execute("916")); -} - -TEST(RegularExpression, CopyAssignment) { - RegularExpression r1("^[0-9]+$"); - RegularExpression r2 = r1; - cantFail(r2.GetError()); - EXPECT_TRUE(r2.IsValid()); - EXPECT_EQ("^[0-9]+$", r2.GetText()); - EXPECT_TRUE(r2.Execute("916")); -} - -TEST(RegularExpression, Empty) { - RegularExpression r1(""); - Error err = r1.GetError(); - EXPECT_TRUE(static_cast(err)); - consumeError(std::move(err)); - EXPECT_FALSE(r1.IsValid()); - EXPECT_EQ("", r1.GetText()); - EXPECT_FALSE(r1.Execute("916")); -} - -TEST(RegularExpression, Invalid) { - RegularExpression r1("a[b-"); - Error err = r1.GetError(); - EXPECT_TRUE(static_cast(err)); - consumeError(std::move(err)); - EXPECT_FALSE(r1.IsValid()); - EXPECT_EQ("a[b-", r1.GetText()); - EXPECT_FALSE(r1.Execute("ab")); -} - -TEST(RegularExpression, Match) { - RegularExpression r1("[0-9]+([a-f])?:([0-9]+)"); - cantFail(r1.GetError()); - EXPECT_TRUE(r1.IsValid()); - EXPECT_EQ("[0-9]+([a-f])?:([0-9]+)", r1.GetText()); - - SmallVector matches; - EXPECT_TRUE(r1.Execute("9a:513b", &matches)); - EXPECT_EQ(3u, matches.size()); - EXPECT_EQ("9a:513", matches[0].str()); - EXPECT_EQ("a", matches[1].str()); - EXPECT_EQ("513", matches[2].str()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp b/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp deleted file mode 100644 index ce259c5969e..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp +++ /dev/null @@ -1,1167 +0,0 @@ -//===-- ReproducerInstrumentationTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include -#include - -#include "lldb/Utility/ReproducerInstrumentation.h" - -using namespace lldb_private; -using namespace lldb_private::repro; - -struct Foo { - int m = 1; -}; -struct Bar { - double m = 2; -}; - -bool operator==(const Foo &LHS, const Foo &RHS) { return LHS.m == RHS.m; } -bool operator==(const Bar &LHS, const Bar &RHS) { return LHS.m == RHS.m; } - -struct Pod { - bool a = true; - bool b = false; - char c = 'a'; - float d = 1.1f; - int e = 2; - long long f = 3; - long g = 4; - short h = 5; - unsigned char i = 'b'; - unsigned int j = 6; - unsigned long long k = 7; - unsigned long l = 8; - unsigned short m = 9; - - Pod() {} -}; - -class TestingRegistry : public Registry { -public: - TestingRegistry(); -}; - -static std::unique_ptr g_registry; -static llvm::Optional g_serializer; -static llvm::Optional g_deserializer; - -class TestInstrumentationData : public InstrumentationData { -public: - TestInstrumentationData() : InstrumentationData() {} - TestInstrumentationData(Serializer &serializer, Registry ®istry) - : InstrumentationData(serializer, registry) {} - TestInstrumentationData(Deserializer &deserializer, Registry ®istry) - : InstrumentationData(deserializer, registry) {} -}; - -inline TestInstrumentationData GetTestInstrumentationData() { - assert(!(g_serializer && g_deserializer)); - if (g_serializer) - return TestInstrumentationData(*g_serializer, *g_registry); - if (g_deserializer) - return TestInstrumentationData(*g_deserializer, *g_registry); - return TestInstrumentationData(); -} - -class TestInstrumentationDataRAII { -public: - TestInstrumentationDataRAII(llvm::raw_string_ostream &os) { - g_registry = std::make_unique(); - g_serializer.emplace(os); - g_deserializer.reset(); - } - - TestInstrumentationDataRAII(llvm::StringRef buffer) { - g_registry = std::make_unique(); - g_serializer.reset(); - g_deserializer.emplace(buffer); - } - - ~TestInstrumentationDataRAII() { Reset(); } - - void Reset() { - g_registry.reset(); - g_serializer.reset(); - g_deserializer.reset(); - } - - static std::unique_ptr - GetRecordingData(llvm::raw_string_ostream &os) { - return std::make_unique(os); - } - - static std::unique_ptr - GetReplayData(llvm::StringRef buffer) { - return std::make_unique(buffer); - } -}; - -#define LLDB_GET_INSTRUMENTATION_DATA() GetTestInstrumentationData() - -enum class Class { - Foo, - Bar, -}; - -class Instrumented { -public: - virtual ~Instrumented() = default; - virtual void Validate() = 0; - virtual bool IsA(Class c) = 0; -}; - -class InstrumentedFoo : public Instrumented { -public: - InstrumentedFoo() = default; - /// Instrumented methods. - /// { - InstrumentedFoo(int i); - InstrumentedFoo(const InstrumentedFoo &foo); - InstrumentedFoo &operator=(const InstrumentedFoo &foo); - void A(int a); - int GetA(); - void B(int &b) const; - int &GetB(); - int C(float *c); - float GetC(); - int D(const char *d) const; - size_t GetD(char *buffer, size_t length); - static void E(double e); - double GetE(); - static int F(); - bool GetF(); - void Validate() override; - //// } - virtual bool IsA(Class c) override { return c == Class::Foo; } - -private: - int m_a = 0; - mutable int m_b = 0; - float m_c = 0; - mutable std::string m_d = {}; - static double g_e; - static bool g_f; - mutable int m_called = 0; -}; - -class InstrumentedBar : public Instrumented { -public: - /// Instrumented methods. - /// { - InstrumentedBar(); - InstrumentedFoo GetInstrumentedFoo(); - InstrumentedFoo &GetInstrumentedFooRef(); - InstrumentedFoo *GetInstrumentedFooPtr(); - void SetInstrumentedFoo(InstrumentedFoo *foo); - void SetInstrumentedFoo(InstrumentedFoo &foo); - void Validate() override; - /// } - virtual bool IsA(Class c) override { return c == Class::Bar; } - -private: - bool m_get_instrumend_foo_called = false; - InstrumentedFoo *m_foo_set_by_ptr = nullptr; - InstrumentedFoo *m_foo_set_by_ref = nullptr; -}; - -double InstrumentedFoo::g_e = 0; -bool InstrumentedFoo::g_f = false; - -struct Validator { - enum Validation { valid, invalid }; - Validator(Class clazz, Validation validation) - : clazz(clazz), validation(validation) {} - Class clazz; - Validation validation; -}; - -void ValidateObjects(std::vector objects, - std::vector validators) { - ASSERT_EQ(validators.size(), objects.size()); - for (size_t i = 0; i < validators.size(); ++i) { - Validator &validator = validators[i]; - Instrumented *instrumented = static_cast(objects[i]); - EXPECT_TRUE(instrumented->IsA(validator.clazz)); - switch (validator.validation) { - case Validator::valid: - instrumented->Validate(); - break; - case Validator::invalid: - break; - } - } -} - -InstrumentedFoo::InstrumentedFoo(int i) { - LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (int), i); -} - -InstrumentedFoo::InstrumentedFoo(const InstrumentedFoo &foo) { - LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &), foo); -} - -InstrumentedFoo &InstrumentedFoo::operator=(const InstrumentedFoo &foo) { - LLDB_RECORD_METHOD(InstrumentedFoo &, - InstrumentedFoo, operator=,(const InstrumentedFoo &), foo); - return *this; -} - -void InstrumentedFoo::A(int a) { - LLDB_RECORD_METHOD(void, InstrumentedFoo, A, (int), a); - B(a); - m_a = a; -} - -int InstrumentedFoo::GetA() { - LLDB_RECORD_METHOD_NO_ARGS(int, InstrumentedFoo, GetA); - - return m_a; -} - -void InstrumentedFoo::B(int &b) const { - LLDB_RECORD_METHOD_CONST(void, InstrumentedFoo, B, (int &), b); - m_called++; - m_b = b; -} - -int &InstrumentedFoo::GetB() { - LLDB_RECORD_METHOD_NO_ARGS(int &, InstrumentedFoo, GetB); - - return m_b; -} - -int InstrumentedFoo::C(float *c) { - LLDB_RECORD_METHOD(int, InstrumentedFoo, C, (float *), c); - m_c = *c; - return 1; -} - -float InstrumentedFoo::GetC() { - LLDB_RECORD_METHOD_NO_ARGS(float, InstrumentedFoo, GetC); - - return m_c; -} - -int InstrumentedFoo::D(const char *d) const { - LLDB_RECORD_METHOD_CONST(int, InstrumentedFoo, D, (const char *), d); - m_d = std::string(d); - return 2; -} - -size_t InstrumentedFoo::GetD(char *buffer, size_t length) { - LLDB_RECORD_CHAR_PTR_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t), - buffer, "", length); - ::snprintf(buffer, length, "%s", m_d.c_str()); - return m_d.size(); -} - -void InstrumentedFoo::E(double e) { - LLDB_RECORD_STATIC_METHOD(void, InstrumentedFoo, E, (double), e); - g_e = e; -} - -double InstrumentedFoo::GetE() { - LLDB_RECORD_METHOD_NO_ARGS(double, InstrumentedFoo, GetE); - - return g_e; -} - -int InstrumentedFoo::F() { - LLDB_RECORD_STATIC_METHOD_NO_ARGS(int, InstrumentedFoo, F); - g_f = true; - return 3; -} - -bool InstrumentedFoo::GetF() { - LLDB_RECORD_METHOD_NO_ARGS(bool, InstrumentedFoo, GetF); - - return g_f; -} - -void InstrumentedFoo::Validate() { - LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedFoo, Validate); - EXPECT_EQ(m_a, 100); - EXPECT_EQ(m_b, 200); - EXPECT_NEAR(m_c, 300.3, 0.01); - EXPECT_EQ(m_d, "bar"); - EXPECT_NEAR(g_e, 400.4, 0.01); - EXPECT_EQ(g_f, true); - EXPECT_EQ(2, m_called); -} - -InstrumentedBar::InstrumentedBar() { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(InstrumentedBar); -} - -InstrumentedFoo InstrumentedBar::GetInstrumentedFoo() { - LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo, InstrumentedBar, - GetInstrumentedFoo); - m_get_instrumend_foo_called = true; - return LLDB_RECORD_RESULT(InstrumentedFoo(0)); -} - -InstrumentedFoo &InstrumentedBar::GetInstrumentedFooRef() { - LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo &, InstrumentedBar, - GetInstrumentedFooRef); - InstrumentedFoo *foo = new InstrumentedFoo(0); - m_get_instrumend_foo_called = true; - return LLDB_RECORD_RESULT(*foo); -} - -InstrumentedFoo *InstrumentedBar::GetInstrumentedFooPtr() { - LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo *, InstrumentedBar, - GetInstrumentedFooPtr); - InstrumentedFoo *foo = new InstrumentedFoo(0); - m_get_instrumend_foo_called = true; - return LLDB_RECORD_RESULT(foo); -} - -void InstrumentedBar::SetInstrumentedFoo(InstrumentedFoo *foo) { - LLDB_RECORD_METHOD(void, InstrumentedBar, SetInstrumentedFoo, - (InstrumentedFoo *), foo); - m_foo_set_by_ptr = foo; -} - -void InstrumentedBar::SetInstrumentedFoo(InstrumentedFoo &foo) { - LLDB_RECORD_METHOD(void, InstrumentedBar, SetInstrumentedFoo, - (InstrumentedFoo &), foo); - m_foo_set_by_ref = &foo; -} - -void InstrumentedBar::Validate() { - LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedBar, Validate); - - EXPECT_TRUE(m_get_instrumend_foo_called); - EXPECT_NE(m_foo_set_by_ptr, nullptr); - EXPECT_EQ(m_foo_set_by_ptr, m_foo_set_by_ref); -} - -TestingRegistry::TestingRegistry() { - Registry &R = *this; - - LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (int i)); - LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &)); - LLDB_REGISTER_METHOD(InstrumentedFoo &, - InstrumentedFoo, operator=,(const InstrumentedFoo &)); - LLDB_REGISTER_METHOD(void, InstrumentedFoo, A, (int)); - LLDB_REGISTER_METHOD_CONST(void, InstrumentedFoo, B, (int &)); - LLDB_REGISTER_METHOD(int, InstrumentedFoo, C, (float *)); - LLDB_REGISTER_METHOD_CONST(int, InstrumentedFoo, D, (const char *)); - LLDB_REGISTER_STATIC_METHOD(void, InstrumentedFoo, E, (double)); - LLDB_REGISTER_STATIC_METHOD(int, InstrumentedFoo, F, ()); - LLDB_REGISTER_METHOD(void, InstrumentedFoo, Validate, ()); - - LLDB_REGISTER_CONSTRUCTOR(InstrumentedBar, ()); - LLDB_REGISTER_METHOD(InstrumentedFoo, InstrumentedBar, GetInstrumentedFoo, - ()); - LLDB_REGISTER_METHOD(InstrumentedFoo &, InstrumentedBar, - GetInstrumentedFooRef, ()); - LLDB_REGISTER_METHOD(InstrumentedFoo *, InstrumentedBar, - GetInstrumentedFooPtr, ()); - LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo, - (InstrumentedFoo *)); - LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo, - (InstrumentedFoo &)); - LLDB_REGISTER_METHOD(void, InstrumentedBar, Validate, ()); - LLDB_REGISTER_METHOD(int, InstrumentedFoo, GetA, ()); - LLDB_REGISTER_METHOD(int &, InstrumentedFoo, GetB, ()); - LLDB_REGISTER_METHOD(float, InstrumentedFoo, GetC, ()); - LLDB_REGISTER_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t)); - LLDB_REGISTER_METHOD(double, InstrumentedFoo, GetE, ()); - LLDB_REGISTER_METHOD(bool, InstrumentedFoo, GetF, ()); -} - -static const Pod p; - -TEST(IndexToObjectTest, ObjectForIndex) { - IndexToObject index_to_object; - Foo foo; - Bar bar; - - EXPECT_EQ(nullptr, index_to_object.GetObjectForIndex(1)); - EXPECT_EQ(nullptr, index_to_object.GetObjectForIndex(2)); - - index_to_object.AddObjectForIndex(1, foo); - index_to_object.AddObjectForIndex(2, &bar); - - EXPECT_EQ(&foo, index_to_object.GetObjectForIndex(1)); - EXPECT_EQ(&bar, index_to_object.GetObjectForIndex(2)); -} - -TEST(DeserializerTest, HasData) { - { - Deserializer deserializer(""); - EXPECT_FALSE(deserializer.HasData(1)); - } - - { - Deserializer deserializer("a"); - EXPECT_TRUE(deserializer.HasData(1)); - EXPECT_FALSE(deserializer.HasData(2)); - } -} - -TEST(SerializationRountripTest, SerializeDeserializePod) { - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(p.a, p.b, p.c, p.d, p.e, p.f, p.g, p.h, p.i, p.j, p.k, - p.l, p.m); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - EXPECT_EQ(p.a, deserializer.Deserialize()); - EXPECT_EQ(p.b, deserializer.Deserialize()); - EXPECT_EQ(p.c, deserializer.Deserialize()); - EXPECT_EQ(p.d, deserializer.Deserialize()); - EXPECT_EQ(p.e, deserializer.Deserialize()); - EXPECT_EQ(p.f, deserializer.Deserialize()); - EXPECT_EQ(p.g, deserializer.Deserialize()); - EXPECT_EQ(p.h, deserializer.Deserialize()); - EXPECT_EQ(p.i, deserializer.Deserialize()); - EXPECT_EQ(p.j, deserializer.Deserialize()); - EXPECT_EQ(p.k, deserializer.Deserialize()); - EXPECT_EQ(p.l, deserializer.Deserialize()); - EXPECT_EQ(p.m, deserializer.Deserialize()); -} - -TEST(SerializationRountripTest, SerializeDeserializePodPointers) { - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(&p.a, &p.b, &p.c, &p.d, &p.e, &p.f, &p.g, &p.h, &p.i, - &p.j, &p.k, &p.l, &p.m); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - EXPECT_EQ(p.a, *deserializer.Deserialize()); - EXPECT_EQ(p.b, *deserializer.Deserialize()); - EXPECT_EQ(p.c, *deserializer.Deserialize()); - EXPECT_EQ(p.d, *deserializer.Deserialize()); - EXPECT_EQ(p.e, *deserializer.Deserialize()); - EXPECT_EQ(p.f, *deserializer.Deserialize()); - EXPECT_EQ(p.g, *deserializer.Deserialize()); - EXPECT_EQ(p.h, *deserializer.Deserialize()); - EXPECT_EQ(p.i, *deserializer.Deserialize()); - EXPECT_EQ(p.j, *deserializer.Deserialize()); - EXPECT_EQ(p.k, *deserializer.Deserialize()); - EXPECT_EQ(p.l, *deserializer.Deserialize()); - EXPECT_EQ(p.m, *deserializer.Deserialize()); -} - -TEST(SerializationRountripTest, SerializeDeserializePodReferences) { - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(p.a, p.b, p.c, p.d, p.e, p.f, p.g, p.h, p.i, p.j, p.k, - p.l, p.m); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - EXPECT_EQ(p.a, deserializer.Deserialize()); - EXPECT_EQ(p.b, deserializer.Deserialize()); - EXPECT_EQ(p.c, deserializer.Deserialize()); - EXPECT_EQ(p.d, deserializer.Deserialize()); - EXPECT_EQ(p.e, deserializer.Deserialize()); - EXPECT_EQ(p.f, deserializer.Deserialize()); - EXPECT_EQ(p.g, deserializer.Deserialize()); - EXPECT_EQ(p.h, deserializer.Deserialize()); - EXPECT_EQ(p.i, deserializer.Deserialize()); - EXPECT_EQ(p.j, deserializer.Deserialize()); - EXPECT_EQ(p.k, deserializer.Deserialize()); - EXPECT_EQ(p.l, deserializer.Deserialize()); - EXPECT_EQ(p.m, deserializer.Deserialize()); -} - -TEST(SerializationRountripTest, SerializeDeserializeCString) { - const char *cstr = "string"; - - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(cstr); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - EXPECT_STREQ(cstr, deserializer.Deserialize()); -} - -TEST(SerializationRountripTest, SerializeDeserializeCStringNull) { - const char *cstr = nullptr; - - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(cstr); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - EXPECT_EQ(nullptr, deserializer.Deserialize()); -} - -TEST(SerializationRountripTest, SerializeDeserializeCStringArray) { - const char *foo = "foo"; - const char *bar = "bar"; - const char *baz = "baz"; - const char *arr[4] = {foo, bar, baz, nullptr}; - - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(static_cast(arr)); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - const char **deserialized = deserializer.Deserialize(); - EXPECT_STREQ("foo", deserialized[0]); - EXPECT_STREQ("bar", deserialized[1]); - EXPECT_STREQ("baz", deserialized[2]); -} - -TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptrElem) { - const char *arr[1] = {nullptr}; - - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(static_cast(arr)); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - const char **deserialized = deserializer.Deserialize(); - EXPECT_EQ(nullptr, deserialized); -} - -TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptr) { - std::string str; - llvm::raw_string_ostream os(str); - - Serializer serializer(os); - serializer.SerializeAll(static_cast(nullptr)); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - const char **deserialized = deserializer.Deserialize(); - EXPECT_EQ(nullptr, deserialized); -} - -TEST(SerializationRountripTest, SerializeDeserializeObjectPointer) { - Foo foo; - Bar bar; - - std::string str; - llvm::raw_string_ostream os(str); - - unsigned sequence = 123; - - Serializer serializer(os); - serializer.SerializeAll(sequence, static_cast(1)); - serializer.SerializeAll(sequence, static_cast(2)); - serializer.SerializeAll(&foo, &bar); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - deserializer.HandleReplayResult(&foo); - deserializer.HandleReplayResult(&bar); - - EXPECT_EQ(foo, *deserializer.Deserialize()); - EXPECT_EQ(bar, *deserializer.Deserialize()); -} - -TEST(SerializationRountripTest, SerializeDeserializeObjectReference) { - Foo foo; - Bar bar; - - std::string str; - llvm::raw_string_ostream os(str); - - unsigned sequence = 123; - - Serializer serializer(os); - serializer.SerializeAll(sequence, static_cast(1)); - serializer.SerializeAll(sequence, static_cast(2)); - serializer.SerializeAll(foo, bar); - - llvm::StringRef buffer(os.str()); - Deserializer deserializer(buffer); - - deserializer.HandleReplayResult(&foo); - deserializer.HandleReplayResult(&bar); - - EXPECT_EQ(foo, deserializer.Deserialize()); - EXPECT_EQ(bar, deserializer.Deserialize()); -} - -TEST(RecordReplayTest, InstrumentedFoo) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - InstrumentedFoo foo(0); - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - registry.Replay(deserializer); - - ValidateObjects(deserializer.GetAllObjects(), - {{Class::Foo, Validator::valid}}); -} - -TEST(RecordReplayTest, InstrumentedFooSameThis) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - InstrumentedFoo *foo = new InstrumentedFoo(0); - foo->A(100); - foo->B(b); - foo->C(&c); - foo->D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo->Validate(); - foo->~InstrumentedFoo(); - - InstrumentedFoo *foo2 = new (foo) InstrumentedFoo(0); - foo2->A(100); - foo2->B(b); - foo2->C(&c); - foo2->D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo2->Validate(); - delete foo2; - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - registry.Replay(deserializer); - - ValidateObjects(deserializer.GetAllObjects(), - {{Class::Foo, Validator::valid}}); -} - -TEST(RecordReplayTest, InstrumentedBar) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - InstrumentedBar bar; - InstrumentedFoo foo = bar.GetInstrumentedFoo(); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - registry.Replay(deserializer); - - ValidateObjects( - deserializer.GetAllObjects(), - { - {Class::Bar, Validator::valid}, // bar - {Class::Foo, Validator::invalid}, // bar.GetInstrumentedFoo() - {Class::Foo, Validator::valid}, // foo - }); -} - -TEST(RecordReplayTest, InstrumentedBarRef) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - InstrumentedBar bar; - InstrumentedFoo &foo = bar.GetInstrumentedFooRef(); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - registry.Replay(deserializer); - - ValidateObjects( - deserializer.GetAllObjects(), - {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}}); -} - -TEST(RecordReplayTest, InstrumentedBarPtr) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - InstrumentedBar bar; - InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr()); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - registry.Replay(deserializer); - - ValidateObjects( - deserializer.GetAllObjects(), - {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}}); -} - -TEST(PassiveReplayTest, InstrumentedFoo) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - InstrumentedFoo foo(0); - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - } - - std::string buffer = os.str(); - - { - auto data = TestInstrumentationDataRAII::GetReplayData(buffer); - - int b = 999; - float c = 999.9f; - double e = 999.9; - - InstrumentedFoo foo(9); - foo.A(999); - foo.B(b); - foo.C(&c); - foo.D("999"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - } -} - -TEST(PassiveReplayTest, InstrumentedFooInvalid) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - InstrumentedFoo foo(0); - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - } - - std::string buffer = os.str(); - - { - auto data = TestInstrumentationDataRAII::GetReplayData(buffer); - - int b = 999; - float c = 999.9f; - double e = 999.9; - - InstrumentedFoo foo(9); - foo.A(999); - foo.B(b); - foo.C(&c); - foo.D("999"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - // Detect divergence. - EXPECT_DEATH(foo.GetA(), ""); - } -} - -TEST(PassiveReplayTest, InstrumentedBar) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - InstrumentedBar bar; - InstrumentedFoo foo = bar.GetInstrumentedFoo(); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } - - std::string buffer = os.str(); - - { - auto data = TestInstrumentationDataRAII::GetReplayData(buffer); - - InstrumentedBar bar; - InstrumentedFoo foo = bar.GetInstrumentedFoo(); - - int b = 99; - float c = 999.9f; - double e = 999.9; - - foo.A(999); - foo.B(b); - foo.C(&c); - foo.D("999"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } -} - -TEST(PassiveReplayTest, InstrumentedBarRef) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - InstrumentedBar bar; - InstrumentedFoo &foo = bar.GetInstrumentedFooRef(); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } - - std::string buffer = os.str(); - - { - auto data = TestInstrumentationDataRAII::GetReplayData(buffer); - - InstrumentedBar bar; - InstrumentedFoo &foo = bar.GetInstrumentedFooRef(); - - int b = 99; - float c = 999.9f; - double e = 999.9; - - foo.A(999); - foo.B(b); - foo.C(&c); - foo.D("999"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } -} - -TEST(PassiveReplayTest, InstrumentedBarPtr) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - InstrumentedBar bar; - InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr()); - - int b = 200; - float c = 300.3f; - double e = 400.4; - - foo.A(100); - foo.B(b); - foo.C(&c); - foo.D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } - - std::string buffer = os.str(); - - { - auto data = TestInstrumentationDataRAII::GetReplayData(buffer); - - InstrumentedBar bar; - InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr()); - - int b = 99; - float c = 999.9f; - double e = 999.9; - - foo.A(999); - foo.B(b); - foo.C(&c); - foo.D("999"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo.Validate(); - - EXPECT_EQ(foo.GetA(), 100); - EXPECT_EQ(foo.GetB(), 200); - EXPECT_NEAR(foo.GetC(), 300.3, 0.01); - char buffer[100]; - foo.GetD(buffer, 100); - EXPECT_STREQ(buffer, "bar"); - EXPECT_NEAR(foo.GetE(), 400.4, 0.01); - EXPECT_EQ(foo.GetF(), true); - - bar.SetInstrumentedFoo(foo); - bar.SetInstrumentedFoo(&foo); - bar.Validate(); - } -} - -TEST(RecordReplayTest, ValidSequence) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - unsigned sequence = 1; - int (*f)() = &lldb_private::repro::invoke::method< - InstrumentedFoo::F>::record; - unsigned id = g_registry->GetID(uintptr_t(f)); - g_serializer->SerializeAll(sequence, id); - - unsigned result = 0; - g_serializer->SerializeAll(sequence, result); - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - registry.Replay(deserializer); -} - -TEST(RecordReplayTest, InvalidSequence) { - std::string str; - llvm::raw_string_ostream os(str); - - { - auto data = TestInstrumentationDataRAII::GetRecordingData(os); - - unsigned sequence = 1; - int (*f)() = &lldb_private::repro::invoke::method< - InstrumentedFoo::F>::record; - unsigned id = g_registry->GetID(uintptr_t(f)); - g_serializer->SerializeAll(sequence, id); - - unsigned result = 0; - unsigned invalid_sequence = 2; - g_serializer->SerializeAll(invalid_sequence, result); - } - - TestingRegistry registry; - Deserializer deserializer(os.str()); - EXPECT_DEATH(registry.Replay(deserializer), ""); -} diff --git a/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp b/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp deleted file mode 100644 index b276de3bf1a..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp +++ /dev/null @@ -1,262 +0,0 @@ -//===-- ReproducerTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Reproducer.h" -#include "lldb/Utility/ReproducerProvider.h" -#include "llvm/ADT/ScopeExit.h" -#include "llvm/Support/Error.h" -#include "llvm/Testing/Support/Error.h" - -using namespace llvm; -using namespace lldb_private; -using namespace lldb_private::repro; - -class DummyProvider : public repro::Provider { -public: - struct Info { - static const char *name; - static const char *file; - }; - - DummyProvider(const FileSpec &directory) : Provider(directory) {} - - static char ID; -}; - -class YamlMultiProvider - : public MultiProvider { -public: - struct Info { - static const char *name; - static const char *file; - }; - - YamlMultiProvider(const FileSpec &directory) : MultiProvider(directory) {} - - static char ID; -}; - -const char *DummyProvider::Info::name = "dummy"; -const char *DummyProvider::Info::file = "dummy.yaml"; -const char *YamlMultiProvider::Info::name = "mutli"; -const char *YamlMultiProvider::Info::file = "mutli.yaml"; -char DummyProvider::ID = 0; -char YamlMultiProvider::ID = 0; - -class DummyReproducer : public Reproducer { -public: - DummyReproducer() : Reproducer(){}; - - using Reproducer::SetCapture; - using Reproducer::SetReplay; -}; - -struct YamlData { - YamlData() : i(-1) {} - YamlData(int i) : i(i) {} - int i; -}; - -inline bool operator==(const YamlData &LHS, const YamlData &RHS) { - return LHS.i == RHS.i; -} - -LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData) - -namespace llvm { -namespace yaml { -template <> struct MappingTraits { - static void mapping(IO &io, YamlData &Y) { io.mapRequired("i", Y.i); }; -}; -} // namespace yaml -} // namespace llvm - -TEST(ReproducerTest, SetCapture) { - DummyReproducer reproducer; - - // Initially both generator and loader are unset. - EXPECT_EQ(nullptr, reproducer.GetGenerator()); - EXPECT_EQ(nullptr, reproducer.GetLoader()); - - // Enable capture and check that means we have a generator. - EXPECT_THAT_ERROR( - reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), - Succeeded()); - EXPECT_NE(nullptr, reproducer.GetGenerator()); - EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), - reproducer.GetGenerator()->GetRoot()); - EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), - reproducer.GetReproducerPath()); - - // Ensure that we cannot enable replay. - EXPECT_THAT_ERROR( - reproducer.SetReplay(FileSpec("//bogus/path", FileSpec::Style::posix)), - Failed()); - EXPECT_EQ(nullptr, reproducer.GetLoader()); - - // Ensure we can disable the generator again. - EXPECT_THAT_ERROR(reproducer.SetCapture(llvm::None), Succeeded()); - EXPECT_EQ(nullptr, reproducer.GetGenerator()); - EXPECT_EQ(nullptr, reproducer.GetLoader()); -} - -TEST(ReproducerTest, SetReplay) { - DummyReproducer reproducer; - - // Initially both generator and loader are unset. - EXPECT_EQ(nullptr, reproducer.GetGenerator()); - EXPECT_EQ(nullptr, reproducer.GetLoader()); - - // Expected to fail because we can't load the index. - EXPECT_THAT_ERROR( - reproducer.SetReplay(FileSpec("//bogus/path", FileSpec::Style::posix)), - Failed()); - // However the loader should still be set, which we check here. - EXPECT_NE(nullptr, reproducer.GetLoader()); - - // Make sure the bogus path is correctly set. - EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), - reproducer.GetLoader()->GetRoot()); - EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), - reproducer.GetReproducerPath()); - - // Ensure that we cannot enable replay. - EXPECT_THAT_ERROR( - reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), - Failed()); - EXPECT_EQ(nullptr, reproducer.GetGenerator()); -} - -TEST(GeneratorTest, Create) { - DummyReproducer reproducer; - - EXPECT_THAT_ERROR( - reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), - Succeeded()); - auto &generator = *reproducer.GetGenerator(); - - auto *provider = generator.Create(); - EXPECT_NE(nullptr, provider); - EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), - provider->GetRoot()); -} - -TEST(GeneratorTest, Get) { - DummyReproducer reproducer; - - EXPECT_THAT_ERROR( - reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), - Succeeded()); - auto &generator = *reproducer.GetGenerator(); - - auto *provider = generator.Create(); - EXPECT_NE(nullptr, provider); - - auto *provider_alt = generator.Get(); - EXPECT_EQ(provider, provider_alt); -} - -TEST(GeneratorTest, GetOrCreate) { - DummyReproducer reproducer; - - EXPECT_THAT_ERROR( - reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), - Succeeded()); - auto &generator = *reproducer.GetGenerator(); - - auto &provider = generator.GetOrCreate(); - EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), - provider.GetRoot()); - - auto &provider_alt = generator.GetOrCreate(); - EXPECT_EQ(&provider, &provider_alt); -} - -TEST(GeneratorTest, YamlMultiProvider) { - SmallString<128> root; - std::error_code ec = llvm::sys::fs::createUniqueDirectory("reproducer", root); - ASSERT_FALSE(static_cast(ec)); - - auto cleanup = llvm::make_scope_exit( - [&] { EXPECT_FALSE(llvm::sys::fs::remove_directories(root.str())); }); - - YamlData data0(0); - YamlData data1(1); - YamlData data2(2); - YamlData data3(3); - - { - DummyReproducer reproducer; - EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec(root.str())), Succeeded()); - - auto &generator = *reproducer.GetGenerator(); - auto *provider = generator.Create(); - ASSERT_NE(nullptr, provider); - - auto *recorder = provider->GetNewRecorder(); - ASSERT_NE(nullptr, recorder); - recorder->Record(data0); - recorder->Record(data1); - - recorder = provider->GetNewRecorder(); - ASSERT_NE(nullptr, recorder); - recorder->Record(data2); - recorder->Record(data3); - - generator.Keep(); - } - - { - DummyReproducer reproducer; - EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec(root.str())), Succeeded()); - - auto &loader = *reproducer.GetLoader(); - std::unique_ptr> multi_loader = - repro::MultiLoader::Create(&loader); - - // Read the first file. - { - llvm::Optional file = multi_loader->GetNextFile(); - EXPECT_TRUE(static_cast(file)); - - auto buffer = llvm::MemoryBuffer::getFile(*file); - EXPECT_TRUE(static_cast(buffer)); - - yaml::Input yin((*buffer)->getBuffer()); - std::vector data; - yin >> data; - - ASSERT_EQ(data.size(), 2U); - EXPECT_THAT(data, testing::ElementsAre(data0, data1)); - } - - // Read the second file. - { - llvm::Optional file = multi_loader->GetNextFile(); - EXPECT_TRUE(static_cast(file)); - - auto buffer = llvm::MemoryBuffer::getFile(*file); - EXPECT_TRUE(static_cast(buffer)); - - yaml::Input yin((*buffer)->getBuffer()); - std::vector data; - yin >> data; - - ASSERT_EQ(data.size(), 2U); - EXPECT_THAT(data, testing::ElementsAre(data2, data3)); - } - - // There is no third file. - llvm::Optional file = multi_loader->GetNextFile(); - EXPECT_FALSE(static_cast(file)); - } -} diff --git a/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp b/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp deleted file mode 100644 index 1e65cd53573..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp +++ /dev/null @@ -1,402 +0,0 @@ -//===-- ScalarTest.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 "gtest/gtest.h" - -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Endian.h" -#include "lldb/Utility/Scalar.h" -#include "lldb/Utility/Status.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private; -using llvm::APFloat; -using llvm::APInt; -using llvm::Failed; -using llvm::Succeeded; - -template -bool checkInequality(T c1, T c2) { - return (Scalar(c1) != Scalar(c2)); -} - -template -bool checkEquality(T c1, T c2) { - return (Scalar(c1) == Scalar(c2)); -} - -TEST(ScalarTest, Equality) { - ASSERT_TRUE(checkInequality(23, 24)); - ASSERT_TRUE(checkEquality(96, 96)); - ASSERT_TRUE(checkInequality(4.0f, 4.5f)); - ASSERT_TRUE(checkEquality(4.0f, 4.0f)); - - auto apint1 = APInt(64, 234); - auto apint2 = APInt(64, 246); - ASSERT_TRUE(checkInequality(apint1, apint2)); - ASSERT_TRUE(checkEquality(apint1, apint1)); - - Scalar void1; - Scalar void2; - float f1 = 2.0; - ASSERT_TRUE(void1 == void2); - ASSERT_FALSE(void1 == Scalar(f1)); -} - -TEST(ScalarTest, Comparison) { - auto s1 = Scalar(23); - auto s2 = Scalar(46); - ASSERT_TRUE(s1 < s2); - ASSERT_TRUE(s1 <= s2); - ASSERT_TRUE(s2 > s1); - ASSERT_TRUE(s2 >= s1); -} - -TEST(ScalarTest, ComparisonFloat) { - auto s1 = Scalar(23.0f); - auto s2 = Scalar(46.0f); - ASSERT_TRUE(s1 < s2); - ASSERT_TRUE(s1 <= s2); - ASSERT_TRUE(s2 > s1); - ASSERT_TRUE(s2 >= s1); -} - -template static void CheckConversion(T val) { - SCOPED_TRACE("val = " + std::to_string(val)); - EXPECT_EQ((signed char)val, Scalar(val).SChar()); - EXPECT_EQ((unsigned char)val, Scalar(val).UChar()); - EXPECT_EQ((short)val, Scalar(val).SShort()); - EXPECT_EQ((unsigned short)val, Scalar(val).UShort()); - EXPECT_EQ((int)val, Scalar(val).SInt()); - EXPECT_EQ((unsigned)val, Scalar(val).UInt()); - EXPECT_EQ((long)val, Scalar(val).SLong()); - EXPECT_EQ((unsigned long)val, Scalar(val).ULong()); - EXPECT_EQ((long long)val, Scalar(val).SLongLong()); - EXPECT_EQ((unsigned long long)val, Scalar(val).ULongLong()); - EXPECT_NEAR((float)val, Scalar(val).Float(), std::abs(val / 1e6)); - EXPECT_NEAR((double)val, Scalar(val).Double(), std::abs(val / 1e12)); - EXPECT_NEAR((long double)val, Scalar(val).LongDouble(), std::abs(val / 1e12)); -} - -TEST(ScalarTest, Getters) { - CheckConversion(0x87654321); - CheckConversion(0x87654321u); - CheckConversion(0x87654321l); - CheckConversion(0x87654321ul); - CheckConversion(0x8765432112345678ll); - CheckConversion(0x8765432112345678ull); - CheckConversion(42.25f); - CheckConversion(42.25); - CheckConversion(42.25L); - - EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0f, 70.0f)).SInt128(APInt())); - EXPECT_EQ(APInt(128, -1, true) << 70, - Scalar(-std::pow(2.0f, 70.0f)).SInt128(APInt())); - EXPECT_EQ(APInt(128, 1) << 70, - Scalar(std::pow(2.0f, 70.0f)).UInt128(APInt())); - EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0f, 70.0f)).UInt128(APInt())); - - EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).SInt128(APInt())); - EXPECT_EQ(APInt(128, -1, true) << 70, - Scalar(-std::pow(2.0, 70.0)).SInt128(APInt())); - EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).UInt128(APInt())); - EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0, 70.0)).UInt128(APInt())); -} - -TEST(ScalarTest, RightShiftOperator) { - int a = 0x00001000; - int b = 0xFFFFFFFF; - int c = 4; - Scalar a_scalar(a); - Scalar b_scalar(b); - Scalar c_scalar(c); - ASSERT_EQ(a >> c, a_scalar >> c_scalar); - ASSERT_EQ(b >> c, b_scalar >> c_scalar); -} - -TEST(ScalarTest, GetBytes) { - uint8_t Storage[256]; - int a = 0x01020304; - long long b = 0x0102030405060708LL; - float c = 1234567.89e32f; - double d = 1234567.89e42; - char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - char f[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; - Scalar a_scalar(a); - Scalar b_scalar(b); - Scalar c_scalar(c); - Scalar d_scalar(d); - Scalar e_scalar; - Scalar f_scalar; - DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(), - sizeof(void *)); - DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(), - sizeof(void *)); - a_scalar.GetBytes(Storage); - ASSERT_EQ(0, memcmp(&a, Storage, sizeof(a))); - b_scalar.GetBytes(Storage); - ASSERT_EQ(0, memcmp(&b, Storage, sizeof(b))); - c_scalar.GetBytes(Storage); - ASSERT_EQ(0, memcmp(&c, Storage, sizeof(c))); - d_scalar.GetBytes(Storage); - ASSERT_EQ(0, memcmp(&d, Storage, sizeof(d))); - ASSERT_THAT_ERROR( - e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e)) - .ToError(), - llvm::Succeeded()); - e_scalar.GetBytes(Storage); - ASSERT_EQ(0, memcmp(e, Storage, sizeof(e))); - ASSERT_THAT_ERROR( - f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f)) - .ToError(), - llvm::Succeeded()); - f_scalar.GetBytes(Storage); - ASSERT_EQ(0, memcmp(f, Storage, sizeof(f))); -} - -TEST(ScalarTest, SetValueFromData) { - uint8_t a[] = {1, 2, 3, 4}; - Scalar s; - ASSERT_THAT_ERROR( - s.SetValueFromData( - DataExtractor(a, sizeof(a), lldb::eByteOrderLittle, sizeof(void *)), - lldb::eEncodingSint, sizeof(a)) - .ToError(), - llvm::Succeeded()); - EXPECT_EQ(0x04030201, s); - ASSERT_THAT_ERROR( - s.SetValueFromData( - DataExtractor(a, sizeof(a), lldb::eByteOrderBig, sizeof(void *)), - lldb::eEncodingSint, sizeof(a)) - .ToError(), - llvm::Succeeded()); - EXPECT_EQ(0x01020304, s); -} - -TEST(ScalarTest, CastOperations) { - long long a = 0xf1f2f3f4f5f6f7f8LL; - Scalar a_scalar(a); - EXPECT_EQ((signed char)a, a_scalar.SChar()); - EXPECT_EQ((unsigned char)a, a_scalar.UChar()); - EXPECT_EQ((signed short)a, a_scalar.SShort()); - EXPECT_EQ((unsigned short)a, a_scalar.UShort()); - EXPECT_EQ((signed int)a, a_scalar.SInt()); - EXPECT_EQ((unsigned int)a, a_scalar.UInt()); - EXPECT_EQ((signed long)a, a_scalar.SLong()); - EXPECT_EQ((unsigned long)a, a_scalar.ULong()); - EXPECT_EQ((signed long long)a, a_scalar.SLongLong()); - EXPECT_EQ((unsigned long long)a, a_scalar.ULongLong()); - - int a2 = 23; - Scalar a2_scalar(a2); - EXPECT_EQ((float)a2, a2_scalar.Float()); - EXPECT_EQ((double)a2, a2_scalar.Double()); - EXPECT_EQ((long double)a2, a2_scalar.LongDouble()); - - EXPECT_EQ(std::numeric_limits::min(), Scalar(-1.0f).UInt()); - EXPECT_EQ(std::numeric_limits::max(), Scalar(1e11f).UInt()); - EXPECT_EQ(std::numeric_limits::min(), - Scalar(-1.0).ULongLong()); - EXPECT_EQ(std::numeric_limits::max(), - Scalar(1e22).ULongLong()); - - EXPECT_EQ(std::numeric_limits::min(), Scalar(-1e11f).SInt()); - EXPECT_EQ(std::numeric_limits::max(), Scalar(1e11f).SInt()); - EXPECT_EQ(std::numeric_limits::min(), Scalar(-1e22).SLongLong()); - EXPECT_EQ(std::numeric_limits::max(), Scalar(1e22).SLongLong()); -} - -TEST(ScalarTest, ExtractBitfield) { - uint32_t len = sizeof(long long) * 8; - - long long a1 = 0xf1f2f3f4f5f6f7f8LL; - long long b1 = 0xff1f2f3f4f5f6f7fLL; - Scalar s_scalar(a1); - ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0)); - EXPECT_EQ(s_scalar, a1); - ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0)); - EXPECT_EQ(s_scalar, a1); - ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4)); - EXPECT_EQ(s_scalar, b1); - - unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL; - unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL; - Scalar u_scalar(a2); - ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0)); - EXPECT_EQ(u_scalar, a2); - ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0)); - EXPECT_EQ(u_scalar, a2); - ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4)); - EXPECT_EQ(u_scalar, b2); -} - -template static std::string ScalarGetValue(T value) { - StreamString stream; - Scalar(value).GetValue(&stream, false); - return std::string(stream.GetString()); -} - -TEST(ScalarTest, GetValue) { - EXPECT_EQ("12345", ScalarGetValue(12345)); - EXPECT_EQ("-12345", ScalarGetValue(-12345)); - EXPECT_EQ("12345", ScalarGetValue(12345)); - EXPECT_EQ(std::to_string(std::numeric_limits::max()), - ScalarGetValue(std::numeric_limits::max())); - - EXPECT_EQ("12345", ScalarGetValue(12345)); - EXPECT_EQ("-12345", ScalarGetValue(-12345)); - EXPECT_EQ("12345", ScalarGetValue(12345)); - EXPECT_EQ(std::to_string(std::numeric_limits::max()), - ScalarGetValue(std::numeric_limits::max())); - - EXPECT_EQ("12345678", ScalarGetValue(12345678L)); - EXPECT_EQ("-12345678", ScalarGetValue(-12345678L)); - EXPECT_EQ("12345678", ScalarGetValue(12345678UL)); - EXPECT_EQ(std::to_string(std::numeric_limits::max()), - ScalarGetValue(std::numeric_limits::max())); - - EXPECT_EQ("1234567890123", ScalarGetValue(1234567890123LL)); - EXPECT_EQ("-1234567890123", - ScalarGetValue(-1234567890123LL)); - EXPECT_EQ("1234567890123", - ScalarGetValue(1234567890123ULL)); - EXPECT_EQ(std::to_string(std::numeric_limits::max()), - ScalarGetValue(std::numeric_limits::max())); -} - -TEST(ScalarTest, LongLongAssigmentOperator) { - Scalar ull; - ull = std::numeric_limits::max(); - EXPECT_EQ(std::numeric_limits::max(), ull.ULongLong()); - - Scalar sll; - sll = std::numeric_limits::max(); - EXPECT_EQ(std::numeric_limits::max(), sll.SLongLong()); -} - -TEST(ScalarTest, Division) { - Scalar lhs(5.0); - Scalar rhs(2.0); - Scalar r = lhs / rhs; - EXPECT_TRUE(r.IsValid()); - EXPECT_EQ(r, Scalar(2.5)); -} - -TEST(ScalarTest, Promotion) { - Scalar a(47); - EXPECT_TRUE(a.IntegralPromote(64, true)); - EXPECT_TRUE(a.IsSigned()); - EXPECT_EQ(APInt(64, 47), a.UInt128(APInt())); - - EXPECT_FALSE(a.IntegralPromote(32, true)); - EXPECT_FALSE(a.IntegralPromote(32, false)); - EXPECT_TRUE(a.IsSigned()); - - EXPECT_TRUE(a.IntegralPromote(64, false)); - EXPECT_FALSE(a.IsSigned()); - EXPECT_EQ(APInt(64, 47), a.UInt128(APInt())); - - EXPECT_FALSE(a.IntegralPromote(64, true)); - - EXPECT_TRUE(a.FloatPromote(APFloat::IEEEdouble())); - EXPECT_EQ(Scalar::e_float, a.GetType()); - EXPECT_EQ(47.0, a.Double()); - - EXPECT_FALSE(a.FloatPromote(APFloat::IEEEsingle())); - EXPECT_TRUE(a.FloatPromote(APFloat::x87DoubleExtended())); - EXPECT_EQ(47.0L, a.LongDouble()); -} - -TEST(ScalarTest, SetValueFromCString) { - Scalar a; - - EXPECT_THAT_ERROR( - a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(), - Succeeded()); - EXPECT_EQ(1234567890123ull, a); - - EXPECT_THAT_ERROR( - a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(), - Succeeded()); - EXPECT_EQ(-1234567890123ll, a); - - EXPECT_THAT_ERROR( - a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(), - Failed()); - EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890", - lldb::eEncodingUint, 8) - .ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("-2147483648", lldb::eEncodingSint, 4).ToError(), - Succeeded()); - EXPECT_EQ(-2147483648, a); - EXPECT_THAT_ERROR( - a.SetValueFromCString("-2147483649", lldb::eEncodingSint, 4).ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("47.25", lldb::eEncodingIEEE754, 4).ToError(), - Succeeded()); - EXPECT_EQ(47.25f, a); - EXPECT_THAT_ERROR( - a.SetValueFromCString("asdf", lldb::eEncodingIEEE754, 4).ToError(), - Failed()); -} - -TEST(ScalarTest, APIntConstructor) { - for (auto &width : {8, 16, 32}) { - Scalar A(APInt(width, 24)); - EXPECT_TRUE(A.IsSigned()); - EXPECT_EQ(A.GetType(), Scalar::e_int); - EXPECT_EQ(APInt(width, 24), A.UInt128(APInt())); - } -} - -TEST(ScalarTest, Scalar_512) { - Scalar Z(APInt(512, 0)); - ASSERT_TRUE(Z.IsZero()); - Z.MakeUnsigned(); - ASSERT_TRUE(Z.IsZero()); - - Scalar S(APInt(512, 2000)); - ASSERT_STREQ(S.GetTypeAsCString(), "int"); - - ASSERT_TRUE(S.MakeUnsigned()); - EXPECT_EQ(S.GetType(), Scalar::e_int); - EXPECT_FALSE(S.IsSigned()); - ASSERT_STREQ(S.GetTypeAsCString(), "int"); - EXPECT_EQ(S.GetByteSize(), 64U); - - ASSERT_TRUE(S.MakeSigned()); - EXPECT_EQ(S.GetType(), Scalar::e_int); - EXPECT_TRUE(S.IsSigned()); - EXPECT_EQ(S.GetByteSize(), 64U); -} - -TEST(ScalarTest, TruncOrExtendTo) { - Scalar S(0xffff); - S.TruncOrExtendTo(12, true); - EXPECT_EQ(S.UInt128(APInt()), APInt(12, 0xfffu)); - S.TruncOrExtendTo(20, true); - EXPECT_EQ(S.UInt128(APInt()), APInt(20, 0xfffffu)); - S.TruncOrExtendTo(24, false); - EXPECT_EQ(S.UInt128(APInt()), APInt(24, 0x0fffffu)); - S.TruncOrExtendTo(16, false); - EXPECT_EQ(S.UInt128(APInt()), APInt(16, 0xffffu)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/SharedClusterTest.cpp b/gnu/llvm/lldb/unittests/Utility/SharedClusterTest.cpp deleted file mode 100644 index 56dd4da2ed9..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/SharedClusterTest.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===-- SharedClusterTest.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 "lldb/Utility/SharedCluster.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -class DestructNotifier { -public: - DestructNotifier(std::vector &Queue, int Key) : Queue(Queue), Key(Key) {} - ~DestructNotifier() { Queue.push_back(Key); } - - std::vector &Queue; - const int Key; -}; -} // namespace - -TEST(SharedCluster, ClusterManager) { - std::vector Queue; - { - auto CM = ClusterManager::Create(); - auto *One = new DestructNotifier(Queue, 1); - auto *Two = new DestructNotifier(Queue, 2); - CM->ManageObject(One); - CM->ManageObject(Two); - - ASSERT_THAT(Queue, testing::IsEmpty()); - { - std::shared_ptr OnePtr = CM->GetSharedPointer(One); - ASSERT_EQ(OnePtr->Key, 1); - ASSERT_THAT(Queue, testing::IsEmpty()); - - { - std::shared_ptr OnePtrCopy = OnePtr; - ASSERT_EQ(OnePtrCopy->Key, 1); - ASSERT_THAT(Queue, testing::IsEmpty()); - } - - { - std::shared_ptr TwoPtr = CM->GetSharedPointer(Two); - ASSERT_EQ(TwoPtr->Key, 2); - ASSERT_THAT(Queue, testing::IsEmpty()); - } - - ASSERT_THAT(Queue, testing::IsEmpty()); - } - ASSERT_THAT(Queue, testing::IsEmpty()); - } - ASSERT_THAT(Queue, testing::ElementsAre(1, 2)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StateTest.cpp b/gnu/llvm/lldb/unittests/Utility/StateTest.cpp deleted file mode 100644 index d91a23123b0..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StateTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//===-- StateTest.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 "lldb/Utility/State.h" -#include "llvm/Support/FormatVariadic.h" -#include "gtest/gtest.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(StateTest, Formatv) { - EXPECT_EQ("invalid", llvm::formatv("{0}", eStateInvalid).str()); - EXPECT_EQ("unloaded", llvm::formatv("{0}", eStateUnloaded).str()); - EXPECT_EQ("connected", llvm::formatv("{0}", eStateConnected).str()); - EXPECT_EQ("attaching", llvm::formatv("{0}", eStateAttaching).str()); - EXPECT_EQ("launching", llvm::formatv("{0}", eStateLaunching).str()); - EXPECT_EQ("stopped", llvm::formatv("{0}", eStateStopped).str()); - EXPECT_EQ("running", llvm::formatv("{0}", eStateRunning).str()); - EXPECT_EQ("stepping", llvm::formatv("{0}", eStateStepping).str()); - EXPECT_EQ("crashed", llvm::formatv("{0}", eStateCrashed).str()); - EXPECT_EQ("detached", llvm::formatv("{0}", eStateDetached).str()); - EXPECT_EQ("exited", llvm::formatv("{0}", eStateExited).str()); - EXPECT_EQ("suspended", llvm::formatv("{0}", eStateSuspended).str()); - -} diff --git a/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp b/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp deleted file mode 100644 index 9b9d870cd12..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp +++ /dev/null @@ -1,96 +0,0 @@ -//===-- StatusTest.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 "lldb/Utility/Status.h" -#include "gtest/gtest.h" - -#ifdef _WIN32 -#include -#endif - -using namespace lldb_private; -using namespace lldb; - -TEST(StatusTest, Formatv) { - EXPECT_EQ("", llvm::formatv("{0}", Status()).str()); - EXPECT_EQ("Hello Status", llvm::formatv("{0}", Status("Hello Status")).str()); - EXPECT_EQ("Hello", llvm::formatv("{0:5}", Status("Hello Error")).str()); -} - -TEST(StatusTest, ErrorConstructor) { - EXPECT_TRUE(Status(llvm::Error::success()).Success()); - - Status eagain( - llvm::errorCodeToError(std::error_code(EAGAIN, std::generic_category()))); - EXPECT_TRUE(eagain.Fail()); - EXPECT_EQ(eErrorTypePOSIX, eagain.GetType()); - EXPECT_EQ(Status::ValueType(EAGAIN), eagain.GetError()); - - Status foo(llvm::make_error( - "foo", llvm::inconvertibleErrorCode())); - EXPECT_TRUE(foo.Fail()); - EXPECT_EQ(eErrorTypeGeneric, foo.GetType()); - EXPECT_STREQ("foo", foo.AsCString()); - - foo = llvm::Error::success(); - EXPECT_TRUE(foo.Success()); -} - -TEST(StatusTest, ErrorCodeConstructor) { - EXPECT_TRUE(Status(std::error_code()).Success()); - - Status eagain = std::error_code(EAGAIN, std::generic_category()); - EXPECT_TRUE(eagain.Fail()); - EXPECT_EQ(eErrorTypePOSIX, eagain.GetType()); - EXPECT_EQ(Status::ValueType(EAGAIN), eagain.GetError()); -} - -TEST(StatusTest, ErrorConversion) { - EXPECT_FALSE(bool(Status().ToError())); - - llvm::Error eagain = Status(EAGAIN, ErrorType::eErrorTypePOSIX).ToError(); - EXPECT_TRUE(bool(eagain)); - std::error_code ec = llvm::errorToErrorCode(std::move(eagain)); - EXPECT_EQ(EAGAIN, ec.value()); - EXPECT_EQ(std::generic_category(), ec.category()); - - llvm::Error foo = Status("foo").ToError(); - EXPECT_TRUE(bool(foo)); - EXPECT_EQ("foo", llvm::toString(std::move(foo))); -} - -#ifdef _WIN32 -TEST(StatusTest, ErrorWin32) { - auto success = Status(NO_ERROR, ErrorType::eErrorTypeWin32); - EXPECT_STREQ(NULL, success.AsCString()); - EXPECT_FALSE(success.ToError()); - EXPECT_TRUE(success.Success()); - - WCHAR name[128]{}; - ULONG nameLen = llvm::array_lengthof(name); - ULONG langs = 0; - GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &langs, - reinterpret_cast(&name), &nameLen); - // Skip the following tests on non-English, non-US, locales because the - // formatted messages will be different. - bool skip = wcscmp(L"en-US", name) != 0; - - auto s = Status(ERROR_ACCESS_DENIED, ErrorType::eErrorTypeWin32); - EXPECT_TRUE(s.Fail()); - if (!skip) - EXPECT_STREQ("Access is denied. ", s.AsCString()); - - s.SetError(ERROR_IPSEC_IKE_TIMED_OUT, ErrorType::eErrorTypeWin32); - if (!skip) - EXPECT_STREQ("Negotiation timed out ", s.AsCString()); - - s.SetError(16000, ErrorType::eErrorTypeWin32); - if (!skip) - EXPECT_STREQ("unknown error", s.AsCString()); -} -#endif diff --git a/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp b/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp deleted file mode 100644 index e92ee3eb022..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp +++ /dev/null @@ -1,198 +0,0 @@ -//===-- StreamTeeTest.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 "lldb/Utility/StreamTee.h" -#include "lldb/Utility/StreamString.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(StreamTeeTest, DefaultConstructor) { - // Test the default constructor. - StreamTee tee; - ASSERT_EQ(0U, tee.GetNumStreams()); -} - -TEST(StreamTeeTest, Constructor1Stream) { - // Test the constructor for a single stream. - lldb::StreamSP s1(std::make_shared()); - StreamTee tee(s1); - - ASSERT_EQ(1U, tee.GetNumStreams()); - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); -} - -TEST(StreamTeeTest, Constructor2Streams) { - // Test the constructor for two streams. - lldb::StreamSP s1(std::make_shared()); - lldb::StreamSP s2(std::make_shared()); - StreamTee tee(s1, s2); - - ASSERT_EQ(2U, tee.GetNumStreams()); - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); - EXPECT_EQ(s2, tee.GetStreamAtIndex(1U)); -} - -TEST(StreamTeeTest, CopyConstructor) { - // Test the copy constructor. - lldb::StreamSP s1(std::make_shared()); - lldb::StreamSP s2(std::make_shared()); - StreamTee tee1(s1, s2); - StreamTee tee2(tee1); - - ASSERT_EQ(2U, tee2.GetNumStreams()); - EXPECT_EQ(s1, tee2.GetStreamAtIndex(0U)); - EXPECT_EQ(s2, tee2.GetStreamAtIndex(1U)); -} - -TEST(StreamTeeTest, Assignment) { - // Test the assignment of StreamTee. - lldb::StreamSP s1(std::make_shared()); - lldb::StreamSP s2(std::make_shared()); - StreamTee tee1(s1, s2); - StreamTee tee2 = tee1; - - ASSERT_EQ(2U, tee2.GetNumStreams()); - EXPECT_EQ(s1, tee2.GetStreamAtIndex(0U)); - EXPECT_EQ(s2, tee2.GetStreamAtIndex(1U)); -} - -TEST(StreamTeeTest, Write) { - // Test that write is sent out to all children. - auto ss1 = new StreamString(); - auto ss2 = new StreamString(); - lldb::StreamSP s1(ss1); - lldb::StreamSP s2(ss2); - StreamTee tee(s1, s2); - - tee << "foo"; - tee.Flush(); - - ASSERT_EQ(2U, tee.GetNumStreams()); - EXPECT_EQ("foo", ss1->GetString().str()); - EXPECT_EQ("foo", ss2->GetString().str()); - - tee << "bar"; - tee.Flush(); - EXPECT_EQ("foobar", ss1->GetString().str()); - EXPECT_EQ("foobar", ss2->GetString().str()); -} - -namespace { - struct FlushTestStream : public Stream { - unsigned m_flush_count = false; - void Flush() override { - ++m_flush_count; - } - size_t WriteImpl(const void *src, size_t src_len) override { - return src_len; - } - }; -} - -TEST(StreamTeeTest, Flush) { - // Check that Flush is distributed to all streams. - auto fs1 = new FlushTestStream(); - auto fs2 = new FlushTestStream(); - lldb::StreamSP s1(fs1); - lldb::StreamSP s2(fs2); - StreamTee tee(s1, s2); - - tee << "foo"; - tee.Flush(); - - ASSERT_EQ(2U, tee.GetNumStreams()); - EXPECT_EQ(1U, fs1->m_flush_count); - EXPECT_EQ(1U, fs2->m_flush_count); - - tee << "bar"; - tee.Flush(); - EXPECT_EQ(2U, fs1->m_flush_count); - EXPECT_EQ(2U, fs2->m_flush_count); -} - -TEST(StreamTeeTest, AppendStream) { - // Append new streams to our StreamTee. - auto ss1 = new StreamString(); - auto ss2 = new StreamString(); - lldb::StreamSP s1(ss1); - lldb::StreamSP s2(ss2); - - StreamTee tee; - - ASSERT_EQ(0U, tee.GetNumStreams()); - - tee.AppendStream(s1); - ASSERT_EQ(1U, tee.GetNumStreams()); - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); - - tee.AppendStream(s2); - ASSERT_EQ(2U, tee.GetNumStreams()); - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); - EXPECT_EQ(s2, tee.GetStreamAtIndex(1U)); -} - -TEST(StreamTeeTest, GetStreamAtIndexOutOfBounds) { - // The index we check for is not in the bounds of the StreamTee. - lldb::StreamSP s1(std::make_shared()); - StreamTee tee(s1); - - ASSERT_EQ(1U, tee.GetNumStreams()); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1)); -} - -TEST(StreamTeeTest, GetStreamAtIndexOutOfBoundsEmpty) { - // Same as above, but with an empty StreamTee. - StreamTee tee; - ASSERT_EQ(0U, tee.GetNumStreams()); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(0U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U)); -} - -TEST(StreamTeeTest, SetStreamAtIndexOverwrite) { - // We overwrite an existing stream at a given index. - lldb::StreamSP s1(std::make_shared()); - StreamTee tee(s1); - - ASSERT_EQ(1U, tee.GetNumStreams()); - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U)); - - lldb::StreamSP s2(std::make_shared()); - tee.SetStreamAtIndex(0U, s2); - EXPECT_EQ(1U, tee.GetNumStreams()); - EXPECT_EQ(s2, tee.GetStreamAtIndex(0U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1)); -} - -TEST(StreamTeeTest, SetStreamAtIndexOutOfBounds) { - // We place a new stream out of the bounds of the current StreamTee. - lldb::StreamSP s1(std::make_shared()); - StreamTee tee(s1); - - ASSERT_EQ(1U, tee.GetNumStreams()); - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U)); - - // Place a new stream out of bounds of the current array. The StreamTee should - // resize itself until it can contain this index. - lldb::StreamSP s2(std::make_shared()); - tee.SetStreamAtIndex(4U, s2); - // Check that the vector has been resized. - EXPECT_EQ(5U, tee.GetNumStreams()); - // Is our stream at the right place? - EXPECT_EQ(s2, tee.GetStreamAtIndex(4U)); - - // Existing stream should still be there. - EXPECT_EQ(s1, tee.GetStreamAtIndex(0U)); - // Other elements are all invalid StreamSPs. - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(2U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(3U)); - EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(5U)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp b/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp deleted file mode 100644 index 940d49fdfdb..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp +++ /dev/null @@ -1,696 +0,0 @@ -//===-- StreamTest.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 "lldb/Utility/StreamString.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -namespace { -struct StreamTest : ::testing::Test { - // Note: Stream is an abstract class, so we use StreamString to test it. To - // make it easier to change this later, only methods in this class explicitly - // refer to the StringStream class. - StreamString s; - // We return here a std::string because that way gtest can print better - // assertion messages. - std::string TakeValue() { - std::string result = s.GetString().str(); - s.Clear(); - return result; - } -}; -} - -namespace { -// A StreamTest where we expect the Stream output to be binary. -struct BinaryStreamTest : StreamTest { - void SetUp() override { - s.GetFlags().Set(Stream::eBinary); - } -}; -} - -TEST_F(StreamTest, AddressPrefix) { - DumpAddress(s.AsRawOstream(), 0x1, 1, "foo"); - EXPECT_EQ("foo0x01", TakeValue()); -} - -TEST_F(StreamTest, AddressEmptyPrefix) { - DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr); - EXPECT_EQ("0x01", TakeValue()); - DumpAddress(s.AsRawOstream(), 0x1, 1, ""); - EXPECT_EQ("0x01", TakeValue()); -} - -TEST_F(StreamTest, AddressSuffix) { - DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr, "foo"); - EXPECT_EQ("0x01foo", TakeValue()); -} - -TEST_F(StreamTest, AddressNoSuffix) { - DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr, nullptr); - EXPECT_EQ("0x01", TakeValue()); - DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr, ""); - EXPECT_EQ("0x01", TakeValue()); -} - -TEST_F(StreamTest, AddressPrefixAndSuffix) { - DumpAddress(s.AsRawOstream(), 0x1, 1, "foo", "bar"); - EXPECT_EQ("foo0x01bar", TakeValue()); -} - -TEST_F(StreamTest, AddressSize) { - DumpAddress(s.AsRawOstream(), 0x0, 0); - EXPECT_EQ("0x0", TakeValue()); - DumpAddress(s.AsRawOstream(), 0x1, 0); - EXPECT_EQ("0x1", TakeValue()); - - DumpAddress(s.AsRawOstream(), 0x1, 1); - EXPECT_EQ("0x01", TakeValue()); - DumpAddress(s.AsRawOstream(), 0xf1, 1); - EXPECT_EQ("0xf1", TakeValue()); - DumpAddress(s.AsRawOstream(), 0xff, 1); - EXPECT_EQ("0xff", TakeValue()); - DumpAddress(s.AsRawOstream(), 0x100, 1); - EXPECT_EQ("0x100", TakeValue()); - - DumpAddress(s.AsRawOstream(), 0xf00, 4); - EXPECT_EQ("0x00000f00", TakeValue()); - DumpAddress(s.AsRawOstream(), 0x100, 8); - EXPECT_EQ("0x0000000000000100", TakeValue()); -} - -TEST_F(StreamTest, AddressRange) { - DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 2); - EXPECT_EQ("[0x0100-0x0101)", TakeValue()); -} - -TEST_F(StreamTest, AddressRangeEmptyRange) { - DumpAddressRange(s.AsRawOstream(), 0x100, 0x100, 2); - EXPECT_EQ("[0x0100-0x0100)", TakeValue()); - DumpAddressRange(s.AsRawOstream(), 0x0, 0x0, 2); - EXPECT_EQ("[0x0000-0x0000)", TakeValue()); -} - -TEST_F(StreamTest, AddressRangeInvalidRange) { - DumpAddressRange(s.AsRawOstream(), 0x100, 0x0FF, 2); - EXPECT_EQ("[0x0100-0x00ff)", TakeValue()); - DumpAddressRange(s.AsRawOstream(), 0x100, 0x0, 2); - EXPECT_EQ("[0x0100-0x0000)", TakeValue()); -} - -TEST_F(StreamTest, AddressRangeSize) { - DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 0); - EXPECT_EQ("[0x100-0x101)", TakeValue()); - DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 2); - EXPECT_EQ("[0x0100-0x0101)", TakeValue()); - DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 4); - EXPECT_EQ("[0x00000100-0x00000101)", TakeValue()); - - DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 4); - EXPECT_EQ("[0x00000100-0x00000101)", TakeValue()); - DumpAddressRange(s.AsRawOstream(), 0x1, 0x101, 4); - EXPECT_EQ("[0x00000001-0x00000101)", TakeValue()); - DumpAddressRange(s.AsRawOstream(), 0x101, 0x1, 4); - EXPECT_EQ("[0x00000101-0x00000001)", TakeValue()); - - DumpAddressRange(s.AsRawOstream(), 0x1, 0x101, 1); - EXPECT_EQ("[0x01-0x101)", TakeValue()); -} - -TEST_F(StreamTest, ChangingByteOrder) { - s.SetByteOrder(lldb::eByteOrderPDP); - EXPECT_EQ(lldb::eByteOrderPDP, s.GetByteOrder()); -} - -TEST_F(StreamTest, SetIndentLevel) { - s.Indent("a"); - EXPECT_EQ("a", TakeValue()); - - s.SetIndentLevel(3); - s.Indent("a"); - EXPECT_EQ(" a", TakeValue()); - - s.SetIndentLevel(2); - s.Indent("a"); - EXPECT_EQ(" a", TakeValue()); - - s.SetIndentLevel(0); - s.Indent("a"); - EXPECT_EQ("a", TakeValue()); -} - -TEST_F(StreamTest, Indent) { - s.SetIndentLevel(2); - const char *nullptr_cstring = nullptr; - s.Indent(nullptr_cstring); - EXPECT_EQ(" ", TakeValue()); - - s.Indent(""); - EXPECT_EQ(" ", TakeValue()); - - s.Indent(" "); - EXPECT_EQ(" ", TakeValue()); - - s.Indent(" aa"); - EXPECT_EQ(" aa", TakeValue()); -} - -TEST_F(StreamTest, PutChar) { - s.PutChar('a'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("a", TakeValue()); - - s.PutChar('1'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("1", TakeValue()); -} - -TEST_F(StreamTest, PutCharWhitespace) { - s.PutChar(' '); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(" ", TakeValue()); - - s.PutChar('\n'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("\n", TakeValue()); - - s.PutChar('\r'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("\r", TakeValue()); - - s.PutChar('\t'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("\t", TakeValue()); -} - -TEST_F(StreamTest, PutCString) { - s.PutCString(""); - EXPECT_EQ(0U, s.GetWrittenBytes()); - EXPECT_EQ("", TakeValue()); - - s.PutCString("foobar"); - EXPECT_EQ(6U, s.GetWrittenBytes()); - EXPECT_EQ("foobar", TakeValue()); - - s.PutCString(" "); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(" ", TakeValue()); -} - -TEST_F(StreamTest, PutCStringWithStringRef) { - s.PutCString(llvm::StringRef("")); - EXPECT_EQ(0U, s.GetWrittenBytes()); - EXPECT_EQ("", TakeValue()); - - s.PutCString(llvm::StringRef("foobar")); - EXPECT_EQ(6U, s.GetWrittenBytes()); - EXPECT_EQ("foobar", TakeValue()); - - s.PutCString(llvm::StringRef(" ")); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(" ", TakeValue()); -} - -TEST_F(StreamTest, QuotedCString) { - s.QuotedCString("foo"); - EXPECT_EQ(5U, s.GetWrittenBytes()); - EXPECT_EQ(R"("foo")", TakeValue()); - - s.QuotedCString("ba r"); - EXPECT_EQ(6U, s.GetWrittenBytes()); - EXPECT_EQ(R"("ba r")", TakeValue()); - - s.QuotedCString(" "); - EXPECT_EQ(3U, s.GetWrittenBytes()); - EXPECT_EQ(R"(" ")", TakeValue()); -} - -TEST_F(StreamTest, PutCharNull) { - s.PutChar('\0'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("\0", 1), TakeValue()); - - s.PutChar('a'); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("a", 1), TakeValue()); -} - -TEST_F(StreamTest, PutStringAsRawHex8) { - s.PutStringAsRawHex8(""); - EXPECT_EQ(0U, s.GetWrittenBytes()); - EXPECT_EQ("", TakeValue()); - - s.PutStringAsRawHex8("foobar"); - EXPECT_EQ(12U, s.GetWrittenBytes()); - EXPECT_EQ("666f6f626172", TakeValue()); - - s.PutStringAsRawHex8(" "); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("20", TakeValue()); -} - -TEST_F(StreamTest, PutHex8) { - s.PutHex8((uint8_t)55); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("37", TakeValue()); - - s.PutHex8(std::numeric_limits::max()); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("ff", TakeValue()); - - s.PutHex8((uint8_t)0); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("00", TakeValue()); -} - -TEST_F(StreamTest, PutNHex8) { - s.PutNHex8(0, (uint8_t)55); - EXPECT_EQ(0U, s.GetWrittenBytes()); - EXPECT_EQ("", TakeValue()); - - s.PutNHex8(1, (uint8_t)55); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("37", TakeValue()); - - s.PutNHex8(2, (uint8_t)55); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("3737", TakeValue()); - - s.PutNHex8(1, (uint8_t)56); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("38", TakeValue()); -} - -TEST_F(StreamTest, PutHex16ByteOrderLittle) { - s.PutHex16(0x1234U, lldb::eByteOrderLittle); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("3412", TakeValue()); - - s.PutHex16(std::numeric_limits::max(), lldb::eByteOrderLittle); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("ffff", TakeValue()); - - s.PutHex16(0U, lldb::eByteOrderLittle); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("0000", TakeValue()); -} - -TEST_F(StreamTest, PutHex16ByteOrderBig) { - s.PutHex16(0x1234U, lldb::eByteOrderBig); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("1234", TakeValue()); - - s.PutHex16(std::numeric_limits::max(), lldb::eByteOrderBig); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("ffff", TakeValue()); - - s.PutHex16(0U, lldb::eByteOrderBig); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("0000", TakeValue()); -} - -TEST_F(StreamTest, PutHex32ByteOrderLittle) { - s.PutHex32(0x12345678U, lldb::eByteOrderLittle); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("78563412", TakeValue()); - - s.PutHex32(std::numeric_limits::max(), lldb::eByteOrderLittle); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("ffffffff", TakeValue()); - - s.PutHex32(0U, lldb::eByteOrderLittle); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("00000000", TakeValue()); -} - -TEST_F(StreamTest, PutHex32ByteOrderBig) { - s.PutHex32(0x12345678U, lldb::eByteOrderBig); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("12345678", TakeValue()); - - s.PutHex32(std::numeric_limits::max(), lldb::eByteOrderBig); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("ffffffff", TakeValue()); - - s.PutHex32(0U, lldb::eByteOrderBig); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("00000000", TakeValue()); -} - -TEST_F(StreamTest, PutHex64ByteOrderLittle) { - s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderLittle); - EXPECT_EQ(16U, s.GetWrittenBytes()); - EXPECT_EQ("efcdab9078563412", TakeValue()); - - s.PutHex64(std::numeric_limits::max(), lldb::eByteOrderLittle); - EXPECT_EQ(16U, s.GetWrittenBytes()); - EXPECT_EQ("ffffffffffffffff", TakeValue()); - - s.PutHex64(0U, lldb::eByteOrderLittle); - EXPECT_EQ(16U, s.GetWrittenBytes()); - EXPECT_EQ("0000000000000000", TakeValue()); -} - -TEST_F(StreamTest, PutHex64ByteOrderBig) { - s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderBig); - EXPECT_EQ(16U, s.GetWrittenBytes()); - EXPECT_EQ("1234567890abcdef", TakeValue()); - - s.PutHex64(std::numeric_limits::max(), lldb::eByteOrderBig); - EXPECT_EQ(16U, s.GetWrittenBytes()); - EXPECT_EQ("ffffffffffffffff", TakeValue()); - - s.PutHex64(0U, lldb::eByteOrderBig); - EXPECT_EQ(16U, s.GetWrittenBytes()); - EXPECT_EQ("0000000000000000", TakeValue()); -} - -TEST_F(StreamTest, PutMaxHex64ByteOrderBig) { - std::size_t bytes; - bytes = s.PutMaxHex64(0x12U, 1, lldb::eByteOrderBig); - EXPECT_EQ(2U, bytes); - bytes = s.PutMaxHex64(0x1234U, 2, lldb::eByteOrderBig); - EXPECT_EQ(4U, bytes); - bytes = s.PutMaxHex64(0x12345678U, 4, lldb::eByteOrderBig); - EXPECT_EQ(8U, bytes); - bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderBig); - EXPECT_EQ(16U, bytes); - EXPECT_EQ(30U, s.GetWrittenBytes()); - EXPECT_EQ("121234123456781234567890abcdef", TakeValue()); -} - -TEST_F(StreamTest, PutMaxHex64ByteOrderLittle) { - std::size_t bytes; - bytes = s.PutMaxHex64(0x12U, 1, lldb::eByteOrderLittle); - EXPECT_EQ(2U, bytes); - bytes = s.PutMaxHex64(0x1234U, 2, lldb::eByteOrderLittle); - EXPECT_EQ(4U, bytes); - bytes = s.PutMaxHex64(0x12345678U, 4, lldb::eByteOrderLittle); - EXPECT_EQ(8U, bytes); - bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderLittle); - EXPECT_EQ(16U, bytes); - EXPECT_EQ(30U, s.GetWrittenBytes()); - EXPECT_EQ("12341278563412efcdab9078563412", TakeValue()); -} - -// Shift operator tests. - -TEST_F(StreamTest, ShiftOperatorChars) { - s << 'a' << 'b'; - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("ab", TakeValue()); -} - -TEST_F(StreamTest, ShiftOperatorStrings) { - s << "cstring\n"; - EXPECT_EQ(8U, s.GetWrittenBytes()); - s << llvm::StringRef("llvm::StringRef\n"); - EXPECT_EQ(24U, s.GetWrittenBytes()); - EXPECT_EQ("cstring\nllvm::StringRef\n", TakeValue()); -} - -TEST_F(StreamTest, ShiftOperatorPtr) { - // This test is a bit tricky because pretty much everything related to - // pointer printing seems to lead to UB or IB. So let's make the most basic - // test that just checks that we print *something*. This way we at least know - // that pointer printing doesn't do really bad things (e.g. crashing, reading - // OOB/uninitialized memory which the sanitizers would spot). - - // Shift our own pointer to the output. - int i = 3; - int *ptr = &i; - s << ptr; - - EXPECT_NE(0U, s.GetWrittenBytes()); - EXPECT_TRUE(!TakeValue().empty()); -} - -TEST_F(StreamTest, PutPtr) { - // See the ShiftOperatorPtr test for the rationale. - int i = 3; - int *ptr = &i; - s.PutPointer(ptr); - - EXPECT_NE(0U, s.GetWrittenBytes()); - EXPECT_TRUE(!TakeValue().empty()); -} - -// Alias to make it more clear that 'invalid' means for the Stream interface -// that it should use the host byte order. -const static auto hostByteOrder = lldb::eByteOrderInvalid; - -// PutRawBytes/PutBytesAsRawHex tests. - -TEST_F(StreamTest, PutBytesAsRawHex8ToBigEndian) { - uint32_t value = 0x12345678; - s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), - hostByteOrder, lldb::eByteOrderBig); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("78563412", TakeValue()); -} - -TEST_F(StreamTest, PutRawBytesToBigEndian) { - uint32_t value = 0x12345678; - s.PutRawBytes(static_cast(&value), sizeof(value), - hostByteOrder, lldb::eByteOrderBig); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("\x78\x56\x34\x12", TakeValue()); -} - -TEST_F(StreamTest, PutBytesAsRawHex8ToLittleEndian) { - uint32_t value = 0x12345678; - s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), - hostByteOrder, lldb::eByteOrderLittle); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("12345678", TakeValue()); -} - -TEST_F(StreamTest, PutRawBytesToLittleEndian) { - uint32_t value = 0x12345678; - s.PutRawBytes(static_cast(&value), sizeof(value), - hostByteOrder, lldb::eByteOrderLittle); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("\x12\x34\x56\x78", TakeValue()); -} - -TEST_F(StreamTest, PutBytesAsRawHex8ToMixedEndian) { - uint32_t value = 0x12345678; - s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), - hostByteOrder, lldb::eByteOrderPDP); - - // FIXME: PDP byte order is not actually implemented but Stream just silently - // prints the value in some random byte order... -#if 0 - EXPECT_EQ("34127856", TakeValue()); -#endif -} - -TEST_F(StreamTest, PutRawBytesToMixedEndian) { - uint32_t value = 0x12345678; - s.PutRawBytes(static_cast(&value), sizeof(value), - lldb::eByteOrderInvalid, lldb::eByteOrderPDP); - - // FIXME: PDP byte order is not actually implemented but Stream just silently - // prints the value in some random byte order... -#if 0 - EXPECT_EQ("\x34\x12\x78\x56", TakeValue()); -#endif -} - -// ULEB128 support for binary streams. - -TEST_F(BinaryStreamTest, PutULEB128OneByte) { - auto bytes = s.PutULEB128(0x74ULL); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("\x74", TakeValue()); - EXPECT_EQ(1U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128TwoBytes) { - auto bytes = s.PutULEB128(0x1985ULL); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("\x85\x33", TakeValue()); - EXPECT_EQ(2U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128ThreeBytes) { - auto bytes = s.PutULEB128(0x5023ULL); - EXPECT_EQ(3U, s.GetWrittenBytes()); - EXPECT_EQ("\xA3\xA0\x1", TakeValue()); - EXPECT_EQ(3U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128FourBytes) { - auto bytes = s.PutULEB128(0xA48032ULL); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("\xB2\x80\x92\x5", TakeValue()); - EXPECT_EQ(4U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128FiveBytes) { - auto bytes = s.PutULEB128(0x12345678ULL); - EXPECT_EQ(5U, s.GetWrittenBytes()); - EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue()); - EXPECT_EQ(5U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128SixBytes) { - auto bytes = s.PutULEB128(0xABFE3FAFDFULL); - EXPECT_EQ(6U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue()); - EXPECT_EQ(6U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128SevenBytes) { - auto bytes = s.PutULEB128(0xDABFE3FAFDFULL); - EXPECT_EQ(7U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue()); - EXPECT_EQ(7U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128EightBytes) { - auto bytes = s.PutULEB128(0x7CDABFE3FAFDFULL); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue()); - EXPECT_EQ(8U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128NineBytes) { - auto bytes = s.PutULEB128(0x327CDABFE3FAFDFULL); - EXPECT_EQ(9U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue()); - EXPECT_EQ(9U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128MaxValue) { - auto bytes = s.PutULEB128(std::numeric_limits::max()); - EXPECT_EQ(10U, s.GetWrittenBytes()); - EXPECT_EQ("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1", TakeValue()); - EXPECT_EQ(10U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128Zero) { - auto bytes = s.PutULEB128(0x0U); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("\0", 1), TakeValue()); - EXPECT_EQ(1U, bytes); -} - -TEST_F(BinaryStreamTest, PutULEB128One) { - auto bytes = s.PutULEB128(0x1U); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ("\x1", TakeValue()); - EXPECT_EQ(1U, bytes); -} - -// SLEB128 support for binary streams. - -TEST_F(BinaryStreamTest, PutSLEB128OneByte) { - auto bytes = s.PutSLEB128(0x74LL); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("\xF4\0", 2), TakeValue()); - EXPECT_EQ(2U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128TwoBytes) { - auto bytes = s.PutSLEB128(0x1985LL); - EXPECT_EQ(2U, s.GetWrittenBytes()); - EXPECT_EQ("\x85\x33", TakeValue()); - EXPECT_EQ(2U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128ThreeBytes) { - auto bytes = s.PutSLEB128(0x5023LL); - EXPECT_EQ(3U, s.GetWrittenBytes()); - EXPECT_EQ("\xA3\xA0\x1", TakeValue()); - EXPECT_EQ(3U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128FourBytes) { - auto bytes = s.PutSLEB128(0xA48032LL); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("\xB2\x80\x92\x5", TakeValue()); - EXPECT_EQ(4U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128FiveBytes) { - auto bytes = s.PutSLEB128(0x12345678LL); - EXPECT_EQ(5U, s.GetWrittenBytes()); - EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue()); - EXPECT_EQ(5U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128SixBytes) { - auto bytes = s.PutSLEB128(0xABFE3FAFDFLL); - EXPECT_EQ(6U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue()); - EXPECT_EQ(6U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128SevenBytes) { - auto bytes = s.PutSLEB128(0xDABFE3FAFDFLL); - EXPECT_EQ(7U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue()); - EXPECT_EQ(7U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128EightBytes) { - auto bytes = s.PutSLEB128(0x7CDABFE3FAFDFLL); - EXPECT_EQ(8U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue()); - EXPECT_EQ(8U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128NineBytes) { - auto bytes = s.PutSLEB128(0x327CDABFE3FAFDFLL); - EXPECT_EQ(9U, s.GetWrittenBytes()); - EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue()); - EXPECT_EQ(9U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128MaxValue) { - auto bytes = s.PutSLEB128(std::numeric_limits::max()); - EXPECT_EQ(10U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0", 10), TakeValue()); - EXPECT_EQ(10U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128Zero) { - auto bytes = s.PutSLEB128(0x0); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("\0", 1), TakeValue()); - EXPECT_EQ(1U, bytes); -} - -TEST_F(BinaryStreamTest, PutSLEB128One) { - auto bytes = s.PutSLEB128(0x1); - EXPECT_EQ(1U, s.GetWrittenBytes()); - EXPECT_EQ(std::string("\x1", 1), TakeValue()); - EXPECT_EQ(1U, bytes); -} - -// SLEB128/ULEB128 support for non-binary streams. - -// The logic for this is very simple, so it should be enough to test some basic -// use cases. - -TEST_F(StreamTest, PutULEB128) { - auto bytes = s.PutULEB128(0x74ULL); - EXPECT_EQ(4U, s.GetWrittenBytes()); - EXPECT_EQ("0x74", TakeValue()); - EXPECT_EQ(4U, bytes); -} - -TEST_F(StreamTest, PutSLEB128) { - auto bytes = s.PutSLEB128(0x1985LL); - EXPECT_EQ(6U, s.GetWrittenBytes()); - EXPECT_EQ("0x6533", TakeValue()); - EXPECT_EQ(6U, bytes); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StringExtractorGDBRemoteTest.cpp b/gnu/llvm/lldb/unittests/Utility/StringExtractorGDBRemoteTest.cpp deleted file mode 100644 index 88362c028a9..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StringExtractorGDBRemoteTest.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include - -#include "lldb/Utility/StringExtractorGDBRemote.h" -#include "lldb/lldb-defines.h" - -TEST(StringExtractorGDBRemoteTest, GetPidTid) { - StringExtractorGDBRemote ex(""); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - // invalid/short values - - ex.Reset("narf"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset(";1234"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset(".1234"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("pnarf"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p;1234"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p.1234"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p1234."); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p1234.;1234"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("-2"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p1234.-2"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p-2"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p-2.1234"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - // overflow - - ex.Reset("p10000000000000000"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p10000000000000000.0"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("10000000000000000"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p0.10000000000000000"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - ex.Reset("p10000000000000000.10000000000000000"); - EXPECT_EQ(ex.GetPidTid(0), llvm::None); - - // invalid: all processes but specific thread - - ex.Reset("p-1.0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p-1.1234"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p-1.123456789ABCDEF0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - // unsupported: pid/tid 0 - - ex.Reset("0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p0.0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p0.-1"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p0.1234"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p0.123456789ABCDEF0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p1234.0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - ex.Reset("p123456789ABCDEF0.0"); - EXPECT_EQ(ex.GetPidTid(100), llvm::None); - - // pure thread id - - ex.Reset("-1"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(100, StringExtractorGDBRemote::AllThreads)); - - ex.Reset("1234"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), ::testing::Pair(100, 0x1234ULL)); - - ex.Reset("123456789ABCDEF0"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(100, 0x123456789ABCDEF0ULL)); - - // pure process id - - ex.Reset("p-1"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(StringExtractorGDBRemote::AllProcesses, - StringExtractorGDBRemote::AllThreads)); - - ex.Reset("p1234"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x1234ULL, StringExtractorGDBRemote::AllThreads)); - - ex.Reset("p123456789ABCDEF0"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x123456789ABCDEF0ULL, - StringExtractorGDBRemote::AllThreads)); - - ex.Reset("pFFFFFFFFFFFFFFFF"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(StringExtractorGDBRemote::AllProcesses, - StringExtractorGDBRemote::AllThreads)); - - // combined thread id + process id - - ex.Reset("p-1.-1"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(StringExtractorGDBRemote::AllProcesses, - StringExtractorGDBRemote::AllThreads)); - - ex.Reset("p1234.-1"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x1234ULL, StringExtractorGDBRemote::AllThreads)); - - ex.Reset("p1234.123456789ABCDEF0"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x1234ULL, 0x123456789ABCDEF0ULL)); - - ex.Reset("p123456789ABCDEF0.-1"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x123456789ABCDEF0ULL, - StringExtractorGDBRemote::AllThreads)); - - ex.Reset("p123456789ABCDEF0.1234"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x123456789ABCDEF0ULL, 0x1234ULL)); - - ex.Reset("p123456789ABCDEF0.123456789ABCDEF0"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x123456789ABCDEF0ULL, 0x123456789ABCDEF0ULL)); - - ex.Reset("p123456789ABCDEF0.123456789ABCDEF0"); - EXPECT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x123456789ABCDEF0ULL, 0x123456789ABCDEF0ULL)); -} - -TEST(StringExtractorGDBRemoteTest, GetPidTidMultipleValues) { - StringExtractorGDBRemote ex("1234;p12;p1234.-1"); - ASSERT_THAT(ex.GetPidTid(100).getValue(), ::testing::Pair(100, 0x1234ULL)); - ASSERT_EQ(ex.GetChar(), ';'); - ASSERT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x12ULL, StringExtractorGDBRemote::AllThreads)); - ASSERT_EQ(ex.GetChar(), ';'); - ASSERT_THAT(ex.GetPidTid(100).getValue(), - ::testing::Pair(0x1234ULL, StringExtractorGDBRemote::AllThreads)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StringExtractorTest.cpp b/gnu/llvm/lldb/unittests/Utility/StringExtractorTest.cpp deleted file mode 100644 index 1908cf37b07..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StringExtractorTest.cpp +++ /dev/null @@ -1,697 +0,0 @@ -#include "gtest/gtest.h" -#include - -#include "lldb/Utility/StringExtractor.h" - -namespace { -class StringExtractorTest : public ::testing::Test {}; -} // namespace - -TEST_F(StringExtractorTest, InitEmpty) { - llvm::StringRef kEmptyString = ""; - StringExtractor ex(kEmptyString); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(kEmptyString, ex.GetStringRef()); - ASSERT_EQ(true, ex.Empty()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, InitMisc) { - llvm::StringRef kInitMiscString = "Hello, StringExtractor!"; - StringExtractor ex(kInitMiscString); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(kInitMiscString, ex.GetStringRef()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(kInitMiscString.size(), ex.GetBytesLeft()); - ASSERT_EQ(kInitMiscString[0], *ex.Peek()); -} - -TEST_F(StringExtractorTest, DecodeHexU8_Underflow) { - llvm::StringRef kEmptyString = ""; - StringExtractor ex(kEmptyString); - - ASSERT_EQ(-1, ex.DecodeHexU8()); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(true, ex.Empty()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, DecodeHexU8_Underflow2) { - StringExtractor ex("1"); - - ASSERT_EQ(-1, ex.DecodeHexU8()); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(1u, ex.GetBytesLeft()); - ASSERT_EQ('1', *ex.Peek()); -} - -TEST_F(StringExtractorTest, DecodeHexU8_InvalidHex) { - llvm::StringRef kInvalidHex = "xa"; - StringExtractor ex(kInvalidHex); - - ASSERT_EQ(-1, ex.DecodeHexU8()); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(2u, ex.GetBytesLeft()); - ASSERT_EQ('x', *ex.Peek()); -} - -TEST_F(StringExtractorTest, DecodeHexU8_InvalidHex2) { - llvm::StringRef kInvalidHex = "ax"; - StringExtractor ex(kInvalidHex); - - ASSERT_EQ(-1, ex.DecodeHexU8()); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(2u, ex.GetBytesLeft()); - ASSERT_EQ('a', *ex.Peek()); -} - -TEST_F(StringExtractorTest, DecodeHexU8_Exact) { - llvm::StringRef kValidHexPair = "12"; - StringExtractor ex(kValidHexPair); - - ASSERT_EQ(0x12, ex.DecodeHexU8()); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2u, ex.GetFilePos()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, DecodeHexU8_Extra) { - llvm::StringRef kValidHexPair = "1234"; - StringExtractor ex(kValidHexPair); - - ASSERT_EQ(0x12, ex.DecodeHexU8()); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2u, ex.GetFilePos()); - ASSERT_EQ(2u, ex.GetBytesLeft()); - ASSERT_EQ('3', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Underflow) { - llvm::StringRef kEmptyString = ""; - StringExtractor ex(kEmptyString); - - ASSERT_EQ(0xab, ex.GetHexU8(0xab)); - ASSERT_EQ(false, ex.IsGood()); - ASSERT_EQ(UINT64_MAX, ex.GetFilePos()); - ASSERT_EQ(true, ex.Empty()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Underflow2) { - llvm::StringRef kOneNibble = "1"; - StringExtractor ex(kOneNibble); - - ASSERT_EQ(0xbc, ex.GetHexU8(0xbc)); - ASSERT_EQ(false, ex.IsGood()); - ASSERT_EQ(UINT64_MAX, ex.GetFilePos()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_InvalidHex) { - llvm::StringRef kInvalidHex = "xx"; - StringExtractor ex(kInvalidHex); - - ASSERT_EQ(0xcd, ex.GetHexU8(0xcd)); - ASSERT_EQ(false, ex.IsGood()); - ASSERT_EQ(UINT64_MAX, ex.GetFilePos()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Exact) { - llvm::StringRef kValidHexPair = "12"; - StringExtractor ex(kValidHexPair); - - ASSERT_EQ(0x12, ex.GetHexU8(0x12)); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2u, ex.GetFilePos()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Extra) { - llvm::StringRef kValidHexPair = "1234"; - StringExtractor ex(kValidHexPair); - - ASSERT_EQ(0x12, ex.GetHexU8(0x12)); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2u, ex.GetFilePos()); - ASSERT_EQ(2u, ex.GetBytesLeft()); - ASSERT_EQ('3', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Underflow_NoEof) { - llvm::StringRef kEmptyString = ""; - StringExtractor ex(kEmptyString); - const bool kSetEofOnFail = false; - - ASSERT_EQ(0xab, ex.GetHexU8(0xab, kSetEofOnFail)); - ASSERT_EQ(false, ex.IsGood()); // this result seems inconsistent with - // kSetEofOnFail == false - ASSERT_EQ(UINT64_MAX, ex.GetFilePos()); - ASSERT_EQ(true, ex.Empty()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Underflow2_NoEof) { - llvm::StringRef kOneNibble = "1"; - StringExtractor ex(kOneNibble); - const bool kSetEofOnFail = false; - - ASSERT_EQ(0xbc, ex.GetHexU8(0xbc, kSetEofOnFail)); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(1u, ex.GetBytesLeft()); - ASSERT_EQ('1', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_InvalidHex_NoEof) { - llvm::StringRef kInvalidHex = "xx"; - StringExtractor ex(kInvalidHex); - const bool kSetEofOnFail = false; - - ASSERT_EQ(0xcd, ex.GetHexU8(0xcd, kSetEofOnFail)); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(0u, ex.GetFilePos()); - ASSERT_EQ(2u, ex.GetBytesLeft()); - ASSERT_EQ('x', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Exact_NoEof) { - llvm::StringRef kValidHexPair = "12"; - StringExtractor ex(kValidHexPair); - const bool kSetEofOnFail = false; - - ASSERT_EQ(0x12, ex.GetHexU8(0x12, kSetEofOnFail)); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2u, ex.GetFilePos()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexU8_Extra_NoEof) { - llvm::StringRef kValidHexPair = "1234"; - StringExtractor ex(kValidHexPair); - const bool kSetEofOnFail = false; - - ASSERT_EQ(0x12, ex.GetHexU8(0x12, kSetEofOnFail)); - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2u, ex.GetFilePos()); - ASSERT_EQ(2u, ex.GetBytesLeft()); - ASSERT_EQ('3', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexBytes) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw"; - const size_t kValidHexPairs = 8; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[kValidHexPairs]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - EXPECT_EQ(0x89, dst[7]); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2 * kValidHexPairs, ex.GetFilePos()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(4u, ex.GetBytesLeft()); - ASSERT_EQ('x', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexBytes_FullString) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789"; - const size_t kValidHexPairs = 8; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[kValidHexPairs]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - EXPECT_EQ(0x89, dst[7]); -} - -TEST_F(StringExtractorTest, GetHexBytes_OddPair) { - llvm::StringRef kHexEncodedBytes = "abcdef012345678w"; - const size_t kValidHexPairs = 7; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[8]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - - // This one should be invalid - EXPECT_EQ(0xde, dst[7]); -} - -TEST_F(StringExtractorTest, GetHexBytes_OddPair2) { - llvm::StringRef kHexEncodedBytes = "abcdef012345678"; - const size_t kValidHexPairs = 7; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[8]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - - EXPECT_EQ(0xde, dst[7]); -} - -TEST_F(StringExtractorTest, GetHexBytes_Underflow) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw"; - const size_t kValidHexPairs = 8; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[12]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - EXPECT_EQ(0x89, dst[7]); - // these bytes should be filled with fail_fill_value 0xde - EXPECT_EQ(0xde, dst[8]); - EXPECT_EQ(0xde, dst[9]); - EXPECT_EQ(0xde, dst[10]); - EXPECT_EQ(0xde, dst[11]); - - ASSERT_EQ(false, ex.IsGood()); - ASSERT_EQ(UINT64_MAX, ex.GetFilePos()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(0u, ex.GetBytesLeft()); - ASSERT_EQ(nullptr, ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexBytes_Partial) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw"; - const size_t kReadBytes = 4; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[12]; - memset(dst, 0xab, sizeof(dst)); - ASSERT_EQ( - kReadBytes, - ex.GetHexBytes(llvm::MutableArrayRef(dst, kReadBytes), 0xde)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - // these bytes should be unchanged - EXPECT_EQ(0xab, dst[4]); - EXPECT_EQ(0xab, dst[5]); - EXPECT_EQ(0xab, dst[6]); - EXPECT_EQ(0xab, dst[7]); - EXPECT_EQ(0xab, dst[8]); - EXPECT_EQ(0xab, dst[9]); - EXPECT_EQ(0xab, dst[10]); - EXPECT_EQ(0xab, dst[11]); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(kReadBytes * 2, ex.GetFilePos()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(12u, ex.GetBytesLeft()); - ASSERT_EQ('2', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexBytesAvail) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw"; - const size_t kValidHexPairs = 8; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[kValidHexPairs]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - EXPECT_EQ(0x89, dst[7]); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(2 * kValidHexPairs, ex.GetFilePos()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(4u, ex.GetBytesLeft()); - ASSERT_EQ('x', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexBytesAvail_FullString) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789"; - const size_t kValidHexPairs = 8; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[kValidHexPairs]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - EXPECT_EQ(0x89, dst[7]); -} - -TEST_F(StringExtractorTest, GetHexBytesAvail_OddPair) { - llvm::StringRef kHexEncodedBytes = "abcdef012345678w"; - const size_t kValidHexPairs = 7; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[8]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); -} - -TEST_F(StringExtractorTest, GetHexBytesAvail_OddPair2) { - llvm::StringRef kHexEncodedBytes = "abcdef012345678"; - const size_t kValidHexPairs = 7; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[8]; - ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); -} - -TEST_F(StringExtractorTest, GetHexBytesAvail_Underflow) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw"; - const size_t kValidHexPairs = 8; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[12]; - memset(dst, 0xef, sizeof(dst)); - ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst)); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - EXPECT_EQ(0x23, dst[4]); - EXPECT_EQ(0x45, dst[5]); - EXPECT_EQ(0x67, dst[6]); - EXPECT_EQ(0x89, dst[7]); - // these bytes should be unchanged - EXPECT_EQ(0xef, dst[8]); - EXPECT_EQ(0xef, dst[9]); - EXPECT_EQ(0xef, dst[10]); - EXPECT_EQ(0xef, dst[11]); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(kValidHexPairs * 2, ex.GetFilePos()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(4u, ex.GetBytesLeft()); - ASSERT_EQ('x', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetHexBytesAvail_Partial) { - llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw"; - const size_t kReadBytes = 4; - StringExtractor ex(kHexEncodedBytes); - - uint8_t dst[12]; - memset(dst, 0xab, sizeof(dst)); - ASSERT_EQ(kReadBytes, ex.GetHexBytesAvail( - llvm::MutableArrayRef(dst, kReadBytes))); - EXPECT_EQ(0xab, dst[0]); - EXPECT_EQ(0xcd, dst[1]); - EXPECT_EQ(0xef, dst[2]); - EXPECT_EQ(0x01, dst[3]); - // these bytes should be unchanged - EXPECT_EQ(0xab, dst[4]); - EXPECT_EQ(0xab, dst[5]); - EXPECT_EQ(0xab, dst[6]); - EXPECT_EQ(0xab, dst[7]); - EXPECT_EQ(0xab, dst[8]); - EXPECT_EQ(0xab, dst[9]); - EXPECT_EQ(0xab, dst[10]); - EXPECT_EQ(0xab, dst[11]); - - ASSERT_EQ(true, ex.IsGood()); - ASSERT_EQ(kReadBytes * 2, ex.GetFilePos()); - ASSERT_EQ(false, ex.Empty()); - ASSERT_EQ(12u, ex.GetBytesLeft()); - ASSERT_EQ('2', *ex.Peek()); -} - -TEST_F(StringExtractorTest, GetNameColonValueSuccess) { - llvm::StringRef kNameColonPairs = "key1:value1;key2:value2;"; - StringExtractor ex(kNameColonPairs); - - llvm::StringRef name; - llvm::StringRef value; - EXPECT_TRUE(ex.GetNameColonValue(name, value)); - EXPECT_EQ("key1", name); - EXPECT_EQ("value1", value); - EXPECT_TRUE(ex.GetNameColonValue(name, value)); - EXPECT_EQ("key2", name); - EXPECT_EQ("value2", value); - EXPECT_EQ(0u, ex.GetBytesLeft()); -} - -TEST_F(StringExtractorTest, GetNameColonValueContainsColon) { - llvm::StringRef kNameColonPairs = "key1:value1:value2;key2:value3;"; - StringExtractor ex(kNameColonPairs); - - llvm::StringRef name; - llvm::StringRef value; - EXPECT_TRUE(ex.GetNameColonValue(name, value)); - EXPECT_EQ("key1", name); - EXPECT_EQ("value1:value2", value); - EXPECT_TRUE(ex.GetNameColonValue(name, value)); - EXPECT_EQ("key2", name); - EXPECT_EQ("value3", value); - EXPECT_EQ(0u, ex.GetBytesLeft()); -} - -TEST_F(StringExtractorTest, GetNameColonValueNoSemicolon) { - llvm::StringRef kNameColonPairs = "key1:value1"; - StringExtractor ex(kNameColonPairs); - - llvm::StringRef name; - llvm::StringRef value; - EXPECT_FALSE(ex.GetNameColonValue(name, value)); - EXPECT_EQ(0u, ex.GetBytesLeft()); -} - -TEST_F(StringExtractorTest, GetNameColonValueNoColon) { - llvm::StringRef kNameColonPairs = "key1value1;"; - StringExtractor ex(kNameColonPairs); - - llvm::StringRef name; - llvm::StringRef value; - EXPECT_FALSE(ex.GetNameColonValue(name, value)); - EXPECT_EQ(0u, ex.GetBytesLeft()); -} - -TEST_F(StringExtractorTest, GetU32LittleEndian) { - StringExtractor ex(""); - EXPECT_EQ(0x0ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("0"); - EXPECT_EQ(0x0ull, ex.GetHexMaxU32(true, 1)); - - ex.Reset("1"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("01"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("001"); - EXPECT_EQ(0x100ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("12"); - EXPECT_EQ(0x12ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("123"); - EXPECT_EQ(0x312ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("1203"); - EXPECT_EQ(0x312ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("1234"); - EXPECT_EQ(0x3412ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("12340"); - EXPECT_EQ(0x3412ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("123400"); - EXPECT_EQ(0x3412ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("12345670"); - EXPECT_EQ(0x70563412ull, ex.GetHexMaxU32(true, 0)); - - ex.Reset("123456701"); - EXPECT_EQ(0ull, ex.GetHexMaxU32(true, 0)); -} - -TEST_F(StringExtractorTest, GetU32BigEndian) { - StringExtractor ex(""); - EXPECT_EQ(0x0ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("0"); - EXPECT_EQ(0x0ull, ex.GetHexMaxU32(false, 1)); - - ex.Reset("1"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("01"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("001"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("12"); - EXPECT_EQ(0x12ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("123"); - EXPECT_EQ(0x123ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("1203"); - EXPECT_EQ(0x1203ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("1234"); - EXPECT_EQ(0x1234ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("12340"); - EXPECT_EQ(0x12340ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("123400"); - EXPECT_EQ(0x123400ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("12345670"); - EXPECT_EQ(0x12345670ull, ex.GetHexMaxU32(false, 0)); - - ex.Reset("123456700"); - EXPECT_EQ(0ull, ex.GetHexMaxU32(false, 0)); -} - -TEST_F(StringExtractorTest, GetU64LittleEndian) { - StringExtractor ex(""); - EXPECT_EQ(0x0ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("0"); - EXPECT_EQ(0x0ull, ex.GetHexMaxU64(true, 1)); - - ex.Reset("1"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("01"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("001"); - EXPECT_EQ(0x100ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("12"); - EXPECT_EQ(0x12ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("123"); - EXPECT_EQ(0x312ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("1203"); - EXPECT_EQ(0x312ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("1234"); - EXPECT_EQ(0x3412ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("12340"); - EXPECT_EQ(0x3412ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("123400"); - EXPECT_EQ(0x3412ull, ex.GetHexMaxU64(true, 0)); - - ex.Reset("123456789ABCDEF0"); - EXPECT_EQ(0xF0DEBC9A78563412ULL, ex.GetHexMaxU64(true, 0)); - - ex.Reset("123456789ABCDEF01"); - EXPECT_EQ(0ull, ex.GetHexMaxU64(true, 0)); -} - -TEST_F(StringExtractorTest, GetU64BigEndian) { - StringExtractor ex(""); - EXPECT_EQ(0x0ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("0"); - EXPECT_EQ(0x0ull, ex.GetHexMaxU64(false, 1)); - - ex.Reset("1"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("01"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("001"); - EXPECT_EQ(0x1ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("12"); - EXPECT_EQ(0x12ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("123"); - EXPECT_EQ(0x123ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("1203"); - EXPECT_EQ(0x1203ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("1234"); - EXPECT_EQ(0x1234ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("12340"); - EXPECT_EQ(0x12340ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("123400"); - EXPECT_EQ(0x123400ull, ex.GetHexMaxU64(false, 0)); - - ex.Reset("123456789ABCDEF0"); - EXPECT_EQ(0x123456789ABCDEF0ULL, ex.GetHexMaxU64(false, 0)); - - ex.Reset("123456789ABCDEF000"); - EXPECT_EQ(0ull, ex.GetHexMaxU64(false, 0)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp b/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp deleted file mode 100644 index f7a81bddcea..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//===-- StringLexerTest.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 "lldb/Utility/StringLexer.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(StringLexerTest, GetUnlexed) { - StringLexer l("foo"); - EXPECT_EQ("foo", l.GetUnlexed()); - l.Next(); - EXPECT_EQ("oo", l.GetUnlexed()); - l.Next(); - l.Next(); - EXPECT_EQ("", l.GetUnlexed()); -} - -TEST(StringLexerTest, HasAtLeast) { - StringLexer l("foo"); - EXPECT_FALSE(l.HasAtLeast(5)); - EXPECT_FALSE(l.HasAtLeast(4)); - EXPECT_TRUE(l.HasAtLeast(3)); - EXPECT_TRUE(l.HasAtLeast(2)); - EXPECT_TRUE(l.HasAtLeast(1)); - - l.Next(); - EXPECT_FALSE(l.HasAtLeast(5)); - EXPECT_FALSE(l.HasAtLeast(4)); - EXPECT_FALSE(l.HasAtLeast(3)); - EXPECT_TRUE(l.HasAtLeast(2)); - EXPECT_TRUE(l.HasAtLeast(1)); - - l.Next(); - l.Next(); - EXPECT_FALSE(l.HasAtLeast(5)); - EXPECT_FALSE(l.HasAtLeast(4)); - EXPECT_FALSE(l.HasAtLeast(3)); - EXPECT_FALSE(l.HasAtLeast(2)); - EXPECT_FALSE(l.HasAtLeast(1)); -} - -TEST(StringLexerTest, AdvanceIf) { - StringLexer l("foobar"); - - EXPECT_FALSE(l.AdvanceIf("oo")); - // Skip the "fo" part. - EXPECT_TRUE(l.AdvanceIf("fo")); - EXPECT_FALSE(l.AdvanceIf("obarz")); - // Skip the remaining string. - EXPECT_TRUE(l.AdvanceIf("obar")); - - EXPECT_FALSE(l.AdvanceIf("obarz")); - EXPECT_FALSE(l.AdvanceIf("foo")); - EXPECT_FALSE(l.AdvanceIf("o")); - EXPECT_FALSE(l.AdvanceIf(" ")); -} - -TEST(StringLexerTest, PutBack) { - StringLexer l("foo"); - - l.Next(); - l.PutBack(1); - EXPECT_EQ("foo", l.GetUnlexed()); - - l.Next(); - l.Next(); - l.Next(); - l.PutBack(2); - EXPECT_EQ("oo", l.GetUnlexed()); - - l.PutBack(1); - EXPECT_EQ("foo", l.GetUnlexed()); -} - -TEST(StringLexerTest, Peek) { - StringLexer l("foo"); - - EXPECT_EQ('f', l.Peek()); - l.Next(); - EXPECT_EQ('o', l.Peek()); - l.Next(); - EXPECT_EQ('o', l.Peek()); -} - -TEST(StringLexerTest, Next) { - StringLexer l("foo"); - EXPECT_EQ('f', l.Next()); - EXPECT_EQ('o', l.Next()); - EXPECT_EQ('o', l.Next()); -} - -TEST(StringLexerTest, NextIf) { - StringLexer l("foo"); - - EXPECT_FALSE(l.NextIf('\0')); - EXPECT_FALSE(l.NextIf(' ')); - EXPECT_FALSE(l.NextIf('o')); - - EXPECT_TRUE(l.NextIf('f')); - - EXPECT_FALSE(l.NextIf('\0')); - EXPECT_FALSE(l.NextIf(' ')); - EXPECT_FALSE(l.NextIf('f')); - - EXPECT_TRUE(l.NextIf('o')); - - EXPECT_FALSE(l.NextIf('\0')); - EXPECT_FALSE(l.NextIf(' ')); - EXPECT_FALSE(l.NextIf('f')); - - EXPECT_TRUE(l.NextIf('o')); -} - -TEST(StringLexerTest, NextIfList) { - StringLexer l("foo"); - - EXPECT_FALSE(l.NextIf({'\0', ' ', 'o'}).first); - - auto r = l.NextIf({'f'}); - EXPECT_TRUE(r.first); - EXPECT_EQ('f', r.second); - - EXPECT_FALSE(l.NextIf({'\0', ' ', 'f'}).first); - - r = l.NextIf({'f', 'o'}); - EXPECT_TRUE(r.first); - EXPECT_EQ('o', r.second); - - EXPECT_FALSE(l.NextIf({'\0', ' ', 'f'}).first); - - r = l.NextIf({'*', 'f', 'o', 'o'}); - EXPECT_TRUE(r.first); - EXPECT_EQ('o', r.second); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp b/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp deleted file mode 100644 index 08d55a51c70..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp +++ /dev/null @@ -1,524 +0,0 @@ -//===-- StringListTest.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 "lldb/Utility/StringList.h" -#include "lldb/Utility/StreamString.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -TEST(StringListTest, DefaultConstructor) { - StringList s; - EXPECT_EQ(0U, s.GetSize()); -} - -TEST(StringListTest, Assignment) { - StringList orig; - orig.AppendString("foo"); - orig.AppendString("bar"); - - StringList s = orig; - - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); - - ASSERT_EQ(2U, orig.GetSize()); - EXPECT_STREQ("foo", orig.GetStringAtIndex(0)); - EXPECT_STREQ("bar", orig.GetStringAtIndex(1)); -} - -TEST(StringListTest, AppendStringStdString) { - StringList s; - s.AppendString("foo"); - ASSERT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s.AppendString("bar"); - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, AppendStringCString) { - StringList s; - s.AppendString("foo", strlen("foo")); - ASSERT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s.AppendString("bar", strlen("bar")); - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, AppendStringMove) { - StringList s; - std::string foo = "foo"; - std::string bar = "bar"; - - s.AppendString(std::move(foo)); - ASSERT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s.AppendString(std::move(bar)); - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, ShiftStdString) { - StringList s; - std::string foo = "foo"; - std::string bar = "bar"; - - s << foo; - ASSERT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s << bar; - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, ShiftCString) { - StringList s; - s << "foo"; - ASSERT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s << "bar"; - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, ShiftMove) { - StringList s; - std::string foo = "foo"; - std::string bar = "bar"; - - s << std::move(foo); - ASSERT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s << std::move(bar); - ASSERT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, AppendListCStringArrayEmpty) { - StringList s; - s.AppendList(nullptr, 0); - EXPECT_EQ(0U, s.GetSize()); -} - -TEST(StringListTest, AppendListCStringArray) { - StringList s; - const char *items[3] = {"foo", "", "bar"}; - s.AppendList(items, 3); - - EXPECT_EQ(3U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("", s.GetStringAtIndex(1)); - EXPECT_STREQ("bar", s.GetStringAtIndex(2)); -} - -TEST(StringListTest, AppendList) { - StringList other; - other.AppendString("foo"); - other.AppendString(""); - other.AppendString("bar"); - - StringList empty; - - StringList s; - s.AppendList(other); - - EXPECT_EQ(3U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("", s.GetStringAtIndex(1)); - EXPECT_STREQ("bar", s.GetStringAtIndex(2)); - - EXPECT_EQ(3U, other.GetSize()); - EXPECT_STREQ("foo", other.GetStringAtIndex(0)); - EXPECT_STREQ("", other.GetStringAtIndex(1)); - EXPECT_STREQ("bar", other.GetStringAtIndex(2)); - - s.AppendList(empty); - s.AppendList(other); - EXPECT_EQ(6U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("", s.GetStringAtIndex(1)); - EXPECT_STREQ("bar", s.GetStringAtIndex(2)); - EXPECT_STREQ("foo", s.GetStringAtIndex(3)); - EXPECT_STREQ("", s.GetStringAtIndex(4)); - EXPECT_STREQ("bar", s.GetStringAtIndex(5)); - - EXPECT_EQ(3U, other.GetSize()); - EXPECT_STREQ("foo", other.GetStringAtIndex(0)); - EXPECT_STREQ("", other.GetStringAtIndex(1)); - EXPECT_STREQ("bar", other.GetStringAtIndex(2)); -} - -TEST(StringListTest, GetSize) { - StringList s; - s.AppendString("foo"); - EXPECT_EQ(1U, s.GetSize()); - - s.AppendString("foo"); - EXPECT_EQ(2U, s.GetSize()); - - s.AppendString("foobar"); - EXPECT_EQ(3U, s.GetSize()); -} - -TEST(StringListTest, SetSize) { - StringList s; - s.SetSize(3); - EXPECT_EQ(3U, s.GetSize()); - EXPECT_STREQ("", s.GetStringAtIndex(0)); - EXPECT_STREQ("", s.GetStringAtIndex(1)); - EXPECT_STREQ("", s.GetStringAtIndex(2)); -} - -TEST(StringListTest, SplitIntoLines) { - StringList s; - s.SplitIntoLines("\nfoo\nbar\n\n"); - EXPECT_EQ(4U, s.GetSize()); - EXPECT_STREQ("", s.GetStringAtIndex(0)); - EXPECT_STREQ("foo", s.GetStringAtIndex(1)); - EXPECT_STREQ("bar", s.GetStringAtIndex(2)); - EXPECT_STREQ("", s.GetStringAtIndex(3)); -} - -TEST(StringListTest, SplitIntoLinesSingleTrailingCR) { - StringList s; - s.SplitIntoLines("\r"); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("", s.GetStringAtIndex(0)); -} - -TEST(StringListTest, SplitIntoLinesEmpty) { - StringList s; - s.SplitIntoLines(""); - EXPECT_EQ(0U, s.GetSize()); -} - -TEST(StringListTest, LongestCommonPrefixEmpty) { - StringList s; - std::string prefix = s.LongestCommonPrefix(); - EXPECT_EQ("", prefix); -} - -TEST(StringListTest, LongestCommonPrefix) { - StringList s; - s.AppendString("foo"); - s.AppendString("foobar"); - s.AppendString("foo"); - s.AppendString("foozar"); - - std::string prefix = s.LongestCommonPrefix(); - EXPECT_EQ("foo", prefix); -} - -TEST(StringListTest, LongestCommonPrefixSingleElement) { - StringList s; - s.AppendString("foo"); - - std::string prefix = s.LongestCommonPrefix(); - EXPECT_EQ("foo", prefix); -} - -TEST(StringListTest, LongestCommonPrefixDuplicateElement) { - StringList s; - s.AppendString("foo"); - s.AppendString("foo"); - - std::string prefix = s.LongestCommonPrefix(); - EXPECT_EQ("foo", prefix); -} - -TEST(StringListTest, LongestCommonPrefixNoPrefix) { - StringList s; - s.AppendString("foo"); - s.AppendString("1foobar"); - s.AppendString("2foo"); - s.AppendString("3foozar"); - - std::string prefix = s.LongestCommonPrefix(); - EXPECT_EQ("", prefix); -} - -TEST(StringListTest, Clear) { - StringList s; - s.Clear(); - EXPECT_EQ(0U, s.GetSize()); - - s.AppendString("foo"); - s.Clear(); - EXPECT_EQ(0U, s.GetSize()); - - s.AppendString("foo"); - s.AppendString("foo"); - s.Clear(); - EXPECT_EQ(0U, s.GetSize()); -} - -TEST(StringListTest, PopBack) { - StringList s; - s.AppendString("foo"); - s.AppendString("bar"); - s.AppendString("boo"); - - s.PopBack(); - EXPECT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); - - s.PopBack(); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s.PopBack(); - EXPECT_EQ(0U, s.GetSize()); -} - -TEST(StringListTest, RemoveBlankLines) { - StringList s; - - // Nothing to remove yet. - s.RemoveBlankLines(); - EXPECT_EQ(0U, s.GetSize()); - - // Add some lines. - s.AppendString(""); - s.AppendString(""); - s.AppendString("\t"); - s.AppendString(""); - s.AppendString(" "); - s.AppendString(""); - s.AppendString(""); - s.AppendString("f"); - s.AppendString(""); - s.AppendString(""); - - // And remove all the empty ones again. - s.RemoveBlankLines(); - - EXPECT_EQ(3U, s.GetSize()); - EXPECT_STREQ("\t", s.GetStringAtIndex(0)); - EXPECT_STREQ(" ", s.GetStringAtIndex(1)); - EXPECT_STREQ("f", s.GetStringAtIndex(2)); -} - -TEST(StringListTest, InsertStringAtIndexStart) { - StringList s; - - s.InsertStringAtIndex(0, "bar"); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("bar", s.GetStringAtIndex(0)); - - s.InsertStringAtIndex(0, "foo"); - EXPECT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, InsertStringAtIndexEnd) { - StringList s; - - s.InsertStringAtIndex(0, "foo"); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - s.InsertStringAtIndex(1, "bar"); - EXPECT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, InsertStringAtIndexOutOfBounds) { - StringList s; - - s.InsertStringAtIndex(1, "foo"); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - - // FIXME: Inserting at an OOB index will always just append to the list. This - // seems not very intuitive. - s.InsertStringAtIndex(3, "bar"); - EXPECT_EQ(2U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); - EXPECT_STREQ("bar", s.GetStringAtIndex(1)); -} - -TEST(StringListTest, InsertStringAtIndexStdString) { - StringList s; - - std::string foo = "foo"; - s.InsertStringAtIndex(0, foo); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); -} - -TEST(StringListTest, InsertStringAtIndexMove) { - StringList s; - - std::string foo = "foo"; - s.InsertStringAtIndex(0, std::move(foo)); - EXPECT_EQ(1U, s.GetSize()); - EXPECT_STREQ("foo", s.GetStringAtIndex(0)); -} - -TEST(StringListTest, CopyListEmpty) { - StringList s; - - EXPECT_EQ("", s.CopyList()); - EXPECT_EQ("", s.CopyList("+")); -} - -TEST(StringListTest, CopyListSingle) { - StringList s; - s.AppendString("ab"); - - EXPECT_EQ("ab", s.CopyList()); - EXPECT_EQ("-ab", s.CopyList("-")); -} - -TEST(StringListTest, CopyList) { - StringList s; - s.AppendString("ab"); - s.AppendString("cd"); - - EXPECT_EQ("ab\ncd", s.CopyList()); - EXPECT_EQ("-ab\n-cd", s.CopyList("-")); -} - -TEST(StringListTest, Join) { - StringList s; - s.AppendString("ab"); - s.AppendString("cd"); - - StreamString ss; - s.Join(" ", ss); - - EXPECT_EQ("ab cd", ss.GetString()); -} - -TEST(StringListTest, JoinEmpty) { - StringList s; - - StreamString ss; - s.Join(" ", ss); - - EXPECT_EQ("", ss.GetString()); -} - -TEST(StringListTest, JoinSingle) { - StringList s; - s.AppendString("foo"); - - StreamString ss; - s.Join(" ", ss); - - EXPECT_EQ("foo", ss.GetString()); -} - -TEST(StringListTest, JoinThree) { - StringList s; - s.AppendString("1"); - s.AppendString("2"); - s.AppendString("3"); - - StreamString ss; - s.Join(" ", ss); - - EXPECT_EQ("1 2 3", ss.GetString()); -} - -TEST(StringListTest, JoinNonSpace) { - StringList s; - s.AppendString("1"); - s.AppendString("2"); - s.AppendString("3"); - - StreamString ss; - s.Join(".", ss); - - EXPECT_EQ("1.2.3", ss.GetString()); -} - -TEST(StringListTest, JoinMultiCharSeparator) { - StringList s; - s.AppendString("1"); - s.AppendString("2"); - s.AppendString("3"); - - StreamString ss; - s.Join("--", ss); - - EXPECT_EQ("1--2--3", ss.GetString()); -} - -TEST(StringListTest, GetMaxStringLengthEqualSize) { - StringList s; - s.AppendString("123"); - s.AppendString("123"); - EXPECT_EQ(3U, s.GetMaxStringLength()); -} - -TEST(StringListTest, GetMaxStringLengthIncreasingSize) { - StringList s; - s.AppendString("123"); - s.AppendString("1234"); - EXPECT_EQ(4U, s.GetMaxStringLength()); -} - -TEST(StringListTest, GetMaxStringLengthDecreasingSize) { - StringList s; - s.AppendString("1234"); - s.AppendString("123"); - EXPECT_EQ(4U, s.GetMaxStringLength()); -} - -TEST(StringListTest, GetMaxStringLengthMixed) { - StringList s; - s.AppendString("123"); - s.AppendString("1"); - s.AppendString("123"); - s.AppendString("1234"); - s.AppendString("123"); - s.AppendString("1"); - EXPECT_EQ(4U, s.GetMaxStringLength()); -} - -TEST(StringListTest, GetMaxStringLengthEmpty) { - StringList s; - EXPECT_EQ(0U, s.GetMaxStringLength()); -} - -TEST(StringListTest, ForRangeEmpty) { - StringList s; - for (const std::string &e : s) - FAIL() << "Shouldn't have hit an element in for range" << e; -} - -TEST(StringListTest, ForRange) { - StringList s; - s.AppendString("a"); - s.AppendString("b"); - s.AppendString("c"); - std::vector recorded; - for (const std::string &e : s) - recorded.push_back(e); - EXPECT_THAT(recorded, testing::ElementsAre("a", "b", "c")); -} diff --git a/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp b/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp deleted file mode 100644 index cb5e418cd95..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===-- StructuredDataTest.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 "gtest/gtest.h" - -#include "TestingSupport/TestUtilities.h" -#include "lldb/Utility/Status.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StructuredData.h" -#include "llvm/Support/Path.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(StructuredDataTest, StringDump) { - std::pair TestCases[] = { - {R"(asdfg)", R"("asdfg")"}, - {R"(as"df)", R"("as\"df")"}, - {R"(as\df)", R"("as\\df")"}, - }; - for (auto P : TestCases) { - StreamString S; - const bool pretty_print = false; - StructuredData::String(P.first).Dump(S, pretty_print); - EXPECT_EQ(P.second, S.GetString()); - } -} - -TEST(StructuredDataTest, ParseJSONFromFile) { - Status status; - auto object_sp = StructuredData::ParseJSONFromFile( - FileSpec("non-existing-file.json"), status); - EXPECT_EQ(nullptr, object_sp); - - std::string input = GetInputFilePath("StructuredData-basic.json"); - object_sp = StructuredData::ParseJSONFromFile(FileSpec(input), status); - ASSERT_NE(nullptr, object_sp); - - StreamString S; - object_sp->Dump(S, false); - EXPECT_EQ("[1,2,3]", S.GetString()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp b/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp deleted file mode 100644 index 1a23bfc716f..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp +++ /dev/null @@ -1,99 +0,0 @@ -//===-- SubsystemRAIITest.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 "gtest/gtest-spi.h" -#include "gtest/gtest.h" - -#include "TestingSupport/SubsystemRAII.h" - -using namespace lldb_private; - -namespace { - -enum class SystemState { - /// Start state of the subsystem. - Start, - /// Initialize has been called but Terminate hasn't been called yet. - Initialized, - /// Terminate has been called. - Terminated -}; - -struct TestSubsystem { - static SystemState state; - static void Initialize() { - assert(state == SystemState::Start); - state = SystemState::Initialized; - } - static void Terminate() { - assert(state == SystemState::Initialized); - state = SystemState::Terminated; - } -}; -} // namespace - -SystemState TestSubsystem::state = SystemState::Start; - -TEST(SubsystemRAIITest, NormalSubsystem) { - // Tests that SubsystemRAII handles Initialize functions that return void. - EXPECT_EQ(SystemState::Start, TestSubsystem::state); - { - SubsystemRAII subsystem; - EXPECT_EQ(SystemState::Initialized, TestSubsystem::state); - } - EXPECT_EQ(SystemState::Terminated, TestSubsystem::state); -} - -static const char *SubsystemErrorString = "Initialize failed"; - -namespace { -struct TestSubsystemWithError { - static SystemState state; - static bool will_fail; - static llvm::Error Initialize() { - assert(state == SystemState::Start); - state = SystemState::Initialized; - if (will_fail) - return llvm::make_error( - SubsystemErrorString, llvm::inconvertibleErrorCode()); - return llvm::Error::success(); - } - static void Terminate() { - assert(state == SystemState::Initialized); - state = SystemState::Terminated; - } - /// Reset the subsystem to the default state for testing. - static void Reset() { state = SystemState::Start; } -}; -} // namespace - -SystemState TestSubsystemWithError::state = SystemState::Start; -bool TestSubsystemWithError::will_fail = false; - -TEST(SubsystemRAIITest, SubsystemWithErrorSuccess) { - // Tests that SubsystemRAII handles llvm::success() returned from - // Initialize. - TestSubsystemWithError::Reset(); - EXPECT_EQ(SystemState::Start, TestSubsystemWithError::state); - { - TestSubsystemWithError::will_fail = false; - SubsystemRAII subsystem; - EXPECT_EQ(SystemState::Initialized, TestSubsystemWithError::state); - } - EXPECT_EQ(SystemState::Terminated, TestSubsystemWithError::state); -} - -TEST(SubsystemRAIITest, SubsystemWithErrorFailure) { - // Tests that SubsystemRAII handles any errors returned from - // Initialize. - TestSubsystemWithError::Reset(); - EXPECT_EQ(SystemState::Start, TestSubsystemWithError::state); - TestSubsystemWithError::will_fail = true; - EXPECT_FATAL_FAILURE(SubsystemRAII subsystem, - SubsystemErrorString); -} diff --git a/gnu/llvm/lldb/unittests/Utility/TildeExpressionResolverTest.cpp b/gnu/llvm/lldb/unittests/Utility/TildeExpressionResolverTest.cpp deleted file mode 100644 index bcb7fdb8604..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/TildeExpressionResolverTest.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "gtest/gtest.h" - -#include "TestingSupport/MockTildeExpressionResolver.h" -#include "lldb/Utility/TildeExpressionResolver.h" - -#include "llvm/ADT/SmallString.h" - -using namespace llvm; -using namespace lldb_private; - -TEST(TildeExpressionResolver, ResolveFullPath) { - MockTildeExpressionResolver Resolver("James", "/james"); - Resolver.AddKnownUser("Kirk", "/kirk"); - Resolver.AddKnownUser("Lars", "/lars"); - Resolver.AddKnownUser("Jason", "/jason"); - Resolver.AddKnownUser("Larry", "/larry"); - - SmallString<32> Result; - ASSERT_TRUE(Resolver.ResolveFullPath("~", Result)); - EXPECT_EQ("/james", Result); - ASSERT_TRUE(Resolver.ResolveFullPath("~/", Result)); - EXPECT_EQ("/james/", Result); - - ASSERT_TRUE(Resolver.ResolveFullPath("~James/bar/baz", Result)); - EXPECT_EQ("/james/bar/baz", Result); - - ASSERT_TRUE(Resolver.ResolveFullPath("~Jason/", Result)); - EXPECT_EQ("/jason/", Result); - - ASSERT_TRUE(Resolver.ResolveFullPath("~Lars", Result)); - EXPECT_EQ("/lars", Result); - - ASSERT_FALSE(Resolver.ResolveFullPath("~Jaso", Result)); - EXPECT_EQ("~Jaso", Result); - ASSERT_FALSE(Resolver.ResolveFullPath("", Result)); - EXPECT_EQ("", Result); - ASSERT_FALSE(Resolver.ResolveFullPath("Jason", Result)); - EXPECT_EQ("Jason", Result); -} diff --git a/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp b/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp deleted file mode 100644 index 222ee5db177..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===-- TimeoutTest.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 "lldb/Utility/Timeout.h" -#include "llvm/Support/FormatVariadic.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace std::chrono; - -TEST(TimeoutTest, Construction) { - EXPECT_FALSE(Timeout(llvm::None)); - EXPECT_TRUE(bool(Timeout(seconds(0)))); - EXPECT_EQ(seconds(0), *Timeout(seconds(0))); - EXPECT_EQ(seconds(3), *Timeout(seconds(3))); - EXPECT_TRUE(bool(Timeout(Timeout(seconds(0))))); -} - -TEST(TimeoutTest, Format) { - EXPECT_EQ("", - llvm::formatv("{0}", Timeout(llvm::None)).str()); - EXPECT_EQ("1000 ms", - llvm::formatv("{0}", Timeout(seconds(1))).str()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp b/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp deleted file mode 100644 index c6d1facdebb..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp +++ /dev/null @@ -1,108 +0,0 @@ -//===-- TimerTest.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 "lldb/Utility/StreamString.h" -#include "lldb/Utility/Timer.h" -#include "gtest/gtest.h" -#include - -using namespace lldb_private; - -TEST(TimerTest, CategoryTimes) { - Timer::ResetCategoryTimes(); - { - static Timer::Category tcat("CAT1"); - Timer t(tcat, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - StreamString ss; - Timer::DumpCategoryTimes(&ss); - double seconds; - ASSERT_EQ(1, sscanf(ss.GetData(), "%lf sec for CAT1", &seconds)); - EXPECT_LT(0.001, seconds); - EXPECT_GT(0.1, seconds); -} - -TEST(TimerTest, CategoryTimesNested) { - Timer::ResetCategoryTimes(); - { - static Timer::Category tcat1("CAT1"); - Timer t1(tcat1, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - // Explicitly testing the same category as above. - Timer t2(tcat1, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - StreamString ss; - Timer::DumpCategoryTimes(&ss); - double seconds; - // It should only appear once. - ASSERT_EQ(ss.GetString().count("CAT1"), 1U); - ASSERT_EQ(1, sscanf(ss.GetData(), "%lf sec for CAT1", &seconds)); - EXPECT_LT(0.002, seconds); - EXPECT_GT(0.2, seconds); -} - -TEST(TimerTest, CategoryTimes2) { - Timer::ResetCategoryTimes(); - { - static Timer::Category tcat1("CAT1"); - Timer t1(tcat1, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - static Timer::Category tcat2("CAT2"); - Timer t2(tcat2, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - StreamString ss; - Timer::DumpCategoryTimes(&ss); - double seconds1, seconds2; - ASSERT_EQ(2, sscanf(ss.GetData(), - "%lf sec (total: %*fs; child: %*fs; count: %*d) for " - "CAT1%*[\n ]%lf sec for CAT2", - &seconds1, &seconds2)) - << "String: " << ss.GetData(); - EXPECT_LT(0.01, seconds1); - EXPECT_GT(1, seconds1); - EXPECT_LT(0.001, seconds2); - EXPECT_GT(0.1, seconds2); -} - -TEST(TimerTest, CategoryTimesStats) { - Timer::ResetCategoryTimes(); - { - static Timer::Category tcat1("CAT1"); - Timer t1(tcat1, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - static Timer::Category tcat2("CAT2"); - { - Timer t2(tcat2, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - { - Timer t3(tcat2, "."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - // Example output: - // 0.105202764 sec (total: 0.132s; child: 0.027s; count: 1) for CAT1 - // 0.026772798 sec (total: 0.027s; child: 0.000s; count: 2) for CAT2 - StreamString ss; - Timer::DumpCategoryTimes(&ss); - double seconds1, total1, child1, seconds2; - int count1, count2; - ASSERT_EQ( - 6, sscanf(ss.GetData(), - "%lf sec (total: %lfs; child: %lfs; count: %d) for CAT1%*[\n\r ]" - "%lf sec (total: %*fs; child: %*fs; count: %d) for CAT2", - &seconds1, &total1, &child1, &count1, &seconds2, &count2)) - << "String: " << ss.GetData(); - EXPECT_NEAR(total1 - child1, seconds1, 0.002); - EXPECT_EQ(1, count1); - EXPECT_NEAR(child1, seconds2, 0.002); - EXPECT_EQ(2, count2); -} diff --git a/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp b/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp deleted file mode 100644 index 1c84315d402..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===-- UUIDTest.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 "gtest/gtest.h" - -#include "lldb/Utility/UUID.h" - -using namespace lldb_private; - -TEST(UUIDTest, RelationalOperators) { - UUID empty; - UUID a16 = UUID::fromData("1234567890123456", 16); - UUID b16 = UUID::fromData("1234567890123457", 16); - UUID a20 = UUID::fromData("12345678901234567890", 20); - UUID b20 = UUID::fromData("12345678900987654321", 20); - - EXPECT_EQ(empty, empty); - EXPECT_EQ(a16, a16); - EXPECT_EQ(a20, a20); - - EXPECT_NE(a16, b16); - EXPECT_NE(a20, b20); - EXPECT_NE(a16, a20); - EXPECT_NE(empty, a16); - - EXPECT_LT(empty, a16); - EXPECT_LT(a16, a20); - EXPECT_LT(a16, b16); - EXPECT_GT(a20, b20); -} - -TEST(UUIDTest, Validity) { - UUID empty; - std::vector zeroes(20, 0); - UUID a16 = UUID::fromData(zeroes.data(), 16); - UUID a20 = UUID::fromData(zeroes.data(), 20); - UUID a16_0 = UUID::fromOptionalData(zeroes.data(), 16); - UUID a20_0 = UUID::fromOptionalData(zeroes.data(), 20); - UUID from_str; - from_str.SetFromStringRef("00000000-0000-0000-0000-000000000000"); - UUID opt_from_str; - opt_from_str.SetFromOptionalStringRef("00000000-0000-0000-0000-000000000000"); - - EXPECT_FALSE(empty); - EXPECT_TRUE(a16); - EXPECT_TRUE(a20); - EXPECT_TRUE(from_str); - EXPECT_FALSE(a16_0); - EXPECT_FALSE(a20_0); - EXPECT_FALSE(opt_from_str); -} - -TEST(UUIDTest, SetFromStringRef) { - UUID u; - EXPECT_TRUE(u.SetFromStringRef("404142434445464748494a4b4c4d4e4f")); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u); - - EXPECT_TRUE(u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f")); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u); - - EXPECT_TRUE( - u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f-50515253")); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20), u); - - EXPECT_TRUE(u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f")); - - EXPECT_FALSE(u.SetFromStringRef("40xxxxx")); - EXPECT_FALSE(u.SetFromStringRef("")); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u) - << "uuid was changed by failed parse calls"; - - EXPECT_TRUE(u.SetFromStringRef("404142434445464748494a4b4c4d4e4f-50515253")); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20), u); - - EXPECT_TRUE(u.SetFromStringRef("40414243")); - EXPECT_EQ(UUID::fromData("@ABCD", 4), u); - - EXPECT_FALSE(u.SetFromStringRef("4")); -} - -TEST(UUIDTest, StringConverion) { - EXPECT_EQ("40414243", UUID::fromData("@ABC", 4).GetAsString()); - EXPECT_EQ("40414243-4445-4647", UUID::fromData("@ABCDEFG", 8).GetAsString()); - EXPECT_EQ("40414243-4445-4647-4849-4A4B", - UUID::fromData("@ABCDEFGHIJK", 12).GetAsString()); - EXPECT_EQ("40414243-4445-4647-4849-4A4B4C4D4E4F", - UUID::fromData("@ABCDEFGHIJKLMNO", 16).GetAsString()); - EXPECT_EQ("40414243-4445-4647-4849-4A4B4C4D4E4F-50515253", - UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20).GetAsString()); -} diff --git a/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp b/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp deleted file mode 100644 index c88a647ef93..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "lldb/Utility/UriParser.h" -#include "gtest/gtest.h" - -using namespace lldb_private; - -// result strings (scheme/hostname/port/path) passed into UriParser::Parse -// are initialized to kAsdf so we can verify that they are unmodified if the -// URI is invalid -static const char *kAsdf = "asdf"; - -class UriTestCase { -public: - UriTestCase(const char *uri, const char *scheme, const char *hostname, - int port, const char *path) - : m_uri(uri), m_result(true), m_scheme(scheme), m_hostname(hostname), - m_port(port), m_path(path) {} - - UriTestCase(const char *uri) - : m_uri(uri), m_result(false), m_scheme(kAsdf), m_hostname(kAsdf), - m_port(1138), m_path(kAsdf) {} - - const char *m_uri; - bool m_result; - const char *m_scheme; - const char *m_hostname; - int m_port; - const char *m_path; -}; - -#define VALIDATE \ - llvm::StringRef scheme(kAsdf); \ - llvm::StringRef hostname(kAsdf); \ - int port(1138); \ - llvm::StringRef path(kAsdf); \ - EXPECT_EQ(testCase.m_result, \ - UriParser::Parse(testCase.m_uri, scheme, hostname, port, path)); \ - EXPECT_STREQ(testCase.m_scheme, scheme.str().c_str()); \ - EXPECT_STREQ(testCase.m_hostname, hostname.str().c_str()); \ - EXPECT_EQ(testCase.m_port, port); \ - EXPECT_STREQ(testCase.m_path, path.str().c_str()); - -TEST(UriParserTest, Minimal) { - const UriTestCase testCase("x://y", "x", "y", -1, "/"); - VALIDATE -} - -TEST(UriParserTest, MinimalPort) { - const UriTestCase testCase("x://y:1", "x", "y", 1, "/"); - llvm::StringRef scheme(kAsdf); - llvm::StringRef hostname(kAsdf); - int port(1138); - llvm::StringRef path(kAsdf); - bool result = UriParser::Parse(testCase.m_uri, scheme, hostname, port, path); - EXPECT_EQ(testCase.m_result, result); - - EXPECT_STREQ(testCase.m_scheme, scheme.str().c_str()); - EXPECT_STREQ(testCase.m_hostname, hostname.str().c_str()); - EXPECT_EQ(testCase.m_port, port); - EXPECT_STREQ(testCase.m_path, path.str().c_str()); -} - -TEST(UriParserTest, MinimalPath) { - const UriTestCase testCase("x://y/", "x", "y", -1, "/"); - VALIDATE -} - -TEST(UriParserTest, MinimalPortPath) { - const UriTestCase testCase("x://y:1/", "x", "y", 1, "/"); - VALIDATE -} - -TEST(UriParserTest, LongPath) { - const UriTestCase testCase("x://y/abc/def/xyz", "x", "y", -1, "/abc/def/xyz"); - VALIDATE -} - -TEST(UriParserTest, TypicalPortPathIPv4) { - const UriTestCase testCase("connect://192.168.100.132:5432/", "connect", - "192.168.100.132", 5432, "/"); - VALIDATE; -} - -TEST(UriParserTest, TypicalPortPathIPv6) { - const UriTestCase testCase( - "connect://[2601:600:107f:db64:a42b:4faa:284:3082]:5432/", "connect", - "2601:600:107f:db64:a42b:4faa:284:3082", 5432, "/"); - VALIDATE; -} - -TEST(UriParserTest, BracketedHostnamePort) { - const UriTestCase testCase("connect://[192.168.100.132]:5432/", "connect", - "192.168.100.132", 5432, "/"); - llvm::StringRef scheme(kAsdf); - llvm::StringRef hostname(kAsdf); - int port(1138); - llvm::StringRef path(kAsdf); - bool result = UriParser::Parse(testCase.m_uri, scheme, hostname, port, path); - EXPECT_EQ(testCase.m_result, result); - - EXPECT_STREQ(testCase.m_scheme, scheme.str().c_str()); - EXPECT_STREQ(testCase.m_hostname, hostname.str().c_str()); - EXPECT_EQ(testCase.m_port, port); - EXPECT_STREQ(testCase.m_path, path.str().c_str()); -} - -TEST(UriParserTest, BracketedHostname) { - const UriTestCase testCase("connect://[192.168.100.132]", "connect", - "192.168.100.132", -1, "/"); - VALIDATE -} - -TEST(UriParserTest, BracketedHostnameWithPortIPv4) { - // Android device over IPv4: port is a part of the hostname. - const UriTestCase testCase("connect://[192.168.100.132:1234]", "connect", - "192.168.100.132:1234", -1, "/"); - VALIDATE -} - -TEST(UriParserTest, BracketedHostnameWithPortIPv6) { - // Android device over IPv6: port is a part of the hostname. - const UriTestCase testCase( - "connect://[[2601:600:107f:db64:a42b:4faa:284]:1234]", "connect", - "[2601:600:107f:db64:a42b:4faa:284]:1234", -1, "/"); - VALIDATE -} - -TEST(UriParserTest, BracketedHostnameWithColon) { - const UriTestCase testCase("connect://[192.168.100.132:5555]:1234", "connect", - "192.168.100.132:5555", 1234, "/"); - VALIDATE -} - -TEST(UriParserTest, SchemeHostSeparator) { - const UriTestCase testCase("x:/y"); - VALIDATE -} - -TEST(UriParserTest, SchemeHostSeparator2) { - const UriTestCase testCase("x:y"); - VALIDATE -} - -TEST(UriParserTest, SchemeHostSeparator3) { - const UriTestCase testCase("x//y"); - VALIDATE -} - -TEST(UriParserTest, SchemeHostSeparator4) { - const UriTestCase testCase("x/y"); - VALIDATE -} - -TEST(UriParserTest, BadPort) { - const UriTestCase testCase("x://y:a/"); - VALIDATE -} - -TEST(UriParserTest, BadPort2) { - const UriTestCase testCase("x://y:5432a/"); - VALIDATE -} - -TEST(UriParserTest, Empty) { - const UriTestCase testCase(""); - VALIDATE -} - -TEST(UriParserTest, PortOverflow) { - const UriTestCase testCase("x://" - "y:" - "0123456789012345678901234567890123456789012345678" - "9012345678901234567890123456789012345678901234567" - "89/"); - VALIDATE -} diff --git a/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp b/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp deleted file mode 100644 index 7cd89609b35..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===-- UserIDResolverTest.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 "lldb/Utility/UserIDResolver.h" -#include "gmock/gmock.h" - -using namespace lldb_private; -using namespace testing; - -namespace { -class TestUserIDResolver : public UserIDResolver { -public: - MOCK_METHOD1(DoGetUserName, llvm::Optional(id_t uid)); - MOCK_METHOD1(DoGetGroupName, llvm::Optional(id_t gid)); -}; -} // namespace - -TEST(UserIDResolver, GetUserName) { - StrictMock r; - llvm::StringRef user47("foo"); - EXPECT_CALL(r, DoGetUserName(47)).Times(1).WillOnce(Return(user47.str())); - EXPECT_CALL(r, DoGetUserName(42)).Times(1).WillOnce(Return(llvm::None)); - - // Call functions twice to make sure the caching works. - EXPECT_EQ(user47, r.GetUserName(47)); - EXPECT_EQ(user47, r.GetUserName(47)); - EXPECT_EQ(llvm::None, r.GetUserName(42)); - EXPECT_EQ(llvm::None, r.GetUserName(42)); -} - -TEST(UserIDResolver, GetGroupName) { - StrictMock r; - llvm::StringRef group47("foo"); - EXPECT_CALL(r, DoGetGroupName(47)).Times(1).WillOnce(Return(group47.str())); - EXPECT_CALL(r, DoGetGroupName(42)).Times(1).WillOnce(Return(llvm::None)); - - // Call functions twice to make sure the caching works. - EXPECT_EQ(group47, r.GetGroupName(47)); - EXPECT_EQ(group47, r.GetGroupName(47)); - EXPECT_EQ(llvm::None, r.GetGroupName(42)); - EXPECT_EQ(llvm::None, r.GetGroupName(42)); -} diff --git a/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp b/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp deleted file mode 100644 index a04cd27362d..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//===-- VASprintfTest.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 "lldb/Utility/VASPrintf.h" -#include "llvm/ADT/SmallString.h" - -#include "gtest/gtest.h" - -#include - -#if defined (_WIN32) -#define TEST_ENCODING ".932" // On Windows, test codepage 932 -#else -#define TEST_ENCODING "C" // ...otherwise, any widely available uni-byte LC -#endif - -using namespace lldb_private; -using namespace llvm; - -static bool Sprintf(llvm::SmallVectorImpl &Buffer, const char *Fmt, ...) { - va_list args; - va_start(args, Fmt); - bool Result = VASprintf(Buffer, Fmt, args); - va_end(args); - return Result; -} - -TEST(VASprintfTest, NoBufferResize) { - std::string TestStr("small"); - - llvm::SmallString<32> BigBuffer; - ASSERT_TRUE(Sprintf(BigBuffer, "%s", TestStr.c_str())); - EXPECT_STREQ(TestStr.c_str(), BigBuffer.c_str()); - EXPECT_EQ(TestStr.size(), BigBuffer.size()); -} - -TEST(VASprintfTest, BufferResize) { - std::string TestStr("bigger"); - llvm::SmallString<4> SmallBuffer; - ASSERT_TRUE(Sprintf(SmallBuffer, "%s", TestStr.c_str())); - EXPECT_STREQ(TestStr.c_str(), SmallBuffer.c_str()); - EXPECT_EQ(TestStr.size(), SmallBuffer.size()); -} - -TEST(VASprintfTest, EncodingError) { - // Save the current locale first. - std::string Current(::setlocale(LC_ALL, nullptr)); - - // Ensure tested locale is successfully set - ASSERT_TRUE(setlocale(LC_ALL, TEST_ENCODING)); - - wchar_t Invalid[2]; - Invalid[0] = 0x100; - Invalid[1] = 0; - llvm::SmallString<32> Buffer; - EXPECT_FALSE(Sprintf(Buffer, "%ls", Invalid)); - EXPECT_EQ("", Buffer); - - // Ensure we've restored the original locale once tested - ASSERT_TRUE(setlocale(LC_ALL, Current.c_str())); -} diff --git a/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp b/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp deleted file mode 100644 index 064f12090b9..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp +++ /dev/null @@ -1,151 +0,0 @@ -//===-- VMRangeTest.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 "gtest/gtest.h" - -#include - -#include "lldb/Utility/VMRange.h" - -using namespace lldb_private; - -namespace lldb_private { -void PrintTo(const VMRange &v, std::ostream *os) { - (*os) << "VMRange(" << v.GetBaseAddress() << ", " << v.GetEndAddress() << ")"; -} -} // namespace lldb_private - -TEST(VMRange, IsValid) { - VMRange range; - EXPECT_FALSE(range.IsValid()); - - range.Reset(0x1, 0x100); - EXPECT_TRUE(range.IsValid()); - - range.Reset(0x1, 0x1); - EXPECT_FALSE(range.IsValid()); -} - -TEST(VMRange, Clear) { - VMRange range(0x100, 0x200); - EXPECT_NE(VMRange(), range); - range.Clear(); - EXPECT_EQ(VMRange(), range); -} - -TEST(VMRange, Comparison) { - VMRange range1(0x100, 0x200); - VMRange range2(0x100, 0x200); - EXPECT_EQ(range1, range2); - - EXPECT_NE(VMRange(0x100, 0x1ff), range1); - EXPECT_NE(VMRange(0x100, 0x201), range1); - EXPECT_NE(VMRange(0x0ff, 0x200), range1); - EXPECT_NE(VMRange(0x101, 0x200), range1); - - range2.Clear(); - EXPECT_NE(range1, range2); -} - -TEST(VMRange, Reset) { - VMRange range(0x100, 0x200); - EXPECT_FALSE(VMRange(0x200, 0x200) == range); - range.Reset(0x200, 0x200); - EXPECT_TRUE(VMRange(0x200, 0x200) == range); -} - -TEST(VMRange, SetEndAddress) { - VMRange range(0x100, 0x200); - - range.SetEndAddress(0xFF); - EXPECT_EQ(0U, range.GetByteSize()); - EXPECT_FALSE(range.IsValid()); - - range.SetEndAddress(0x101); - EXPECT_EQ(1U, range.GetByteSize()); - EXPECT_TRUE(range.IsValid()); -} - -TEST(VMRange, ContainsAddr) { - VMRange range(0x100, 0x200); - - EXPECT_FALSE(range.Contains(0x00)); - EXPECT_FALSE(range.Contains(0xFF)); - EXPECT_TRUE(range.Contains(0x100)); - EXPECT_TRUE(range.Contains(0x101)); - EXPECT_TRUE(range.Contains(0x1FF)); - EXPECT_FALSE(range.Contains(0x200)); - EXPECT_FALSE(range.Contains(0x201)); - EXPECT_FALSE(range.Contains(0xFFF)); - EXPECT_FALSE(range.Contains(std::numeric_limits::max())); -} - -TEST(VMRange, ContainsRange) { - VMRange range(0x100, 0x200); - - EXPECT_FALSE(range.Contains(VMRange(0x0, 0x0))); - - EXPECT_FALSE(range.Contains(VMRange(0x0, 0x100))); - EXPECT_FALSE(range.Contains(VMRange(0x0, 0x101))); - EXPECT_TRUE(range.Contains(VMRange(0x100, 0x105))); - EXPECT_TRUE(range.Contains(VMRange(0x101, 0x105))); - EXPECT_TRUE(range.Contains(VMRange(0x100, 0x1FF))); - EXPECT_TRUE(range.Contains(VMRange(0x105, 0x200))); - EXPECT_FALSE(range.Contains(VMRange(0x105, 0x201))); - EXPECT_FALSE(range.Contains(VMRange(0x200, 0x201))); - EXPECT_TRUE(range.Contains(VMRange(0x100, 0x200))); - EXPECT_FALSE( - range.Contains(VMRange(0x105, std::numeric_limits::max()))); - - // Empty range. - EXPECT_TRUE(range.Contains(VMRange(0x100, 0x100))); - - range.Clear(); - EXPECT_FALSE(range.Contains(VMRange(0x0, 0x0))); -} - -TEST(VMRange, Ordering) { - VMRange range1(0x44, 0x200); - VMRange range2(0x100, 0x1FF); - VMRange range3(0x100, 0x200); - - EXPECT_LE(range1, range1); - EXPECT_GE(range1, range1); - - EXPECT_LT(range1, range2); - EXPECT_LT(range2, range3); - - EXPECT_GT(range2, range1); - EXPECT_GT(range3, range2); - - // Ensure that < and > are always false when comparing ranges with themselves. - EXPECT_FALSE(range1 < range1); - EXPECT_FALSE(range2 < range2); - EXPECT_FALSE(range3 < range3); - - EXPECT_FALSE(range1 > range1); - EXPECT_FALSE(range2 > range2); - EXPECT_FALSE(range3 > range3); -} - -TEST(VMRange, CollectionContains) { - VMRange::collection collection = {VMRange(0x100, 0x105), - VMRange(0x108, 0x110)}; - - EXPECT_FALSE(VMRange::ContainsValue(collection, 0xFF)); - EXPECT_TRUE(VMRange::ContainsValue(collection, 0x100)); - EXPECT_FALSE(VMRange::ContainsValue(collection, 0x105)); - EXPECT_TRUE(VMRange::ContainsValue(collection, 0x109)); - - EXPECT_TRUE(VMRange::ContainsRange(collection, VMRange(0x100, 0x104))); - EXPECT_TRUE(VMRange::ContainsRange(collection, VMRange(0x108, 0x100))); - EXPECT_FALSE(VMRange::ContainsRange(collection, VMRange(0xFF, 0x100))); - - // TODO: Implement and test ContainsRange with values that span multiple - // ranges in the collection. -} diff --git a/gnu/llvm/lldb/unittests/Utility/XcodeSDKTest.cpp b/gnu/llvm/lldb/unittests/Utility/XcodeSDKTest.cpp deleted file mode 100644 index 69e4d2caa01..00000000000 --- a/gnu/llvm/lldb/unittests/Utility/XcodeSDKTest.cpp +++ /dev/null @@ -1,241 +0,0 @@ -//===-- XcodeSDKTest.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 "gtest/gtest.h" - -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/XcodeSDK.h" - -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" - -#include - -using namespace lldb_private; - -TEST(XcodeSDKTest, ParseTest) { - EXPECT_EQ(XcodeSDK::GetAnyMacOS().GetType(), XcodeSDK::MacOSX); - EXPECT_EQ(XcodeSDK("MacOSX.sdk").GetType(), XcodeSDK::MacOSX); - EXPECT_EQ(XcodeSDK("iPhoneSimulator.sdk").GetType(), XcodeSDK::iPhoneSimulator); - EXPECT_EQ(XcodeSDK("iPhoneOS.sdk").GetType(), XcodeSDK::iPhoneOS); - EXPECT_EQ(XcodeSDK("AppleTVSimulator.sdk").GetType(), XcodeSDK::AppleTVSimulator); - EXPECT_EQ(XcodeSDK("AppleTVOS.sdk").GetType(), XcodeSDK::AppleTVOS); - EXPECT_EQ(XcodeSDK("WatchSimulator.sdk").GetType(), XcodeSDK::WatchSimulator); - EXPECT_EQ(XcodeSDK("WatchOS.sdk").GetType(), XcodeSDK::watchOS); - EXPECT_EQ(XcodeSDK("Linux.sdk").GetType(), XcodeSDK::Linux); - EXPECT_EQ(XcodeSDK("MacOSX.sdk").GetVersion(), llvm::VersionTuple()); - EXPECT_EQ(XcodeSDK("MacOSX10.9.sdk").GetVersion(), llvm::VersionTuple(10, 9)); - EXPECT_EQ(XcodeSDK("MacOSX10.15.4.sdk").GetVersion(), llvm::VersionTuple(10, 15)); - EXPECT_EQ(XcodeSDK("MacOSX.sdk").IsAppleInternalSDK(), false); - EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").GetType(), XcodeSDK::MacOSX); - EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").GetVersion(), - llvm::VersionTuple(10, 15)); - EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").IsAppleInternalSDK(), true); - EXPECT_EQ(XcodeSDK().GetType(), XcodeSDK::unknown); - EXPECT_EQ(XcodeSDK().GetVersion(), llvm::VersionTuple()); -} - -TEST(XcodeSDKTest, MergeTest) { - XcodeSDK sdk("MacOSX.sdk"); - sdk.Merge(XcodeSDK("WatchOS.sdk")); - // This doesn't make any particular sense and shouldn't happen in practice, we - // just want to guarantee a well-defined behavior when choosing one - // SDK to fit all CUs in an lldb::Module. - // -> The higher number wins. - EXPECT_EQ(sdk.GetType(), XcodeSDK::watchOS); - sdk.Merge(XcodeSDK("WatchOS1.1.sdk")); - EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(1, 1)); - sdk.Merge(XcodeSDK("WatchOS2.0.sdk")); - EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0)); - sdk.Merge(XcodeSDK("WatchOS1.1.Internal.sdk")); - EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0)); - EXPECT_EQ(sdk.IsAppleInternalSDK(), true); - XcodeSDK empty; - empty.Merge(XcodeSDK("MacOSX10.14.Internal.sdk")); - EXPECT_EQ(empty.GetString(), llvm::StringRef("MacOSX10.14.Internal.sdk")); -} - -#ifndef _WIN32 -TEST(XcodeSDKTest, SDKSupportsModules) { - std::string base = "/Applications/Xcode.app/Contents/Developer/Platforms/"; - EXPECT_TRUE(XcodeSDK::SDKSupportsModules( - XcodeSDK::Type::iPhoneSimulator, - FileSpec( - base + - "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.0.sdk"))); - EXPECT_TRUE(XcodeSDK::SDKSupportsModules( - XcodeSDK::Type::iPhoneSimulator, - FileSpec(base + "iPhoneSimulator.platform/Developer/SDKs/" - "iPhoneSimulator12.0.Internal.sdk"))); - EXPECT_FALSE(XcodeSDK::SDKSupportsModules( - XcodeSDK::Type::iPhoneSimulator, - FileSpec( - base + - "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.2.sdk"))); - EXPECT_TRUE(XcodeSDK::SDKSupportsModules( - XcodeSDK::Type::MacOSX, - FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk"))); - EXPECT_FALSE(XcodeSDK::SDKSupportsModules( - XcodeSDK::Type::MacOSX, - FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk"))); -} -#endif - -TEST(XcodeSDKTest, SDKSupportsSwift) { - EXPECT_TRUE(XcodeSDK("iPhoneSimulator12.0.sdk").SupportsSwift()); - EXPECT_TRUE(XcodeSDK("iPhoneSimulator12.0.Internal.sdk").SupportsSwift()); - EXPECT_FALSE(XcodeSDK("iPhoneSimulator7.2.sdk").SupportsSwift()); - EXPECT_TRUE(XcodeSDK("MacOSX10.10.sdk").SupportsSwift()); - EXPECT_FALSE(XcodeSDK("MacOSX10.9.sdk").SupportsSwift()); - EXPECT_TRUE(XcodeSDK("Linux.sdk").SupportsSwift()); - EXPECT_TRUE(XcodeSDK("MacOSX.sdk").SupportsSwift()); - EXPECT_FALSE(XcodeSDK("EverythingElse.sdk").SupportsSwift()); -} - -TEST(XcodeSDKTest, GetCanonicalNameAndConstruct) { - XcodeSDK::Info info; - info.type = XcodeSDK::Type::MacOSX; - EXPECT_EQ("macosx", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::iPhoneSimulator; - EXPECT_EQ("iphonesimulator", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::iPhoneOS; - EXPECT_EQ("iphoneos", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::AppleTVSimulator; - EXPECT_EQ("appletvsimulator", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::AppleTVOS; - EXPECT_EQ("appletvos", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::WatchSimulator; - EXPECT_EQ("watchsimulator", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::watchOS; - EXPECT_EQ("watchos", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::Linux; - EXPECT_EQ("linux", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::unknown; - EXPECT_EQ("", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.internal = true; - info.type = XcodeSDK::Type::MacOSX; - EXPECT_EQ("macosx.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::iPhoneSimulator; - EXPECT_EQ("iphonesimulator.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::iPhoneOS; - EXPECT_EQ("iphoneos.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::AppleTVSimulator; - EXPECT_EQ("appletvsimulator.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::AppleTVOS; - EXPECT_EQ("appletvos.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::WatchSimulator; - EXPECT_EQ("watchsimulator.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::watchOS; - EXPECT_EQ("watchos.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::MacOSX; - info.version = llvm::VersionTuple(10, 9); - EXPECT_EQ("macosx10.9.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); - - info.type = XcodeSDK::Type::iPhoneOS; - info.version = llvm::VersionTuple(7, 0); - EXPECT_EQ("iphoneos7.0.internal", XcodeSDK::GetCanonicalName(info)); - EXPECT_EQ(XcodeSDK(info).Parse(), info); -} - -TEST(XcodeSDKTest, GetSDKTypeForTriple) { - EXPECT_EQ( - XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-apple-macosx10.14")), - XcodeSDK::Type::MacOSX); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-apple-darwin")), - XcodeSDK::Type::MacOSX); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( - llvm::Triple("x86_64-apple-ios13.4-simulator")), - XcodeSDK::Type::iPhoneSimulator); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-ios13.4")), - XcodeSDK::Type::iPhoneOS); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( - llvm::Triple("x86_64-apple-ios13.4-macabi")), - XcodeSDK::Type::MacOSX); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( - llvm::Triple("x86_64-apple-tvos-simulator")), - XcodeSDK::Type::AppleTVSimulator); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-tvos")), - XcodeSDK::Type::AppleTVOS); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( - llvm::Triple("x86_64-apple-watchos-simulator")), - XcodeSDK::Type::WatchSimulator); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-watchos")), - XcodeSDK::Type::watchOS); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-unknown-linux")), - XcodeSDK::Type::Linux); - EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("i386-unknown-netbsd")), - XcodeSDK::Type::unknown); -} - -TEST(XcodeSDKTest, FindXcodeContentsDirectoryInPath) { - std::string standard = - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX.sdk"; - EXPECT_EQ("/Applications/Xcode.app/Contents", - XcodeSDK::FindXcodeContentsDirectoryInPath(standard)); - - std::string standard_version = - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("/Applications/Xcode.app/Contents", - XcodeSDK::FindXcodeContentsDirectoryInPath(standard_version)); - - std::string beta = "/Applications/Xcode-beta.app/Contents/Developer/" - "Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("/Applications/Xcode-beta.app/Contents", - XcodeSDK::FindXcodeContentsDirectoryInPath(beta)); - - std::string no_app = - "/Applications/Xcode/Contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_app)); - - std::string no_contents = - "/Applications/Xcode.app/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_contents)); - - std::string no_capitalization = - "/Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_capitalization)); -} diff --git a/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt b/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt deleted file mode 100644 index fd488c1623b..00000000000 --- a/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# Note: debugserver is a Darwin-only implementation of a remote debugging -# server. It is not intended to be used on other platforms. The tests are here -# because using the LLDB Host API is convenient and allows testing of both parts -# of the debugserver communication path. If you are looking for a non-darwin -# remote debugging server, please use lldb-server. - -add_lldb_unittest(debugserverTests - JSONTest.cpp - RNBSocketTest.cpp - debugserver_LogCallback.cpp - - LINK_LIBS - lldbDebugserverCommon - lldbHost - LLVMTestingSupport - LINK_COMPONENTS - Support - ) - -target_include_directories(debugserverTests PRIVATE - ${LLDB_SOURCE_DIR}/tools/debugserver/source - ${LLDB_SOURCE_DIR}/tools/debugserver/source/MacOSX) - -if(APPLE_EMBEDDED) - set_property(TARGET debugserverTests APPEND PROPERTY COMPILE_DEFINITIONS - WITH_LOCKDOWN - WITH_FBS - WITH_BKS - ) - - add_lldb_unittest(debugserverNonUITests - JSONTest.cpp - RNBSocketTest.cpp - debugserver_LogCallback.cpp - - LINK_LIBS - lldbDebugserverCommon_NonUI - lldbHost - LINK_COMPONENTS - Support - ) -endif() diff --git a/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp b/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp deleted file mode 100644 index ee359cc341d..00000000000 --- a/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp +++ /dev/null @@ -1,89 +0,0 @@ -//===-- JSONTest.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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "JSON.h" - -template -void TestJSON(JSONValue *json_val, const std::function &test_func) { - ASSERT_THAT(json_val, testing::NotNull()); - ASSERT_TRUE(T::classof(json_val)); - test_func(static_cast(*json_val)); -} - -JSONValue::SP ParseJSON(const char *json_string) { - return JSONParser(json_string).ParseJSONValue(); -} - -template -void ParseAndTestJSON( - const char *json_string, - const std::function &test_func = [](T &) {}) { - auto json_val = ParseJSON(json_string); - TestJSON(json_val.get(), test_func); -} - -TEST(JSON, Parse) { - ParseAndTestJSON("\"foo\"", [](JSONString &string_val) { - EXPECT_EQ(string_val.GetData(), "foo"); - }); - EXPECT_THAT(ParseJSON("\"foo"), testing::IsNull()); - ParseAndTestJSON("3", [](JSONNumber &number_val) { - EXPECT_EQ(number_val.GetAsSigned(), 3); - EXPECT_EQ(number_val.GetAsUnsigned(), 3u); - EXPECT_EQ(number_val.GetAsDouble(), 3.0); - }); - ParseAndTestJSON("-5", [](JSONNumber &number_val) { - EXPECT_EQ(number_val.GetAsSigned(), -5); - EXPECT_EQ(number_val.GetAsDouble(), -5.0); - }); - ParseAndTestJSON("-6.4", [](JSONNumber &number_val) { - EXPECT_EQ(number_val.GetAsSigned(), -6); - EXPECT_EQ(number_val.GetAsDouble(), -6.4); - }); - EXPECT_THAT(ParseJSON("-1.2.3"), testing::IsNull()); - ParseAndTestJSON("true"); - ParseAndTestJSON("false"); - ParseAndTestJSON("null"); - ParseAndTestJSON( - "{ \"key1\": 4, \"key2\": \"foobar\" }", [](JSONObject &obj_val) { - TestJSON(obj_val.GetObject("key1").get(), - [](JSONNumber &number_val) { - EXPECT_EQ(number_val.GetAsSigned(), 4); - EXPECT_EQ(number_val.GetAsUnsigned(), 4u); - EXPECT_EQ(number_val.GetAsDouble(), 4.0); - }); - TestJSON(obj_val.GetObject("key2").get(), - [](JSONString &string_val) { - EXPECT_EQ(string_val.GetData(), "foobar"); - }); - }); - ParseAndTestJSON("[1, \"bar\", 3.14]", [](JSONArray &array_val) { - EXPECT_EQ(array_val.GetNumElements(), 3u); - TestJSON(array_val.GetObject(0).get(), - [](JSONNumber &number_val) { - EXPECT_EQ(number_val.GetAsSigned(), 1); - EXPECT_EQ(number_val.GetAsUnsigned(), 1u); - EXPECT_EQ(number_val.GetAsDouble(), 1.0); - }); - TestJSON( - array_val.GetObject(1).get(), - [](JSONString &string_val) { EXPECT_EQ(string_val.GetData(), "bar"); }); - TestJSON(array_val.GetObject(2).get(), - [](JSONNumber &number_val) { - EXPECT_EQ(number_val.GetAsSigned(), 3); - EXPECT_EQ(number_val.GetAsUnsigned(), 3u); - EXPECT_EQ(number_val.GetAsDouble(), 3.14); - }); - }); - ParseAndTestJSON("[]", [](JSONArray &array_val) { - EXPECT_EQ(array_val.GetNumElements(), 0u); - }); -} diff --git a/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp b/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp deleted file mode 100644 index 2625a6d36b5..00000000000 --- a/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp +++ /dev/null @@ -1,162 +0,0 @@ -//===-- RNBSocketTest.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 "gtest/gtest.h" - -#include -#include -#include - -#include "RNBDefs.h" -#include "RNBSocket.h" -#include "lldb/Host/Socket.h" -#include "lldb/Host/StringConvert.h" -#include "lldb/Host/common/TCPSocket.h" -#include "llvm/Testing/Support/Error.h" - -using namespace lldb_private; - -std::string hello = "Hello, world!"; -std::string goodbye = "Goodbye!"; - -static void ServerCallbackv4(const void *baton, in_port_t port) { - auto child_pid = fork(); - if (child_pid == 0) { - char addr_buffer[256]; - sprintf(addr_buffer, "%s:%d", (const char *)baton, port); - llvm::Expected> socket_or_err = - Socket::TcpConnect(addr_buffer, false); - ASSERT_THAT_EXPECTED(socket_or_err, llvm::Succeeded()); - Socket *client_socket = socket_or_err->get(); - - char buffer[32]; - size_t read_size = 32; - Status err = client_socket->Read((void *)&buffer[0], read_size); - if (err.Fail()) - abort(); - std::string Recv(&buffer[0], read_size); - if (Recv != hello) - abort(); - size_t write_size = goodbye.length(); - err = client_socket->Write(goodbye.c_str(), write_size); - if (err.Fail()) - abort(); - if (write_size != goodbye.length()) - abort(); - delete client_socket; - exit(0); - } -} - -void TestSocketListen(const char *addr) { - // Skip IPv6 tests if there isn't a valid interafce - auto addresses = lldb_private::SocketAddress::GetAddressInfo( - addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); - if (addresses.size() == 0) - return; - - char addr_wrap[256]; - if (addresses.front().GetFamily() == AF_INET6) - sprintf(addr_wrap, "[%s]", addr); - else - sprintf(addr_wrap, "%s", addr); - - RNBSocket server_socket; - auto result = - server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr_wrap); - ASSERT_TRUE(result == rnb_success); - result = server_socket.Write(hello.c_str(), hello.length()); - ASSERT_TRUE(result == rnb_success); - std::string bye; - result = server_socket.Read(bye); - ASSERT_TRUE(result == rnb_success); - ASSERT_EQ(bye, goodbye); - - int exit_status; - wait(&exit_status); - ASSERT_EQ(exit_status, 0); -} - -TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); } - -TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); } - -TEST(RNBSocket, AnyListen) { TestSocketListen("*"); } - -void TestSocketConnect(const char *addr) { - // Skip IPv6 tests if there isn't a valid interafce - auto addresses = lldb_private::SocketAddress::GetAddressInfo( - addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); - if (addresses.size() == 0) - return; - - char addr_wrap[256]; - if (addresses.front().GetFamily() == AF_INET6) - sprintf(addr_wrap, "[%s]:0", addr); - else - sprintf(addr_wrap, "%s:0", addr); - - Socket *server_socket; - Predicate port_predicate; - port_predicate.SetValue(0, eBroadcastNever); - llvm::Expected> socket_or_err = - Socket::TcpListen(addr_wrap, false, &port_predicate); - ASSERT_THAT_EXPECTED(socket_or_err, llvm::Succeeded()); - server_socket = socket_or_err->get(); - - auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber(); - auto child_pid = fork(); - if (child_pid != 0) { - RNBSocket client_socket; - auto result = client_socket.Connect(addr, port); - ASSERT_TRUE(result == rnb_success); - result = client_socket.Write(hello.c_str(), hello.length()); - ASSERT_TRUE(result == rnb_success); - std::string bye; - result = client_socket.Read(bye); - ASSERT_TRUE(result == rnb_success); - ASSERT_EQ(bye, goodbye); - } else { - Socket *connected_socket; - Status err = server_socket->Accept(connected_socket); - if (err.Fail()) { - llvm::errs() << err.AsCString(); - abort(); - } - char buffer[32]; - size_t read_size = 32; - err = connected_socket->Read((void *)&buffer[0], read_size); - if (err.Fail()) { - llvm::errs() << err.AsCString(); - abort(); - } - std::string Recv(&buffer[0], read_size); - if (Recv != hello) { - llvm::errs() << err.AsCString(); - abort(); - } - size_t write_size = goodbye.length(); - err = connected_socket->Write(goodbye.c_str(), write_size); - if (err.Fail()) { - llvm::errs() << err.AsCString(); - abort(); - } - if (write_size != goodbye.length()) { - llvm::errs() << err.AsCString(); - abort(); - } - exit(0); - } - int exit_status; - wait(&exit_status); - ASSERT_EQ(exit_status, 0); -} - -TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); } - -TEST(RNBSocket, LoopBackConnectIPv6) { TestSocketConnect("::1"); } diff --git a/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp b/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp deleted file mode 100644 index 2c7da2d127c..00000000000 --- a/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp +++ /dev/null @@ -1,17 +0,0 @@ -//===-- debugserver_LogCallback.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 -// -//===----------------------------------------------------------------------===// - -// this function is defined in debugserver.cpp, but is needed to link the -// debugserver Common library. It is for logging only, so it is left -// unimplemented here. - -#include -#include - -void FileLogCallback(void *baton, uint32_t flags, const char *format, - va_list args) {} diff --git a/gnu/llvm/lldb/unittests/gtest_common.h b/gnu/llvm/lldb/unittests/gtest_common.h deleted file mode 100644 index 3a92123a949..00000000000 --- a/gnu/llvm/lldb/unittests/gtest_common.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef LLDB_UNITTESTS_GTEST_COMMON_H - -#define LLDB_UNITTESTS_GTEST_COMMON_H - -//===-- gtest_common.h ------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#if defined(LLDB_GTEST_COMMON_H) -#error "gtest_common.h should not be included manually." -#else -#define LLDB_GTEST_COMMON_H -#endif - -// This header file is force included by all of LLDB's unittest compilation -// units. Be very leary about putting anything in this file. - -#endif diff --git a/gnu/llvm/lldb/unittests/tools/CMakeLists.txt b/gnu/llvm/lldb/unittests/tools/CMakeLists.txt deleted file mode 100644 index 055fc6e6f5d..00000000000 --- a/gnu/llvm/lldb/unittests/tools/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -if(LLDB_TOOL_LLDB_SERVER_BUILD) - add_subdirectory(lldb-server) -endif() diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/CMakeLists.txt b/gnu/llvm/lldb/unittests/tools/lldb-server/CMakeLists.txt deleted file mode 100644 index 1a7603077b8..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -set(ALL_LLDB_TEST_EXECUTABLES) - -function(add_lldb_test_executable test_name) - set(EXCLUDE_FROM_ALL ON) - add_llvm_executable(${test_name} NO_INSTALL_RPATH ${ARGN}) - set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}) - set_output_directory(${test_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir}) - list(APPEND ALL_LLDB_TEST_EXECUTABLES ${test_name}) - set(ALL_LLDB_TEST_EXECUTABLES ${ALL_LLDB_TEST_EXECUTABLES} PARENT_SCOPE) - set_target_properties(${test_name} PROPERTIES FOLDER "lldb tests") -endfunction() - -add_lldb_test_executable(thread_inferior inferior/thread_inferior.cpp) -add_lldb_test_executable(environment_check inferior/environment_check.cpp) - -if(LLDB_CAN_USE_DEBUGSERVER AND (LLDB_TOOL_DEBUGSERVER_BUILD OR LLDB_USE_SYSTEM_DEBUGSERVER)) - if(LLDB_USE_SYSTEM_DEBUGSERVER) - lldb_find_system_debugserver(debugserver_path) - else() - set(debugserver_path $) - endif() - add_definitions(-DLLDB_SERVER="${debugserver_path}" -DLLDB_SERVER_IS_DEBUGSERVER=1) -else() - add_definitions(-DLLDB_SERVER="$" -DLLDB_SERVER_IS_DEBUGSERVER=0) -endif() - -add_definitions( - -DLLDB_TEST_INFERIOR_PATH="${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" - -DLLDB_TEST_INFERIOR_SUFFIX="${CMAKE_EXECUTABLE_SUFFIX}" - ) -add_subdirectory(tests) diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp deleted file mode 100644 index 7d8063cc8c8..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//===-- thread_inferior.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 -#include - -int main() { - const char *value = std::getenv("LLDB_TEST_MAGIC_VARIABLE"); - if (!value) - return 1; - if (std::string(value) != "LLDB_TEST_MAGIC_VALUE") - return 2; - return 0; -} diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp deleted file mode 100644 index 43e9b8cbc10..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp +++ /dev/null @@ -1,40 +0,0 @@ -//===-- thread_inferior.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 -#include -#include -#include -#include - -int main(int argc, char* argv[]) { - int thread_count = 2; - if (argc > 1) { - thread_count = std::stoi(argv[1], nullptr, 10); - } - - std::atomic delay(true); - std::vector threads; - for (int i = 0; i < thread_count; i++) { - threads.push_back(std::thread([&delay] { - while (delay.load()) - std::this_thread::sleep_for(std::chrono::seconds(1)); - })); - } - - // Cause a break. - volatile char *p = nullptr; - *p = 'a'; - - delay.store(false); - for (std::thread& t : threads) { - t.join(); - } - - return 0; -} diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/CMakeLists.txt b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/CMakeLists.txt deleted file mode 100644 index ed5eb88ba52..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -add_lldb_unittest(LLDBServerTests - LLGSTest.cpp - MessageObjects.cpp - TestBase.cpp - TestClient.cpp - ThreadIdsInJstopinfoTest.cpp - - LINK_LIBS - lldbHost - lldbCore - lldbInterpreter - lldbTarget - lldbPluginPlatformLinux - lldbPluginProcessGDBRemote - - LLVMTestingSupport - LINK_COMPONENTS - Support - ) - -add_dependencies(LLDBServerTests lldb-server ${ALL_LLDB_TEST_EXECUTABLES}) diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp deleted file mode 100644 index 92efeffde7f..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===-- LLGSTest.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 "TestBase.h" -#include "lldb/Host/Host.h" -#include "llvm/Testing/Support/Error.h" - -using namespace llgs_tests; -using namespace lldb_private; -using namespace llvm; - -#ifdef SendMessage -#undef SendMessage -#endif - -// Disable this test on Windows as it appears to have a race condition -// that causes lldb-server not to exit after the inferior hangs up. -#if !defined(_WIN32) -TEST_F(TestBase, LaunchModePreservesEnvironment) { - putenv(const_cast("LLDB_TEST_MAGIC_VARIABLE=LLDB_TEST_MAGIC_VALUE")); - - auto ClientOr = TestClient::launch(getLogFileName(), - {getInferiorPath("environment_check")}); - ASSERT_THAT_EXPECTED(ClientOr, Succeeded()); - auto &Client = **ClientOr; - - ASSERT_THAT_ERROR(Client.ContinueAll(), Succeeded()); - ASSERT_THAT_EXPECTED( - Client.GetLatestStopReplyAs(), - HasValue(testing::Property(&StopReply::getKind, - WaitStatus{WaitStatus::Exit, 0}))); -} -#endif - -TEST_F(TestBase, DS_TEST(DebugserverEnv)) { - // Test that --env takes precedence over inherited environment variables. - putenv(const_cast("LLDB_TEST_MAGIC_VARIABLE=foobar")); - - auto ClientOr = TestClient::launchCustom(getLogFileName(), - { "--env", "LLDB_TEST_MAGIC_VARIABLE=LLDB_TEST_MAGIC_VALUE" }, - {getInferiorPath("environment_check")}); - ASSERT_THAT_EXPECTED(ClientOr, Succeeded()); - auto &Client = **ClientOr; - - ASSERT_THAT_ERROR(Client.ContinueAll(), Succeeded()); - ASSERT_THAT_EXPECTED( - Client.GetLatestStopReplyAs(), - HasValue(testing::Property(&StopReply::getKind, - WaitStatus{WaitStatus::Exit, 0}))); -} - -TEST_F(TestBase, LLGS_TEST(vAttachRichError)) { - auto ClientOr = TestClient::launch(getLogFileName(), - {getInferiorPath("environment_check")}); - ASSERT_THAT_EXPECTED(ClientOr, Succeeded()); - auto &Client = **ClientOr; - - // Until we enable error strings we should just get the error code. - ASSERT_THAT_ERROR(Client.SendMessage("vAttach;1"), - Failed(testing::Property( - &ErrorInfoBase::message, "Error 255"))); - - ASSERT_THAT_ERROR(Client.SendMessage("QEnableErrorStrings"), Succeeded()); - - // Now, we expect the full error message. - ASSERT_THAT_ERROR( - Client.SendMessage("vAttach;1"), - Failed(testing::Property( - &ErrorInfoBase::message, - testing::StartsWith( - "cannot attach to process 1 when another process with pid")))); -} diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp deleted file mode 100644 index 77bc3a5e6ee..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp +++ /dev/null @@ -1,375 +0,0 @@ -//===-- MessageObjects.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 "MessageObjects.h" -#include "lldb/Utility/Args.h" -#include "lldb/Utility/StringExtractor.h" -#include "llvm/ADT/StringExtras.h" -#include "gtest/gtest.h" - -using namespace lldb_private; -using namespace lldb; -using namespace llvm; -namespace llgs_tests { - -Expected ProcessInfo::create(StringRef response) { - ProcessInfo process_info; - auto elements_or_error = SplitUniquePairList("ProcessInfo", response); - if (!elements_or_error) - return elements_or_error.takeError(); - - auto &elements = *elements_or_error; - if (elements["pid"].getAsInteger(16, process_info.m_pid)) - return make_parsing_error("ProcessInfo: pid"); - if (elements["parent-pid"].getAsInteger(16, process_info.m_parent_pid)) - return make_parsing_error("ProcessInfo: parent-pid"); - if (elements["real-uid"].getAsInteger(16, process_info.m_real_uid)) - return make_parsing_error("ProcessInfo: real-uid"); - if (elements["real-gid"].getAsInteger(16, process_info.m_real_gid)) - return make_parsing_error("ProcessInfo: real-uid"); - if (elements["effective-uid"].getAsInteger(16, process_info.m_effective_uid)) - return make_parsing_error("ProcessInfo: effective-uid"); - if (elements["effective-gid"].getAsInteger(16, process_info.m_effective_gid)) - return make_parsing_error("ProcessInfo: effective-gid"); - if (elements["ptrsize"].getAsInteger(10, process_info.m_ptrsize)) - return make_parsing_error("ProcessInfo: ptrsize"); - - process_info.m_triple = fromHex(elements["triple"]); - StringRef endian_str = elements["endian"]; - if (endian_str == "little") - process_info.m_endian = support::little; - else if (endian_str == "big") - process_info.m_endian = support::big; - else - return make_parsing_error("ProcessInfo: endian"); - - return process_info; -} - -lldb::pid_t ProcessInfo::GetPid() const { return m_pid; } - -support::endianness ProcessInfo::GetEndian() const { return m_endian; } - -//====== ThreadInfo ============================================================ -ThreadInfo::ThreadInfo(StringRef name, StringRef reason, RegisterMap registers, - unsigned int) - : m_name(name.str()), m_reason(reason.str()), - m_registers(std::move(registers)) {} - -const RegisterValue *ThreadInfo::ReadRegister(unsigned int Id) const { - auto Iter = m_registers.find(Id); - return Iter == m_registers.end() ? nullptr : &Iter->getSecond(); -} - -//====== JThreadsInfo ========================================================== - -Expected -JThreadsInfo::parseRegisters(const StructuredData::Dictionary &Dict, - ArrayRef RegInfos) { - RegisterMap Result; - - auto KeysObj = Dict.GetKeys(); - auto Keys = KeysObj->GetAsArray(); - for (size_t i = 0; i < Keys->GetSize(); i++) { - StringRef KeyStr, ValueStr; - Keys->GetItemAtIndexAsString(i, KeyStr); - Dict.GetValueForKeyAsString(KeyStr, ValueStr); - unsigned int Register; - if (!llvm::to_integer(KeyStr, Register, 10)) - return make_parsing_error("JThreadsInfo: register key[{0}]", i); - - auto RegValOr = - parseRegisterValue(RegInfos[Register], ValueStr, support::big); - if (!RegValOr) - return RegValOr.takeError(); - Result[Register] = std::move(*RegValOr); - } - return std::move(Result); -} - -Expected JThreadsInfo::create(StringRef Response, - ArrayRef RegInfos) { - JThreadsInfo jthreads_info; - - StructuredData::ObjectSP json = - StructuredData::ParseJSON(std::string(Response)); - StructuredData::Array *array = json->GetAsArray(); - if (!array) - return make_parsing_error("JThreadsInfo: JSON array"); - - for (size_t i = 0; i < array->GetSize(); i++) { - StructuredData::Dictionary *thread_info; - array->GetItemAtIndexAsDictionary(i, thread_info); - if (!thread_info) - return make_parsing_error("JThreadsInfo: JSON obj at {0}", i); - - StringRef name, reason; - thread_info->GetValueForKeyAsString("name", name); - thread_info->GetValueForKeyAsString("reason", reason); - uint64_t signal; - thread_info->GetValueForKeyAsInteger("signal", signal); - uint64_t tid; - thread_info->GetValueForKeyAsInteger("tid", tid); - - StructuredData::Dictionary *register_dict; - thread_info->GetValueForKeyAsDictionary("registers", register_dict); - if (!register_dict) - return make_parsing_error("JThreadsInfo: registers JSON obj"); - - auto RegsOr = parseRegisters(*register_dict, RegInfos); - if (!RegsOr) - return RegsOr.takeError(); - jthreads_info.m_thread_infos[tid] = - ThreadInfo(name, reason, std::move(*RegsOr), signal); - } - - return jthreads_info; -} - -const ThreadInfoMap &JThreadsInfo::GetThreadInfos() const { - return m_thread_infos; -} - -Expected RegisterInfoParser::create(StringRef Response) { - auto ElementsOr = SplitUniquePairList("RegisterInfoParser", Response); - if (!ElementsOr) - return ElementsOr.takeError(); - auto &Elements = *ElementsOr; - - RegisterInfo Info = { - nullptr, // Name - nullptr, // Alt name - 0, // byte size - 0, // offset - eEncodingUint, // encoding - eFormatHex, // format - { - LLDB_INVALID_REGNUM, // eh_frame reg num - LLDB_INVALID_REGNUM, // DWARF reg num - LLDB_INVALID_REGNUM, // generic reg num - LLDB_INVALID_REGNUM, // process plugin reg num - LLDB_INVALID_REGNUM // native register number - }, - nullptr, - nullptr, - nullptr, // Dwarf expression opcode bytes pointer - 0 // Dwarf expression opcode bytes length - }; - Info.name = ConstString(Elements["name"]).GetCString(); - if (!Info.name) - return make_parsing_error("qRegisterInfo: name"); - - Info.alt_name = ConstString(Elements["alt-name"]).GetCString(); - - if (!to_integer(Elements["bitsize"], Info.byte_size, 10)) - return make_parsing_error("qRegisterInfo: bit-size"); - Info.byte_size /= CHAR_BIT; - - if (!to_integer(Elements["offset"], Info.byte_offset, 10)) - Info.byte_offset = LLDB_INVALID_INDEX32; - - Info.encoding = Args::StringToEncoding(Elements["encoding"]); - if (Info.encoding == eEncodingInvalid) - return make_parsing_error("qRegisterInfo: encoding"); - - Info.format = StringSwitch(Elements["format"]) - .Case("binary", eFormatBinary) - .Case("decimal", eFormatDecimal) - .Case("hex", eFormatHex) - .Case("float", eFormatFloat) - .Case("vector-sint8", eFormatVectorOfSInt8) - .Case("vector-uint8", eFormatVectorOfUInt8) - .Case("vector-sint16", eFormatVectorOfSInt16) - .Case("vector-uint16", eFormatVectorOfUInt16) - .Case("vector-sint32", eFormatVectorOfSInt32) - .Case("vector-uint32", eFormatVectorOfUInt32) - .Case("vector-float32", eFormatVectorOfFloat32) - .Case("vector-uint64", eFormatVectorOfUInt64) - .Case("vector-uint128", eFormatVectorOfUInt128) - .Default(eFormatInvalid); - if (Info.format == eFormatInvalid) - return make_parsing_error("qRegisterInfo: format"); - - Info.kinds[eRegisterKindGeneric] = - Args::StringToGenericRegister(Elements["generic"]); - - return std::move(Info); -} - -Expected parseRegisterValue(const RegisterInfo &Info, - StringRef HexValue, - llvm::support::endianness Endian, - bool ZeroPad) { - SmallString<128> Storage; - if (ZeroPad && HexValue.size() < Info.byte_size * 2) { - Storage.insert(Storage.begin(), Info.byte_size * 2 - HexValue.size(), '0'); - Storage += HexValue; - HexValue = Storage; - } - - SmallVector Bytes(HexValue.size() / 2); - StringExtractor(HexValue).GetHexBytes(Bytes, '\xcc'); - RegisterValue Value; - Status ST; - Value.SetFromMemoryData( - &Info, Bytes.data(), Bytes.size(), - Endian == support::little ? eByteOrderLittle : eByteOrderBig, ST); - if (ST.Fail()) - return ST.ToError(); - return Value; -} - -//====== StopReply ============================================================= -Expected> -StopReply::create(StringRef Response, llvm::support::endianness Endian, - ArrayRef RegInfos) { - if (Response.size() < 3) - return make_parsing_error("StopReply: Invalid packet"); - if (Response.consume_front("T")) - return StopReplyStop::create(Response, Endian, RegInfos); - if (Response.consume_front("W")) - return StopReplyExit::create(Response); - return make_parsing_error("StopReply: Invalid packet"); -} - -Expected StopReplyStop::parseRegisters( - const StringMap> &Elements, - support::endianness Endian, ArrayRef RegInfos) { - - RegisterMap Result; - for (const auto &E : Elements) { - StringRef Key = E.getKey(); - const auto &Val = E.getValue(); - if (Key.size() != 2) - continue; - - unsigned int Reg; - if (!to_integer(Key, Reg, 16)) - continue; - - if (Val.size() != 1) - return make_parsing_error( - "StopReplyStop: multiple entries for register field [{0:x}]", Reg); - - auto RegValOr = parseRegisterValue(RegInfos[Reg], Val[0], Endian); - if (!RegValOr) - return RegValOr.takeError(); - Result[Reg] = std::move(*RegValOr); - } - return std::move(Result); -} - -Expected> -StopReplyStop::create(StringRef Response, support::endianness Endian, - ArrayRef RegInfos) { - unsigned int Signal; - StringRef SignalStr = Response.take_front(2); - Response = Response.drop_front(2); - if (!to_integer(SignalStr, Signal, 16)) - return make_parsing_error("StopReply: stop signal"); - - auto Elements = SplitPairList(Response); - for (StringRef Field : - {"name", "reason", "thread", "threads", "thread-pcs"}) { - // This will insert an empty field if there is none. In the future, we - // should probably differentiate between these fields not being present and - // them being empty, but right now no tests depends on this. - if (Elements.insert({Field, {""}}).first->second.size() != 1) - return make_parsing_error( - "StopReply: got multiple responses for the {0} field", Field); - } - StringRef Name = Elements["name"][0]; - StringRef Reason = Elements["reason"][0]; - - lldb::tid_t Thread; - if (!to_integer(Elements["thread"][0], Thread, 16)) - return make_parsing_error("StopReply: thread"); - - SmallVector Threads; - SmallVector Pcs; - Elements["threads"][0].split(Threads, ','); - Elements["thread-pcs"][0].split(Pcs, ','); - if (Threads.size() != Pcs.size()) - return make_parsing_error("StopReply: thread/PC count mismatch"); - - RegisterMap ThreadPcs; - const RegisterInfo *PcInfo = find_if(RegInfos, [](const RegisterInfo &Info) { - return Info.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC; - }); - assert(PcInfo); - - for (auto ThreadPc : zip(Threads, Pcs)) { - lldb::tid_t Id; - if (!to_integer(std::get<0>(ThreadPc), Id, 16)) - return make_parsing_error("StopReply: Thread id '{0}'", - std::get<0>(ThreadPc)); - - auto PcOr = parseRegisterValue(*PcInfo, std::get<1>(ThreadPc), Endian, - /*ZeroPad*/ true); - if (!PcOr) - return PcOr.takeError(); - ThreadPcs[Id] = std::move(*PcOr); - } - - auto RegistersOr = parseRegisters(Elements, Endian, RegInfos); - if (!RegistersOr) - return RegistersOr.takeError(); - - return std::make_unique(Signal, Thread, Name, - std::move(ThreadPcs), - std::move(*RegistersOr), Reason); -} - -Expected> -StopReplyExit::create(StringRef Response) { - uint8_t Status; - if (!to_integer(Response, Status, 16)) - return make_parsing_error("StopReply: exit status"); - return std::make_unique(Status); -} - -//====== Globals =============================================================== -Expected> SplitUniquePairList(StringRef caller, - StringRef str) { - SmallVector elements; - str.split(elements, ';'); - - StringMap pairs; - for (StringRef s : elements) { - std::pair pair = s.split(':'); - if (pairs.count(pair.first)) - return make_parsing_error("{0}: Duplicate Key: {1}", caller, pair.first); - - pairs.insert(pair); - } - - return pairs; -} - -StringMap> SplitPairList(StringRef str) { - SmallVector elements; - str.split(elements, ';'); - - StringMap> pairs; - for (StringRef s : elements) { - std::pair pair = s.split(':'); - pairs[pair.first].push_back(pair.second); - } - - return pairs; -} -} // namespace llgs_tests - -std::ostream &lldb_private::operator<<(std::ostream &OS, - const RegisterValue &RegVal) { - ArrayRef Bytes(static_cast(RegVal.GetBytes()), - RegVal.GetByteSize()); - return OS << formatv("RegisterValue[{0}]: {1:@[x-2]}", RegVal.GetByteSize(), - make_range(Bytes.begin(), Bytes.end())) - .str(); -} diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h deleted file mode 100644 index ff3f76ae3f0..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h +++ /dev/null @@ -1,186 +0,0 @@ -//===-- MessageObjects.h ----------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H -#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H - -#include "lldb/Host/Host.h" -#include "lldb/Utility/RegisterValue.h" -#include "lldb/Utility/StructuredData.h" -#include "lldb/lldb-types.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/FormatVariadic.h" -#include - -namespace llgs_tests { -class ThreadInfo; -typedef llvm::DenseMap ThreadInfoMap; -typedef llvm::DenseMap RegisterMap; - -template struct Parser { using result_type = T; }; - -class ProcessInfo : public Parser { -public: - static llvm::Expected create(llvm::StringRef response); - lldb::pid_t GetPid() const; - llvm::support::endianness GetEndian() const; - -private: - ProcessInfo() = default; - lldb::pid_t m_pid; - lldb::pid_t m_parent_pid; - uint32_t m_real_uid; - uint32_t m_real_gid; - uint32_t m_effective_uid; - uint32_t m_effective_gid; - std::string m_triple; - llvm::SmallString<16> m_ostype; - llvm::support::endianness m_endian; - unsigned int m_ptrsize; -}; - -class ThreadInfo { -public: - ThreadInfo() = default; - ThreadInfo(llvm::StringRef name, llvm::StringRef reason, - RegisterMap registers, unsigned int signal); - - const lldb_private::RegisterValue *ReadRegister(unsigned int Id) const; - -private: - std::string m_name; - std::string m_reason; - RegisterMap m_registers; -}; - -class JThreadsInfo : public Parser { -public: - static llvm::Expected - create(llvm::StringRef Response, - llvm::ArrayRef RegInfos); - - const ThreadInfoMap &GetThreadInfos() const; - -private: - static llvm::Expected - parseRegisters(const lldb_private::StructuredData::Dictionary &Dict, - llvm::ArrayRef RegInfos); - - JThreadsInfo() = default; - ThreadInfoMap m_thread_infos; -}; - -struct RegisterInfoParser : public Parser { - static llvm::Expected - create(llvm::StringRef Response); -}; - -llvm::Expected -parseRegisterValue(const lldb_private::RegisterInfo &Info, - llvm::StringRef HexValue, llvm::support::endianness Endian, - bool ZeroPad = false); - -class StopReply : public Parser> { -public: - StopReply() = default; - virtual ~StopReply() = default; - - static llvm::Expected> - create(llvm::StringRef Response, llvm::support::endianness Endian, - llvm::ArrayRef RegInfos); - - // for llvm::cast<> - virtual lldb_private::WaitStatus getKind() const = 0; - - StopReply(const StopReply &) = delete; - void operator=(const StopReply &) = delete; -}; - -class StopReplyStop : public StopReply { -public: - StopReplyStop(uint8_t Signal, lldb::tid_t ThreadId, llvm::StringRef Name, - RegisterMap ThreadPcs, RegisterMap Registers, - llvm::StringRef Reason) - : Signal(Signal), ThreadId(ThreadId), Name(Name), - ThreadPcs(std::move(ThreadPcs)), Registers(std::move(Registers)), - Reason(Reason) {} - - static llvm::Expected> - create(llvm::StringRef Response, llvm::support::endianness Endian, - llvm::ArrayRef RegInfos); - - const RegisterMap &getThreadPcs() const { return ThreadPcs; } - lldb::tid_t getThreadId() const { return ThreadId; } - - // for llvm::cast<> - lldb_private::WaitStatus getKind() const override { - return lldb_private::WaitStatus{lldb_private::WaitStatus::Stop, Signal}; - } - static bool classof(const StopReply *R) { - return R->getKind().type == lldb_private::WaitStatus::Stop; - } - -private: - static llvm::Expected parseRegisters( - const llvm::StringMap> &Elements, - llvm::support::endianness Endian, - llvm::ArrayRef RegInfos); - - uint8_t Signal; - lldb::tid_t ThreadId; - std::string Name; - RegisterMap ThreadPcs; - RegisterMap Registers; - std::string Reason; -}; - -class StopReplyExit : public StopReply { -public: - explicit StopReplyExit(uint8_t Status) : Status(Status) {} - - static llvm::Expected> - create(llvm::StringRef response); - - // for llvm::cast<> - lldb_private::WaitStatus getKind() const override { - return lldb_private::WaitStatus{lldb_private::WaitStatus::Exit, Status}; - } - static bool classof(const StopReply *R) { - return R->getKind().type == lldb_private::WaitStatus::Exit; - } - -private: - uint8_t Status; -}; - -// Common functions for parsing packet data. -llvm::Expected> -SplitUniquePairList(llvm::StringRef caller, llvm::StringRef s); - -llvm::StringMap> -SplitPairList(llvm::StringRef s); - -template -llvm::Error make_parsing_error(llvm::StringRef format, Args &&... args) { - std::string error = - "Unable to parse " + - llvm::formatv(format.data(), std::forward(args)...).str(); - return llvm::make_error(error, - llvm::inconvertibleErrorCode()); -} - -} // namespace llgs_tests - -namespace lldb_private { -std::ostream &operator<<(std::ostream &OS, const RegisterValue &RegVal); -} - -#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp deleted file mode 100644 index eeb73f05575..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp +++ /dev/null @@ -1,35 +0,0 @@ -//===-- TestBase.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 "TestBase.h" -#include - -using namespace llgs_tests; -using namespace llvm; - -std::string TestBase::getLogFileName() { - const auto *test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - assert(test_info); - - const char *Dir = getenv("LOG_FILE_DIRECTORY"); - if (!Dir) - return ""; - - if (!llvm::sys::fs::is_directory(Dir)) { - GTEST_LOG_(WARNING) << "Cannot access log directory: " << Dir; - return ""; - } - - SmallString<64> DirStr(Dir); - sys::path::append(DirStr, std::string("server-") + - test_info->test_case_name() + "-" + - test_info->name() + ".log"); - return std::string(DirStr.str()); -} - diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h deleted file mode 100644 index 6b0a9cdfd7c..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h +++ /dev/null @@ -1,59 +0,0 @@ -//===-- TestBase.h ----------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H -#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H - -#include "TestClient.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Host/Socket.h" -#include "llvm/Support/Path.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -namespace llgs_tests { - -class TestBase: public ::testing::Test { -public: - static void SetUpTestCase() { - lldb_private::FileSystem::Initialize(); - lldb_private::HostInfo::Initialize(); - ASSERT_THAT_ERROR(lldb_private::Socket::Initialize(), llvm::Succeeded()); - } - - static void TearDownTestCase() { - lldb_private::Socket::Terminate(); - lldb_private::HostInfo::Terminate(); - lldb_private::FileSystem::Terminate(); - } - - static std::string getInferiorPath(llvm::StringRef Name) { - llvm::SmallString<64> Path(LLDB_TEST_INFERIOR_PATH); - llvm::sys::path::append(Path, Name + LLDB_TEST_INFERIOR_SUFFIX); - return std::string(Path.str()); - } - - static std::string getLogFileName(); -}; - -class StandardStartupTest: public TestBase { -public: - void SetUp() override { - auto ClientOr = TestClient::launch(getLogFileName()); - ASSERT_THAT_EXPECTED(ClientOr, llvm::Succeeded()); - Client = std::move(*ClientOr); - } - -protected: - std::unique_ptr Client; -}; - -} // namespace llgs_tests - -#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp deleted file mode 100644 index 0bb60f26219..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp +++ /dev/null @@ -1,276 +0,0 @@ -//===-- TestClient.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 "TestClient.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Host/common/TCPSocket.h" -#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" -#include "lldb/Utility/Args.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Path.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" -#include -#include -#include -#include - -using namespace lldb; -using namespace lldb_private; -using namespace llvm; -using namespace llgs_tests; - -#ifdef SendMessage -#undef SendMessage -#endif - -TestClient::TestClient(std::unique_ptr Conn) { - SetConnection(std::move(Conn)); - SetPacketTimeout(std::chrono::seconds(10)); -} - -TestClient::~TestClient() { - if (!IsConnected()) - return; - - EXPECT_THAT_ERROR(SendMessage("k"), Succeeded()); -} - -Error TestClient::initializeConnection() { - if (SendAck() == 0) - return make_error("Sending initial ACK failed.", - inconvertibleErrorCode()); - - if (Error E = SendMessage("QStartNoAckMode")) - return E; - - m_send_acks = false; - return Error::success(); -} - -Expected> TestClient::launch(StringRef Log) { - return launch(Log, {}); -} - -Expected> TestClient::launch(StringRef Log, ArrayRef InferiorArgs) { - return launchCustom(Log, {}, InferiorArgs); -} - -Expected> TestClient::launchCustom(StringRef Log, ArrayRef ServerArgs, ArrayRef InferiorArgs) { - const ArchSpec &arch_spec = HostInfo::GetArchitecture(); - Args args; - args.AppendArgument(LLDB_SERVER); - if (IsLldbServer()) - args.AppendArgument("gdbserver"); - args.AppendArgument("--reverse-connect"); - - if (!Log.empty()) { - args.AppendArgument(("--log-file=" + Log).str()); - if (IsLldbServer()) - args.AppendArgument("--log-channels=gdb-remote packets"); - else - args.AppendArgument("--log-flags=0x800000"); - } - - Status status; - TCPSocket listen_socket(true, false); - status = listen_socket.Listen("127.0.0.1:0", 5); - if (status.Fail()) - return status.ToError(); - - args.AppendArgument( - ("127.0.0.1:" + Twine(listen_socket.GetLocalPortNumber())).str()); - - for (StringRef arg : ServerArgs) - args.AppendArgument(arg); - - if (!InferiorArgs.empty()) { - args.AppendArgument("--"); - for (StringRef arg : InferiorArgs) - args.AppendArgument(arg); - } - - ProcessLaunchInfo Info; - Info.SetArchitecture(arch_spec); - Info.SetArguments(args, true); - Info.GetEnvironment() = Host::GetEnvironment(); - // TODO: Use this callback to detect botched launches. If lldb-server does not - // start, we can print a nice error message here instead of hanging in - // Accept(). - Info.SetMonitorProcessCallback(&ProcessLaunchInfo::NoOpMonitorCallback, - false); - - status = Host::LaunchProcess(Info); - if (status.Fail()) - return status.ToError(); - - Socket *accept_socket; - listen_socket.Accept(accept_socket); - auto Conn = std::make_unique(accept_socket); - auto Client = std::unique_ptr(new TestClient(std::move(Conn))); - - if (Error E = Client->initializeConnection()) - return std::move(E); - - if (!InferiorArgs.empty()) { - if (Error E = Client->queryProcess()) - return std::move(E); - } - - return std::move(Client); -} - -Error TestClient::SetInferior(llvm::ArrayRef inferior_args) { - if (SendEnvironment(Host::GetEnvironment()) != 0) { - return make_error("Failed to set launch environment", - inconvertibleErrorCode()); - } - std::stringstream command; - command << "A"; - for (size_t i = 0; i < inferior_args.size(); i++) { - if (i > 0) - command << ','; - std::string hex_encoded = toHex(inferior_args[i]); - command << hex_encoded.size() << ',' << i << ',' << hex_encoded; - } - - if (Error E = SendMessage(command.str())) - return E; - if (Error E = SendMessage("qLaunchSuccess")) - return E; - if (Error E = queryProcess()) - return E; - return Error::success(); -} - -Error TestClient::ListThreadsInStopReply() { - return SendMessage("QListThreadsInStopReply"); -} - -Error TestClient::SetBreakpoint(unsigned long address) { - return SendMessage(formatv("Z0,{0:x-},1", address).str()); -} - -Error TestClient::ContinueAll() { return Continue("vCont;c"); } - -Error TestClient::ContinueThread(unsigned long thread_id) { - return Continue(formatv("vCont;c:{0:x-}", thread_id).str()); -} - -const llgs_tests::ProcessInfo &TestClient::GetProcessInfo() { - return *m_process_info; -} - -Expected TestClient::GetJThreadsInfo() { - return SendMessage("jThreadsInfo", m_register_infos); -} - -const StopReply &TestClient::GetLatestStopReply() { - assert(m_stop_reply); - return *m_stop_reply; -} - -Error TestClient::SendMessage(StringRef message) { - std::string dummy_string; - return SendMessage(message, dummy_string); -} - -Error TestClient::SendMessage(StringRef message, std::string &response_string) { - if (Error E = SendMessage(message, response_string, PacketResult::Success)) - return E; - StringExtractorGDBRemote Extractor(response_string); - if (Extractor.IsErrorResponse()) - return Extractor.GetStatus().ToError(); - return Error::success(); -} - -Error TestClient::SendMessage(StringRef message, std::string &response_string, - PacketResult expected_result) { - StringExtractorGDBRemote response; - GTEST_LOG_(INFO) << "Send Packet: " << message.str(); - PacketResult result = SendPacketAndWaitForResponse(message, response); - response.GetEscapedBinaryData(response_string); - GTEST_LOG_(INFO) << "Read Packet: " << response_string; - if (result != expected_result) - return make_error( - formatv("Error sending message `{0}`: {1}", message, result).str(), - inconvertibleErrorCode()); - - return Error::success(); -} - -unsigned int TestClient::GetPcRegisterId() { - assert(m_pc_register != LLDB_INVALID_REGNUM); - return m_pc_register; -} - -Error TestClient::qProcessInfo() { - m_process_info = None; - auto InfoOr = SendMessage("qProcessInfo"); - if (!InfoOr) - return InfoOr.takeError(); - m_process_info = std::move(*InfoOr); - return Error::success(); -} - -Error TestClient::qRegisterInfos() { - uint32_t reg_offset = 0; - for (unsigned int Reg = 0;; ++Reg) { - std::string Message = formatv("qRegisterInfo{0:x-}", Reg).str(); - Expected InfoOr = SendMessage(Message); - if (!InfoOr) { - consumeError(InfoOr.takeError()); - break; - } - m_register_infos.emplace_back(std::move(*InfoOr)); - - if (m_register_infos[Reg].byte_offset == LLDB_INVALID_INDEX32) - m_register_infos[Reg].byte_offset = reg_offset; - - reg_offset = - m_register_infos[Reg].byte_offset + m_register_infos[Reg].byte_size; - if (m_register_infos[Reg].kinds[eRegisterKindGeneric] == - LLDB_REGNUM_GENERIC_PC) - m_pc_register = Reg; - } - if (m_pc_register == LLDB_INVALID_REGNUM) - return make_parsing_error("qRegisterInfo: generic"); - return Error::success(); -} - -Error TestClient::queryProcess() { - if (Error E = qProcessInfo()) - return E; - if (Error E = qRegisterInfos()) - return E; - return Error::success(); -} - -Error TestClient::Continue(StringRef message) { - assert(m_process_info.hasValue()); - - auto StopReplyOr = SendMessage( - message, m_process_info->GetEndian(), m_register_infos); - if (!StopReplyOr) - return StopReplyOr.takeError(); - - m_stop_reply = std::move(*StopReplyOr); - if (!isa(m_stop_reply)) { - StringExtractorGDBRemote R; - PacketResult result = ReadPacket(R, GetPacketTimeout(), false); - if (result != PacketResult::ErrorDisconnected) { - return make_error( - formatv("Expected connection close after sending {0}. Got {1}/{2} " - "instead.", - message, result, R.GetStringRef()) - .str(), - inconvertibleErrorCode()); - } - } - return Error::success(); -} diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h deleted file mode 100644 index 32a21a4411c..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h +++ /dev/null @@ -1,112 +0,0 @@ -//===-- TestClient.h --------------------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H -#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H - -#include "MessageObjects.h" -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" -#include "lldb/Host/ProcessLaunchInfo.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Connection.h" -#include "llvm/ADT/Optional.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/FormatVariadic.h" -#include -#include - -#if LLDB_SERVER_IS_DEBUGSERVER -#define LLGS_TEST(x) DISABLED_ ## x -#define DS_TEST(x) x -#else -#define LLGS_TEST(x) x -#define DS_TEST(x) DISABLED_ ## x -#endif - -namespace llgs_tests { -class TestClient - : public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { -public: - static bool IsDebugServer() { return LLDB_SERVER_IS_DEBUGSERVER; } - static bool IsLldbServer() { return !IsDebugServer(); } - - /// Launches the server, connects it to the client and returns the client. If - /// Log is non-empty, the server will write it's log to this file. - static llvm::Expected> launch(llvm::StringRef Log); - - /// Launches the server, while specifying the inferior on its command line. - /// When the client connects, it already has a process ready. - static llvm::Expected> - launch(llvm::StringRef Log, llvm::ArrayRef InferiorArgs); - - /// Allows user to pass additional arguments to the server. Be careful when - /// using this for generic tests, as the two stubs have different - /// command-line interfaces. - static llvm::Expected> - launchCustom(llvm::StringRef Log, llvm::ArrayRef ServerArgs, llvm::ArrayRef InferiorArgs); - - - ~TestClient() override; - llvm::Error SetInferior(llvm::ArrayRef inferior_args); - llvm::Error ListThreadsInStopReply(); - llvm::Error SetBreakpoint(unsigned long address); - llvm::Error ContinueAll(); - llvm::Error ContinueThread(unsigned long thread_id); - const ProcessInfo &GetProcessInfo(); - llvm::Expected GetJThreadsInfo(); - const StopReply &GetLatestStopReply(); - template llvm::Expected GetLatestStopReplyAs() { - assert(m_stop_reply); - if (const auto *Reply = llvm::dyn_cast(m_stop_reply.get())) - return *Reply; - return llvm::make_error( - llvm::formatv("Unexpected Stop Reply {0}", m_stop_reply->getKind()), - llvm::inconvertibleErrorCode()); - } - llvm::Error SendMessage(llvm::StringRef message); - llvm::Error SendMessage(llvm::StringRef message, - std::string &response_string); - llvm::Error SendMessage(llvm::StringRef message, std::string &response_string, - PacketResult expected_result); - - template - llvm::Expected SendMessage(llvm::StringRef Message, - CreateArgs &&... Args); - unsigned int GetPcRegisterId(); - -private: - TestClient(std::unique_ptr Conn); - - llvm::Error initializeConnection(); - llvm::Error qProcessInfo(); - llvm::Error qRegisterInfos(); - llvm::Error queryProcess(); - llvm::Error Continue(llvm::StringRef message); - std::string FormatFailedResult( - const std::string &message, - lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult - result); - - llvm::Optional m_process_info; - std::unique_ptr m_stop_reply; - std::vector m_register_infos; - unsigned int m_pc_register = LLDB_INVALID_REGNUM; -}; - -template -llvm::Expected -TestClient::SendMessage(llvm::StringRef Message, CreateArgs &&... Args) { - std::string ResponseText; - if (llvm::Error E = SendMessage(Message, ResponseText)) - return std::move(E); - return P::create(ResponseText, std::forward(Args)...); -} - -} // namespace llgs_tests - -#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp deleted file mode 100644 index 2306b434a6d..00000000000 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===-- ThreadsInJstopinfoTest.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 "TestBase.h" -#include "TestClient.h" -#include "lldb/Utility/DataExtractor.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/Path.h" -#include "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include - -using namespace llgs_tests; -using namespace lldb_private; -using namespace llvm; -using namespace lldb; -using namespace testing; - -#ifdef __NetBSD__ -#define SKIP_ON_NETBSD(x) DISABLED_ ## x -#else -#define SKIP_ON_NETBSD(x) x -#endif - -TEST_F(StandardStartupTest, SKIP_ON_NETBSD(TestStopReplyContainsThreadPcs)) { - // This inferior spawns 4 threads, then forces a break. - ASSERT_THAT_ERROR( - Client->SetInferior({getInferiorPath("thread_inferior"), "4"}), - Succeeded()); - - ASSERT_THAT_ERROR(Client->ListThreadsInStopReply(), Succeeded()); - ASSERT_THAT_ERROR(Client->ContinueAll(), Succeeded()); - unsigned int pc_reg = Client->GetPcRegisterId(); - ASSERT_NE(pc_reg, UINT_MAX); - - auto jthreads_info = Client->GetJThreadsInfo(); - ASSERT_THAT_EXPECTED(jthreads_info, Succeeded()); - - auto stop_reply = Client->GetLatestStopReplyAs(); - ASSERT_THAT_EXPECTED(stop_reply, Succeeded()); - auto stop_reply_pcs = stop_reply->getThreadPcs(); - auto thread_infos = jthreads_info->GetThreadInfos(); - ASSERT_EQ(stop_reply_pcs.size(), thread_infos.size()) - << "Thread count mismatch."; - - for (auto stop_reply_pc : stop_reply_pcs) { - unsigned long tid = stop_reply_pc.first; - ASSERT_TRUE(thread_infos.find(tid) != thread_infos.end()) - << "Thread ID: " << tid << " not in JThreadsInfo."; - EXPECT_THAT(thread_infos[tid].ReadRegister(pc_reg), - Pointee(Eq(stop_reply_pc.second))); - } -}