Coverage Report

Created: 2022-01-22 13:19

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
Line
Count
Source (jump to first uncovered line)
1
//===-- AppleObjCTrampolineHandler.h ----------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
10
#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
11
12
#include <map>
13
#include <mutex>
14
#include <vector>
15
16
#include "lldb/Expression/UtilityFunction.h"
17
#include "lldb/lldb-public.h"
18
19
namespace lldb_private {
20
21
class AppleObjCTrampolineHandler {
22
public:
23
  AppleObjCTrampolineHandler(const lldb::ProcessSP &process_sp,
24
                             const lldb::ModuleSP &objc_module_sp);
25
26
  ~AppleObjCTrampolineHandler();
27
28
  lldb::ThreadPlanSP GetStepThroughDispatchPlan(Thread &thread,
29
                                                bool stop_others);
30
31
  FunctionCaller *GetLookupImplementationFunctionCaller();
32
33
34
  bool AddrIsMsgForward(lldb::addr_t addr) const {
34
34
    return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr);
35
34
  }
36
37
  struct DispatchFunction {
38
  public:
39
    enum FixUpState { eFixUpNone, eFixUpFixed, eFixUpToFix };
40
41
    const char *name;
42
    bool stret_return;
43
    bool is_super;
44
    bool is_super2;
45
    FixUpState fixedup;
46
  };
47
48
  lldb::addr_t SetupDispatchFunction(Thread &thread,
49
                                     ValueList &dispatch_values);
50
  const DispatchFunction *FindDispatchFunction(lldb::addr_t addr);
51
  void ForEachDispatchFunction(std::function<void(lldb::addr_t, 
52
                                                  const DispatchFunction &)>);
53
54
private:
55
  static const char *g_lookup_implementation_function_name;
56
  static const char *g_lookup_implementation_with_stret_function_code;
57
  static const char *g_lookup_implementation_no_stret_function_code;
58
59
  class AppleObjCVTables {
60
  public:
61
    // These come from objc-gdb.h.
62
    enum VTableFlags {
63
      eOBJC_TRAMPOLINE_MESSAGE = (1 << 0), // trampoline acts like objc_msgSend
64
      eOBJC_TRAMPOLINE_STRET = (1 << 1),   // trampoline is struct-returning
65
      eOBJC_TRAMPOLINE_VTABLE = (1 << 2)   // trampoline is vtable dispatcher
66
    };
67
68
  private:
69
    struct VTableDescriptor {
70
      VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start)
71
0
          : flags(in_flags), code_start(in_code_start) {}
72
73
      uint32_t flags;
74
      lldb::addr_t code_start;
75
    };
76
77
    class VTableRegion {
78
    public:
79
      VTableRegion() = default;
80
81
      VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
82
83
      void SetUpRegion();
84
85
0
      lldb::addr_t GetNextRegionAddr() { return m_next_region; }
86
87
0
      lldb::addr_t GetCodeStart() { return m_code_start_addr; }
88
89
0
      lldb::addr_t GetCodeEnd() { return m_code_end_addr; }
90
91
0
      uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address) { return 0; }
92
93
0
      bool IsValid() { return m_valid; }
94
95
      bool AddressInRegion(lldb::addr_t addr, uint32_t &flags);
96
97
      void Dump(Stream &s);
98
99
      bool m_valid = false;
100
      AppleObjCVTables *m_owner = nullptr;
101
      lldb::addr_t m_header_addr = LLDB_INVALID_ADDRESS;
102
      lldb::addr_t m_code_start_addr = 0;
103
      lldb::addr_t m_code_end_addr = 0;
104
      std::vector<VTableDescriptor> m_descriptors;
105
      lldb::addr_t m_next_region = 0;
106
    };
107
108
  public:
109
    AppleObjCVTables(const lldb::ProcessSP &process_sp,
110
                     const lldb::ModuleSP &objc_module_sp);
111
112
    ~AppleObjCVTables();
113
114
    bool InitializeVTableSymbols();
115
116
    static bool RefreshTrampolines(void *baton,
117
                                   StoppointCallbackContext *context,
118
                                   lldb::user_id_t break_id,
119
                                   lldb::user_id_t break_loc_id);
120
    bool ReadRegions();
121
122
    bool ReadRegions(lldb::addr_t region_addr);
123
124
    bool IsAddressInVTables(lldb::addr_t addr, uint32_t &flags);
125
126
5.15k
    lldb::ProcessSP GetProcessSP() { return m_process_wp.lock(); }
127
128
  private:
129
    lldb::ProcessWP m_process_wp;
130
    typedef std::vector<VTableRegion> region_collection;
131
    lldb::addr_t m_trampoline_header;
132
    lldb::break_id_t m_trampolines_changed_bp_id;
133
    region_collection m_regions;
134
    lldb::ModuleSP m_objc_module_sp;
135
  };
136
137
  static const DispatchFunction g_dispatch_functions[];
138
  static const char *g_opt_dispatch_names[];
139
140
  using MsgsendMap = std::map<lldb::addr_t, int>; // This table maps an dispatch
141
                                                  // fn address to the index in
142
                                                  // g_dispatch_functions
143
  MsgsendMap m_msgSend_map;
144
  MsgsendMap m_opt_dispatch_map;
145
  lldb::ProcessWP m_process_wp;
146
  lldb::ModuleSP m_objc_module_sp;
147
  const char *m_lookup_implementation_function_code;
148
  std::unique_ptr<UtilityFunction> m_impl_code;
149
  std::mutex m_impl_function_mutex;
150
  lldb::addr_t m_impl_fn_addr;
151
  lldb::addr_t m_impl_stret_fn_addr;
152
  lldb::addr_t m_msg_forward_addr;
153
  lldb::addr_t m_msg_forward_stret_addr;
154
  std::unique_ptr<AppleObjCVTables> m_vtables_up;
155
};
156
157
} // namespace lldb_private
158
159
#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H