brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · a6e1e16 Raw
170 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H10#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H11 12#include <map>13#include <mutex>14#include <vector>15 16#include "lldb/Expression/UtilityFunction.h"17#include "lldb/lldb-public.h"18 19namespace lldb_private {20 21class AppleObjCTrampolineHandler {22public: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  bool AddrIsMsgForward(lldb::addr_t addr) const {34    return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr);35  }36 37  struct DispatchFunction {38  public:39    enum FixUpState { eFixUpNone, eFixUpFixed, eFixUpToFix };40 41    const char *name = nullptr;42    bool stret_return = false;43    bool is_super = false;44    bool is_super2 = false;45    FixUpState fixedup = eFixUpNone;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 54private:55  /// These hold the code for the function that finds the implementation of56  /// an ObjC message send given the class & selector and the kind of dispatch.57  /// There are two variants depending on whether the platform uses a separate58  /// _stret passing convention (e.g. Intel) or not (e.g. ARM).  The difference59  /// is only at the very end of the function, so the code is broken into the60  /// common prefix and the suffix, which get composed appropriately before61  /// the function gets compiled.62  /// \{63  static const char *g_lookup_implementation_function_name;64  static const char *g_lookup_implementation_function_common_code;65  static const char *g_lookup_implementation_with_stret_function_code;66  static const char *g_lookup_implementation_no_stret_function_code;67  /// \}68 69  class AppleObjCVTables {70  public:71    // These come from objc-gdb.h.72    enum VTableFlags {73      eOBJC_TRAMPOLINE_MESSAGE = (1 << 0), // trampoline acts like objc_msgSend74      eOBJC_TRAMPOLINE_STRET = (1 << 1),   // trampoline is struct-returning75      eOBJC_TRAMPOLINE_VTABLE = (1 << 2)   // trampoline is vtable dispatcher76    };77 78  private:79    struct VTableDescriptor {80      VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start)81          : flags(in_flags), code_start(in_code_start) {}82 83      uint32_t flags;84      lldb::addr_t code_start;85    };86 87    class VTableRegion {88    public:89      VTableRegion() = default;90 91      VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);92 93      void SetUpRegion();94 95      lldb::addr_t GetNextRegionAddr() { return m_next_region; }96 97      lldb::addr_t GetCodeStart() { return m_code_start_addr; }98 99      lldb::addr_t GetCodeEnd() { return m_code_end_addr; }100 101      uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address) { return 0; }102 103      bool IsValid() { return m_valid; }104 105      bool AddressInRegion(lldb::addr_t addr, uint32_t &flags);106 107      void Dump(Stream &s);108 109      bool m_valid = false;110      AppleObjCVTables *m_owner = nullptr;111      lldb::addr_t m_header_addr = LLDB_INVALID_ADDRESS;112      lldb::addr_t m_code_start_addr = 0;113      lldb::addr_t m_code_end_addr = 0;114      std::vector<VTableDescriptor> m_descriptors;115      lldb::addr_t m_next_region = 0;116    };117 118  public:119    AppleObjCVTables(const lldb::ProcessSP &process_sp,120                     const lldb::ModuleSP &objc_module_sp);121 122    ~AppleObjCVTables();123 124    bool InitializeVTableSymbols();125 126    static bool RefreshTrampolines(void *baton,127                                   StoppointCallbackContext *context,128                                   lldb::user_id_t break_id,129                                   lldb::user_id_t break_loc_id);130    bool ReadRegions();131 132    bool ReadRegions(lldb::addr_t region_addr);133 134    bool IsAddressInVTables(lldb::addr_t addr, uint32_t &flags);135 136    lldb::ProcessSP GetProcessSP() { return m_process_wp.lock(); }137 138  private:139    lldb::ProcessWP m_process_wp;140    typedef std::vector<VTableRegion> region_collection;141    lldb::addr_t m_trampoline_header;142    lldb::break_id_t m_trampolines_changed_bp_id;143    region_collection m_regions;144    lldb::ModuleSP m_objc_module_sp;145  };146 147  static const DispatchFunction g_dispatch_functions[];148  static const char *g_opt_dispatch_names[];149 150  using MsgsendMap = std::map<lldb::addr_t, int>; // This table maps an dispatch151                                                  // fn address to the index in152                                                  // g_dispatch_functions153  MsgsendMap m_msgSend_map;154  MsgsendMap m_opt_dispatch_map;155  lldb::ProcessWP m_process_wp;156  lldb::ModuleSP m_objc_module_sp;157  std::string m_lookup_implementation_function_code;158  std::unique_ptr<UtilityFunction> m_impl_code;159  std::mutex m_impl_function_mutex;160  lldb::addr_t m_impl_fn_addr;161  lldb::addr_t m_impl_stret_fn_addr;162  lldb::addr_t m_msg_forward_addr;163  lldb::addr_t m_msg_forward_stret_addr;164  std::unique_ptr<AppleObjCVTables> m_vtables_up;165};166 167} // namespace lldb_private168 169#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H170