1061da546Spatrick //===-- DynamicLoaderPOSIXDYLD.h --------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H 11061da546Spatrick 12061da546Spatrick #include <map> 13061da546Spatrick #include <memory> 14061da546Spatrick 15061da546Spatrick #include "DYLDRendezvous.h" 16061da546Spatrick #include "Plugins/Process/Utility/AuxVector.h" 17061da546Spatrick #include "lldb/Breakpoint/StoppointCallbackContext.h" 18061da546Spatrick #include "lldb/Core/ModuleList.h" 19061da546Spatrick #include "lldb/Target/DynamicLoader.h" 20061da546Spatrick 21061da546Spatrick class AuxVector; 22061da546Spatrick 23061da546Spatrick class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader { 24061da546Spatrick public: 25061da546Spatrick DynamicLoaderPOSIXDYLD(lldb_private::Process *process); 26061da546Spatrick 27061da546Spatrick ~DynamicLoaderPOSIXDYLD() override; 28061da546Spatrick 29061da546Spatrick static void Initialize(); 30061da546Spatrick 31061da546Spatrick static void Terminate(); 32061da546Spatrick GetPluginNameStatic()33*f6aab3d8Srobert static llvm::StringRef GetPluginNameStatic() { return "posix-dyld"; } 34061da546Spatrick 35*f6aab3d8Srobert static llvm::StringRef GetPluginDescriptionStatic(); 36061da546Spatrick 37061da546Spatrick static lldb_private::DynamicLoader * 38061da546Spatrick CreateInstance(lldb_private::Process *process, bool force); 39061da546Spatrick 40061da546Spatrick // DynamicLoader protocol 41061da546Spatrick 42061da546Spatrick void DidAttach() override; 43061da546Spatrick 44061da546Spatrick void DidLaunch() override; 45061da546Spatrick 46061da546Spatrick lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, 47061da546Spatrick bool stop_others) override; 48061da546Spatrick 49061da546Spatrick lldb_private::Status CanLoadImage() override; 50061da546Spatrick 51061da546Spatrick lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module, 52061da546Spatrick const lldb::ThreadSP thread, 53061da546Spatrick lldb::addr_t tls_file_addr) override; 54061da546Spatrick 55061da546Spatrick // PluginInterface protocol GetPluginName()56*f6aab3d8Srobert llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 57061da546Spatrick 58*f6aab3d8Srobert lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, 59*f6aab3d8Srobert lldb::addr_t link_map_addr, 60*f6aab3d8Srobert lldb::addr_t base_addr, 61*f6aab3d8Srobert bool base_addr_is_offset) override; 62061da546Spatrick 63061da546Spatrick protected: 64061da546Spatrick /// Runtime linker rendezvous structure. 65061da546Spatrick DYLDRendezvous m_rendezvous; 66061da546Spatrick 67061da546Spatrick /// Virtual load address of the inferior process. 68061da546Spatrick lldb::addr_t m_load_offset; 69061da546Spatrick 70061da546Spatrick /// Virtual entry address of the inferior process. 71061da546Spatrick lldb::addr_t m_entry_point; 72061da546Spatrick 73061da546Spatrick /// Auxiliary vector of the inferior process. 74061da546Spatrick std::unique_ptr<AuxVector> m_auxv; 75061da546Spatrick 76061da546Spatrick /// Rendezvous breakpoint. 77061da546Spatrick lldb::break_id_t m_dyld_bid; 78061da546Spatrick 79061da546Spatrick /// Contains AT_SYSINFO_EHDR, which means a vDSO has been 80061da546Spatrick /// mapped to the address space 81061da546Spatrick lldb::addr_t m_vdso_base; 82061da546Spatrick 83061da546Spatrick /// Contains AT_BASE, which means a dynamic loader has been 84061da546Spatrick /// mapped to the address space 85061da546Spatrick lldb::addr_t m_interpreter_base; 86061da546Spatrick 87be691f3bSpatrick /// Contains the pointer to the interpret module, if loaded. 88be691f3bSpatrick std::weak_ptr<lldb_private::Module> m_interpreter_module; 89be691f3bSpatrick 90061da546Spatrick /// Loaded module list. (link map for each module) 91061da546Spatrick std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> 92061da546Spatrick m_loaded_modules; 93061da546Spatrick 94*f6aab3d8Srobert /// Returns true if the process is for a core file. 95*f6aab3d8Srobert bool IsCoreFile() const; 96*f6aab3d8Srobert 97061da546Spatrick /// If possible sets a breakpoint on a function called by the runtime 98061da546Spatrick /// linker each time a module is loaded or unloaded. 99061da546Spatrick bool SetRendezvousBreakpoint(); 100061da546Spatrick 101061da546Spatrick /// Callback routine which updates the current list of loaded modules based 102061da546Spatrick /// on the information supplied by the runtime linker. 103061da546Spatrick static bool RendezvousBreakpointHit( 104061da546Spatrick void *baton, lldb_private::StoppointCallbackContext *context, 105061da546Spatrick lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 106061da546Spatrick 107be691f3bSpatrick /// Indicates whether the initial set of modules was reported added. 108be691f3bSpatrick bool m_initial_modules_added; 109be691f3bSpatrick 110061da546Spatrick /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set 111061da546Spatrick /// of loaded modules. 112061da546Spatrick void RefreshModules(); 113061da546Spatrick 114061da546Spatrick /// Updates the load address of every allocatable section in \p module. 115061da546Spatrick /// 116061da546Spatrick /// \param module The module to traverse. 117061da546Spatrick /// 118061da546Spatrick /// \param link_map_addr The virtual address of the link map for the @p 119061da546Spatrick /// module. 120061da546Spatrick /// 121061da546Spatrick /// \param base_addr The virtual base address \p module is loaded at. 122061da546Spatrick void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, 123061da546Spatrick lldb::addr_t base_addr, 124061da546Spatrick bool base_addr_is_offset) override; 125061da546Spatrick 126061da546Spatrick /// Removes the loaded sections from the target in \p module. 127061da546Spatrick /// 128061da546Spatrick /// \param module The module to traverse. 129061da546Spatrick void UnloadSections(const lldb::ModuleSP module) override; 130061da546Spatrick 131061da546Spatrick /// Resolves the entry point for the current inferior process and sets a 132061da546Spatrick /// breakpoint at that address. 133061da546Spatrick void ProbeEntry(); 134061da546Spatrick 135061da546Spatrick /// Callback routine invoked when we hit the breakpoint on process entry. 136061da546Spatrick /// 137061da546Spatrick /// This routine is responsible for resolving the load addresses of all 138061da546Spatrick /// dependent modules required by the inferior and setting up the rendezvous 139061da546Spatrick /// breakpoint. 140061da546Spatrick static bool 141061da546Spatrick EntryBreakpointHit(void *baton, 142061da546Spatrick lldb_private::StoppointCallbackContext *context, 143061da546Spatrick lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 144061da546Spatrick 145061da546Spatrick /// Helper for the entry breakpoint callback. Resolves the load addresses 146061da546Spatrick /// of all dependent modules. 147061da546Spatrick virtual void LoadAllCurrentModules(); 148061da546Spatrick 149061da546Spatrick void LoadVDSO(); 150061da546Spatrick 151dda28197Spatrick // Loading an interpreter module (if present) assuming m_interpreter_base 152061da546Spatrick // already points to its base address. 153061da546Spatrick lldb::ModuleSP LoadInterpreterModule(); 154061da546Spatrick 155061da546Spatrick /// Computes a value for m_load_offset returning the computed address on 156061da546Spatrick /// success and LLDB_INVALID_ADDRESS on failure. 157061da546Spatrick lldb::addr_t ComputeLoadOffset(); 158061da546Spatrick 159061da546Spatrick /// Computes a value for m_entry_point returning the computed address on 160061da546Spatrick /// success and LLDB_INVALID_ADDRESS on failure. 161061da546Spatrick lldb::addr_t GetEntryPoint(); 162061da546Spatrick 163061da546Spatrick /// Evaluate if Aux vectors contain vDSO and LD information 164061da546Spatrick /// in case they do, read and assign the address to m_vdso_base 165061da546Spatrick /// and m_interpreter_base. 166061da546Spatrick void EvalSpecialModulesStatus(); 167061da546Spatrick 168061da546Spatrick /// Loads Module from inferior process. 169061da546Spatrick void ResolveExecutableModule(lldb::ModuleSP &module_sp); 170061da546Spatrick 171061da546Spatrick bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override; 172061da546Spatrick 173061da546Spatrick private: 174dda28197Spatrick DynamicLoaderPOSIXDYLD(const DynamicLoaderPOSIXDYLD &) = delete; 175dda28197Spatrick const DynamicLoaderPOSIXDYLD & 176dda28197Spatrick operator=(const DynamicLoaderPOSIXDYLD &) = delete; 177061da546Spatrick }; 178061da546Spatrick 179dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H 180