File: LLDBMemoryReader.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (127 lines) | stat: -rw-r--r-- 5,306 bytes parent folder | download
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//===-- LLDBMemoryReader.h --------------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_LLDBMemoryReader_h_
#define liblldb_LLDBMemoryReader_h_

#include "SwiftLanguageRuntime.h"

// We need to include ReflectionContext.h before TypeLowering.h to avoid
// conflicts between mach/machine.h and llvm/BinaryFormat/MachO.h.
#include "swift/RemoteInspection/ReflectionContext.h"
#include "swift/RemoteInspection/TypeLowering.h"

#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/Memory.h"

namespace lldb_private {
class LLDBMemoryReader : public swift::remote::MemoryReader {
public:
  LLDBMemoryReader(Process &p,
                   std::function<swift::remote::RemoteAbsolutePointer(
                       swift::remote::RemoteAbsolutePointer)>
                       stripper,
                   size_t max_read_amount = INT32_MAX)
      : m_process(p), signedPointerStripper(stripper), m_range_module_map() {
    m_max_read_amount = max_read_amount;
  }

  virtual ~LLDBMemoryReader() = default;

  bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
                       void *outBuffer) override;

  swift::remote::RemoteAddress
  getSymbolAddress(const std::string &name) override;

  std::optional<swift::remote::RemoteAbsolutePointer>
  resolvePointerAsSymbol(swift::remote::RemoteAddress address) override;

  swift::remote::RemoteAbsolutePointer
  resolvePointer(swift::remote::RemoteAddress address,
                 uint64_t readValue) override;

  bool readBytes(swift::remote::RemoteAddress address, uint8_t *dest,
                 uint64_t size) override;

  bool readString(swift::remote::RemoteAddress address,
                  std::string &dest) override;

  void pushLocalBuffer(uint64_t local_buffer, uint64_t local_buffer_size);

  void popLocalBuffer();

  /// Adds the module to the list of modules we're tracking using tagged
  /// addresses, so we can read memory from the file cache whenever possible.
  /// \return a pair of addresses indicating the start and end of this image in
  /// the tagged address space. None on failure.
  std::optional<std::pair<uint64_t, uint64_t>>
  addModuleToAddressMap(lldb::ModuleSP module, bool register_symbol_obj_file);

  /// Returns whether the filecache optimization is enabled or not.
  bool readMetadataFromFileCacheEnabled() const;

private:
  /// Gets the file address and module that were mapped to a given tagged
  /// address.
  std::optional<std::pair<uint64_t, lldb::ModuleSP>>
  getFileAddressAndModuleForTaggedAddress(uint64_t tagged_address) const;

  /// Resolves the address by either mapping a tagged address back to an LLDB
  /// Address with section + offset, or, in case the address is not tagged,
  /// constructing an LLDB address with just the offset.
  /// \return an Address with Section + offset  if we succesfully converted a
  /// tagged address back, an Address with just an offset if the address was not
  /// tagged, and None if the address was tagged but we couldn't convert it back
  /// to an Address.
  std::optional<Address> resolveRemoteAddress(uint64_t address) const;

  /// Reads memory from the symbol rich binary from the address into dest.
  /// \return true if it was able to successfully read memory.
  std::optional<Address>
  resolveRemoteAddressFromSymbolObjectFile(uint64_t address) const;

private:
  Process &m_process;
  size_t m_max_read_amount;

  std::optional<uint64_t> m_local_buffer;
  uint64_t m_local_buffer_size = 0;

  std::function<swift::remote::RemoteAbsolutePointer(
      swift::remote::RemoteAbsolutePointer)>
      signedPointerStripper;

  /// LLDBMemoryReader prefers to read reflection metadata from the
  /// binary on disk, which is faster than reading it out of process
  /// memory, especially when debugging remotely.  To achieve this LLDB
  /// registers virtual addresses starting at (0x0 &
  /// LLDB_VIRTUAL_ADDRESS_BIT) with ReflectionContext.  Sorted by
  /// virtual address, m_lldb_virtual_address_map stores each
  /// lldb::Module and the first virtual address after the end of that
  /// module's virtual address space.
  std::vector<std::pair<uint64_t, lldb::ModuleSP>> m_range_module_map;

  /// The set of modules where we should read memory from the symbol file's
  /// object file instead of the main object file.
  llvm::SmallSet<lldb::ModuleSP, 8> m_modules_with_metadata_in_symbol_obj_file;

  /// The bit used to tag LLDB's virtual addresses as such. See \c
  /// m_range_module_map.
  const static uint64_t LLDB_FILE_ADDRESS_BIT = 0x2000000000000000;
  static_assert(LLDB_FILE_ADDRESS_BIT & SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK,
                "LLDB file address bit not in spare bits mask!");
  static_assert(LLDB_FILE_ADDRESS_BIT & SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK,
                "LLDB file address bit not in spare bits mask!");
};
} // namespace lldb_private
#endif