xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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