File: | tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp |
Warning: | line 105, column 3 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- DynamicLoaderPOSIXDYLD.cpp ------------------------------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | // Main header include | |||
11 | #include "DynamicLoaderPOSIXDYLD.h" | |||
12 | ||||
13 | // Project includes | |||
14 | #include "AuxVector.h" | |||
15 | ||||
16 | // Other libraries and framework includes | |||
17 | #include "lldb/Breakpoint/BreakpointLocation.h" | |||
18 | #include "lldb/Core/Module.h" | |||
19 | #include "lldb/Core/ModuleSpec.h" | |||
20 | #include "lldb/Core/PluginManager.h" | |||
21 | #include "lldb/Core/Section.h" | |||
22 | #include "lldb/Symbol/Function.h" | |||
23 | #include "lldb/Symbol/ObjectFile.h" | |||
24 | #include "lldb/Target/MemoryRegionInfo.h" | |||
25 | #include "lldb/Target/Platform.h" | |||
26 | #include "lldb/Target/Process.h" | |||
27 | #include "lldb/Target/Target.h" | |||
28 | #include "lldb/Target/Thread.h" | |||
29 | #include "lldb/Target/ThreadPlanRunToAddress.h" | |||
30 | #include "lldb/Utility/Log.h" | |||
31 | ||||
32 | // C++ Includes | |||
33 | // C Includes | |||
34 | ||||
35 | using namespace lldb; | |||
36 | using namespace lldb_private; | |||
37 | ||||
38 | void DynamicLoaderPOSIXDYLD::Initialize() { | |||
39 | PluginManager::RegisterPlugin(GetPluginNameStatic(), | |||
40 | GetPluginDescriptionStatic(), CreateInstance); | |||
41 | } | |||
42 | ||||
43 | void DynamicLoaderPOSIXDYLD::Terminate() {} | |||
44 | ||||
45 | lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() { | |||
46 | return GetPluginNameStatic(); | |||
47 | } | |||
48 | ||||
49 | lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() { | |||
50 | static ConstString g_name("linux-dyld"); | |||
51 | return g_name; | |||
52 | } | |||
53 | ||||
54 | const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() { | |||
55 | return "Dynamic loader plug-in that watches for shared library " | |||
56 | "loads/unloads in POSIX processes."; | |||
57 | } | |||
58 | ||||
59 | uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; } | |||
60 | ||||
61 | DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, | |||
62 | bool force) { | |||
63 | bool create = force; | |||
64 | if (!create) { | |||
65 | const llvm::Triple &triple_ref = | |||
66 | process->GetTarget().GetArchitecture().GetTriple(); | |||
67 | if (triple_ref.getOS() == llvm::Triple::FreeBSD || | |||
68 | triple_ref.getOS() == llvm::Triple::Linux || | |||
69 | triple_ref.getOS() == llvm::Triple::NetBSD) | |||
70 | create = true; | |||
71 | } | |||
72 | ||||
73 | if (create) | |||
74 | return new DynamicLoaderPOSIXDYLD(process); | |||
75 | return NULL__null; | |||
76 | } | |||
77 | ||||
78 | DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process) | |||
79 | : DynamicLoader(process), m_rendezvous(process), | |||
80 | m_load_offset(LLDB_INVALID_ADDRESS(18446744073709551615UL)), m_entry_point(LLDB_INVALID_ADDRESS(18446744073709551615UL)), | |||
81 | m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID0), | |||
82 | m_vdso_base(LLDB_INVALID_ADDRESS(18446744073709551615UL)), | |||
83 | m_interpreter_base(LLDB_INVALID_ADDRESS(18446744073709551615UL)) {} | |||
84 | ||||
85 | DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { | |||
86 | if (m_dyld_bid != LLDB_INVALID_BREAK_ID0) { | |||
87 | m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid); | |||
88 | m_dyld_bid = LLDB_INVALID_BREAK_ID0; | |||
89 | } | |||
90 | } | |||
91 | ||||
92 | void DynamicLoaderPOSIXDYLD::DidAttach() { | |||
93 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
94 | if (log) | |||
| ||||
95 | log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64"l" "u", __FUNCTION__, | |||
96 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0); | |||
97 | ||||
98 | m_auxv.reset(new AuxVector(m_process)); | |||
99 | if (log) | |||
100 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" " reloaded auxv data", | |||
101 | __FUNCTION__, | |||
102 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0); | |||
103 | ||||
104 | // ask the process if it can load any of its own modules | |||
105 | m_process->LoadModules(); | |||
| ||||
106 | ||||
107 | ModuleSP executable_sp = GetTargetExecutable(); | |||
108 | ResolveExecutableModule(executable_sp); | |||
109 | ||||
110 | // find the main process load offset | |||
111 | addr_t load_offset = ComputeLoadOffset(); | |||
112 | if (log) | |||
113 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
114 | " executable '%s', load_offset 0x%" PRIx64"l" "x", | |||
115 | __FUNCTION__, | |||
116 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0, | |||
117 | executable_sp ? executable_sp->GetFileSpec().GetPath().c_str() | |||
118 | : "<null executable>", | |||
119 | load_offset); | |||
120 | ||||
121 | EvalSpecialModulesStatus(); | |||
122 | ||||
123 | // if we dont have a load address we cant re-base | |||
124 | bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS(18446744073709551615UL)) ? false : true; | |||
125 | ||||
126 | // if we have a valid executable | |||
127 | if (executable_sp.get()) { | |||
128 | lldb_private::ObjectFile *obj = executable_sp->GetObjectFile(); | |||
129 | if (obj) { | |||
130 | // don't rebase if the module already has a load address | |||
131 | Target &target = m_process->GetTarget(); | |||
132 | Address addr = obj->GetImageInfoAddress(&target); | |||
133 | if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
134 | rebase_exec = false; | |||
135 | } | |||
136 | } else { | |||
137 | // no executable, nothing to re-base | |||
138 | rebase_exec = false; | |||
139 | } | |||
140 | ||||
141 | // if the target executable should be re-based | |||
142 | if (rebase_exec) { | |||
143 | ModuleList module_list; | |||
144 | ||||
145 | module_list.Append(executable_sp); | |||
146 | if (log) | |||
147 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
148 | " added executable '%s' to module load list", | |||
149 | __FUNCTION__, | |||
150 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0, | |||
151 | executable_sp->GetFileSpec().GetPath().c_str()); | |||
152 | ||||
153 | UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS(18446744073709551615UL), load_offset, | |||
154 | true); | |||
155 | ||||
156 | LoadAllCurrentModules(); | |||
157 | if (!SetRendezvousBreakpoint()) { | |||
158 | // If we cannot establish rendezvous breakpoint right now we'll try again | |||
159 | // at entry point. | |||
160 | ProbeEntry(); | |||
161 | } | |||
162 | ||||
163 | m_process->GetTarget().ModulesDidLoad(module_list); | |||
164 | if (log) { | |||
165 | log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the " | |||
166 | "modules that loaded:", | |||
167 | __FUNCTION__); | |||
168 | for (auto module_sp : module_list.Modules()) { | |||
169 | log->Printf("-- [module] %s (pid %" PRIu64"l" "u" ")", | |||
170 | module_sp ? module_sp->GetFileSpec().GetPath().c_str() | |||
171 | : "<null>", | |||
172 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0); | |||
173 | } | |||
174 | } | |||
175 | } | |||
176 | } | |||
177 | ||||
178 | void DynamicLoaderPOSIXDYLD::DidLaunch() { | |||
179 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
180 | if (log) | |||
181 | log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__); | |||
182 | ||||
183 | ModuleSP executable; | |||
184 | addr_t load_offset; | |||
185 | ||||
186 | m_auxv.reset(new AuxVector(m_process)); | |||
187 | ||||
188 | executable = GetTargetExecutable(); | |||
189 | load_offset = ComputeLoadOffset(); | |||
190 | EvalSpecialModulesStatus(); | |||
191 | ||||
192 | if (executable.get() && load_offset != LLDB_INVALID_ADDRESS(18446744073709551615UL)) { | |||
193 | ModuleList module_list; | |||
194 | module_list.Append(executable); | |||
195 | UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS(18446744073709551615UL), load_offset, true); | |||
196 | ||||
197 | if (log) | |||
198 | log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", | |||
199 | __FUNCTION__); | |||
200 | ||||
201 | if (!SetRendezvousBreakpoint()) { | |||
202 | // If we cannot establish rendezvous breakpoint right now we'll try again | |||
203 | // at entry point. | |||
204 | ProbeEntry(); | |||
205 | } | |||
206 | ||||
207 | LoadVDSO(); | |||
208 | m_process->GetTarget().ModulesDidLoad(module_list); | |||
209 | } | |||
210 | } | |||
211 | ||||
212 | Status DynamicLoaderPOSIXDYLD::CanLoadImage() { return Status(); } | |||
213 | ||||
214 | void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, | |||
215 | addr_t link_map_addr, | |||
216 | addr_t base_addr, | |||
217 | bool base_addr_is_offset) { | |||
218 | m_loaded_modules[module] = link_map_addr; | |||
219 | UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); | |||
220 | } | |||
221 | ||||
222 | void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) { | |||
223 | m_loaded_modules.erase(module); | |||
224 | ||||
225 | UnloadSectionsCommon(module); | |||
226 | } | |||
227 | ||||
228 | void DynamicLoaderPOSIXDYLD::ProbeEntry() { | |||
229 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
230 | ||||
231 | const addr_t entry = GetEntryPoint(); | |||
232 | if (entry == LLDB_INVALID_ADDRESS(18446744073709551615UL)) { | |||
233 | if (log) | |||
234 | log->Printf( | |||
235 | "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
236 | " GetEntryPoint() returned no address, not setting entry breakpoint", | |||
237 | __FUNCTION__, | |||
238 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0); | |||
239 | return; | |||
240 | } | |||
241 | ||||
242 | if (log) | |||
243 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
244 | " GetEntryPoint() returned address 0x%" PRIx64"l" "x" | |||
245 | ", setting entry breakpoint", | |||
246 | __FUNCTION__, | |||
247 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID0, | |||
248 | entry); | |||
249 | ||||
250 | if (m_process) { | |||
251 | Breakpoint *const entry_break = | |||
252 | m_process->GetTarget().CreateBreakpoint(entry, true, false).get(); | |||
253 | entry_break->SetCallback(EntryBreakpointHit, this, true); | |||
254 | entry_break->SetBreakpointKind("shared-library-event"); | |||
255 | ||||
256 | // Shoudn't hit this more than once. | |||
257 | entry_break->SetOneShot(true); | |||
258 | } | |||
259 | } | |||
260 | ||||
261 | // The runtime linker has run and initialized the rendezvous structure once the | |||
262 | // process has hit its entry point. When we hit the corresponding breakpoint | |||
263 | // we interrogate the rendezvous structure to get the load addresses of all | |||
264 | // dependent modules for the process. Similarly, we can discover the runtime | |||
265 | // linker function and setup a breakpoint to notify us of any dynamically | |||
266 | // loaded modules (via dlopen). | |||
267 | bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( | |||
268 | void *baton, StoppointCallbackContext *context, user_id_t break_id, | |||
269 | user_id_t break_loc_id) { | |||
270 | assert(baton && "null baton")((baton && "null baton") ? static_cast<void> (0 ) : __assert_fail ("baton && \"null baton\"", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , 270, __PRETTY_FUNCTION__)); | |||
271 | if (!baton) | |||
272 | return false; | |||
273 | ||||
274 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
275 | DynamicLoaderPOSIXDYLD *const dyld_instance = | |||
276 | static_cast<DynamicLoaderPOSIXDYLD *>(baton); | |||
277 | if (log) | |||
278 | log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64"l" "u", | |||
279 | __FUNCTION__, | |||
280 | dyld_instance->m_process ? dyld_instance->m_process->GetID() | |||
281 | : LLDB_INVALID_PROCESS_ID0); | |||
282 | ||||
283 | // Disable the breakpoint --- if a stop happens right after this, which we've | |||
284 | // seen on occasion, we don't want the breakpoint stepping thread-plan logic | |||
285 | // to show a breakpoint instruction at the disassembled entry point to the | |||
286 | // program. Disabling it prevents it. (One-shot is not enough - one-shot | |||
287 | // removal logic only happens after the breakpoint goes public, which wasn't | |||
288 | // happening in our scenario). | |||
289 | if (dyld_instance->m_process) { | |||
290 | BreakpointSP breakpoint_sp = | |||
291 | dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id); | |||
292 | if (breakpoint_sp) { | |||
293 | if (log) | |||
294 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
295 | " disabling breakpoint id %" PRIu64"l" "u", | |||
296 | __FUNCTION__, dyld_instance->m_process->GetID(), break_id); | |||
297 | breakpoint_sp->SetEnabled(false); | |||
298 | } else { | |||
299 | if (log) | |||
300 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
301 | " failed to find breakpoint for breakpoint id %" PRIu64"l" "u", | |||
302 | __FUNCTION__, dyld_instance->m_process->GetID(), break_id); | |||
303 | } | |||
304 | } else { | |||
305 | if (log) | |||
306 | log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64"l" "u" | |||
307 | " no Process instance! Cannot disable breakpoint", | |||
308 | __FUNCTION__, break_id); | |||
309 | } | |||
310 | ||||
311 | dyld_instance->LoadAllCurrentModules(); | |||
312 | dyld_instance->SetRendezvousBreakpoint(); | |||
313 | return false; // Continue running. | |||
314 | } | |||
315 | ||||
316 | bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { | |||
317 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
318 | if (m_dyld_bid != LLDB_INVALID_BREAK_ID0) { | |||
319 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint breakpoint id {0} for pid {1}" "is already set.", m_dyld_bid, m_process ? m_process->GetID () : 0); } while (0) | |||
320 | "Rendezvous breakpoint breakpoint id {0} for pid {1}"do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint breakpoint id {0} for pid {1}" "is already set.", m_dyld_bid, m_process ? m_process->GetID () : 0); } while (0) | |||
321 | "is already set.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint breakpoint id {0} for pid {1}" "is already set.", m_dyld_bid, m_process ? m_process->GetID () : 0); } while (0) | |||
322 | m_dyld_bid,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint breakpoint id {0} for pid {1}" "is already set.", m_dyld_bid, m_process ? m_process->GetID () : 0); } while (0) | |||
323 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint breakpoint id {0} for pid {1}" "is already set.", m_dyld_bid, m_process ? m_process->GetID () : 0); } while (0); | |||
324 | return true; | |||
325 | } | |||
326 | ||||
327 | addr_t break_addr; | |||
328 | Target &target = m_process->GetTarget(); | |||
329 | BreakpointSP dyld_break; | |||
330 | if (m_rendezvous.IsValid()) { | |||
331 | break_addr = m_rendezvous.GetBreakAddress(); | |||
332 | LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Setting rendezvous break address for pid {0} at {1:x}" , m_process ? m_process->GetID() : 0, break_addr); } while (0) | |||
333 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Setting rendezvous break address for pid {0} at {1:x}" , m_process ? m_process->GetID() : 0, break_addr); } while (0) | |||
334 | break_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Setting rendezvous break address for pid {0} at {1:x}" , m_process ? m_process->GetID() : 0, break_addr); } while (0); | |||
335 | dyld_break = target.CreateBreakpoint(break_addr, true, false); | |||
336 | } else { | |||
337 | LLDB_LOG(log, "Rendezvous structure is not set up yet. "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous structure is not set up yet. " "Trying to locate rendezvous breakpoint in the interpreter " "by symbol name."); } while (0) | |||
338 | "Trying to locate rendezvous breakpoint in the interpreter "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous structure is not set up yet. " "Trying to locate rendezvous breakpoint in the interpreter " "by symbol name."); } while (0) | |||
339 | "by symbol name.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous structure is not set up yet. " "Trying to locate rendezvous breakpoint in the interpreter " "by symbol name."); } while (0); | |||
340 | ModuleSP interpreter = LoadInterpreterModule(); | |||
341 | if (!interpreter) { | |||
342 | LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set.")do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Can't find interpreter, rendezvous breakpoint isn't set." ); } while (0); | |||
343 | return false; | |||
344 | } | |||
345 | ||||
346 | // Function names from different dynamic loaders that are known to be used | |||
347 | // as rendezvous between the loader and debuggers. | |||
348 | static std::vector<std::string> DebugStateCandidates{ | |||
349 | "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", | |||
350 | "r_debug_state", "_r_debug_state", "_rtld_debug_state", | |||
351 | }; | |||
352 | ||||
353 | FileSpecList containingModules; | |||
354 | containingModules.Append(interpreter->GetFileSpec()); | |||
355 | dyld_break = target.CreateBreakpoint( | |||
356 | &containingModules, nullptr /* containingSourceFiles */, | |||
357 | DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, | |||
358 | 0, /* offset */ | |||
359 | eLazyBoolNo, /* skip_prologue */ | |||
360 | true, /* internal */ | |||
361 | false /* request_hardware */); | |||
362 | } | |||
363 | ||||
364 | if (dyld_break->GetNumResolvedLocations() != 1) { | |||
365 | LLDB_LOG(do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint has abnormal number of" " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1." , dyld_break->GetNumResolvedLocations(), m_process ? m_process ->GetID() : 0); } while (0) | |||
366 | log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint has abnormal number of" " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1." , dyld_break->GetNumResolvedLocations(), m_process ? m_process ->GetID() : 0); } while (0) | |||
367 | "Rendezvous breakpoint has abnormal number of"do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint has abnormal number of" " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1." , dyld_break->GetNumResolvedLocations(), m_process ? m_process ->GetID() : 0); } while (0) | |||
368 | " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint has abnormal number of" " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1." , dyld_break->GetNumResolvedLocations(), m_process ? m_process ->GetID() : 0); } while (0) | |||
369 | dyld_break->GetNumResolvedLocations(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint has abnormal number of" " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1." , dyld_break->GetNumResolvedLocations(), m_process ? m_process ->GetID() : 0); } while (0) | |||
370 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Rendezvous breakpoint has abnormal number of" " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1." , dyld_break->GetNumResolvedLocations(), m_process ? m_process ->GetID() : 0); } while (0); | |||
371 | ||||
372 | target.RemoveBreakpointByID(dyld_break->GetID()); | |||
373 | return false; | |||
374 | } | |||
375 | ||||
376 | BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0); | |||
377 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Successfully set rendezvous breakpoint at address {0:x} " "for pid {1}", location->GetLoadAddress(), m_process ? m_process ->GetID() : 0); } while (0) | |||
378 | "Successfully set rendezvous breakpoint at address {0:x} "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Successfully set rendezvous breakpoint at address {0:x} " "for pid {1}", location->GetLoadAddress(), m_process ? m_process ->GetID() : 0); } while (0) | |||
379 | "for pid {1}",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Successfully set rendezvous breakpoint at address {0:x} " "for pid {1}", location->GetLoadAddress(), m_process ? m_process ->GetID() : 0); } while (0) | |||
380 | location->GetLoadAddress(),do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Successfully set rendezvous breakpoint at address {0:x} " "for pid {1}", location->GetLoadAddress(), m_process ? m_process ->GetID() : 0); } while (0) | |||
381 | m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Successfully set rendezvous breakpoint at address {0:x} " "for pid {1}", location->GetLoadAddress(), m_process ? m_process ->GetID() : 0); } while (0); | |||
382 | ||||
383 | dyld_break->SetCallback(RendezvousBreakpointHit, this, true); | |||
384 | dyld_break->SetBreakpointKind("shared-library-event"); | |||
385 | m_dyld_bid = dyld_break->GetID(); | |||
386 | return true; | |||
387 | } | |||
388 | ||||
389 | bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( | |||
390 | void *baton, StoppointCallbackContext *context, user_id_t break_id, | |||
391 | user_id_t break_loc_id) { | |||
392 | assert(baton && "null baton")((baton && "null baton") ? static_cast<void> (0 ) : __assert_fail ("baton && \"null baton\"", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , 392, __PRETTY_FUNCTION__)); | |||
393 | if (!baton) | |||
394 | return false; | |||
395 | ||||
396 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
397 | DynamicLoaderPOSIXDYLD *const dyld_instance = | |||
398 | static_cast<DynamicLoaderPOSIXDYLD *>(baton); | |||
399 | if (log) | |||
400 | log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64"l" "u", | |||
401 | __FUNCTION__, | |||
402 | dyld_instance->m_process ? dyld_instance->m_process->GetID() | |||
403 | : LLDB_INVALID_PROCESS_ID0); | |||
404 | ||||
405 | dyld_instance->RefreshModules(); | |||
406 | ||||
407 | // Return true to stop the target, false to just let the target run. | |||
408 | const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange(); | |||
409 | if (log) | |||
410 | log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64"l" "u" | |||
411 | " stop_when_images_change=%s", | |||
412 | __FUNCTION__, | |||
413 | dyld_instance->m_process ? dyld_instance->m_process->GetID() | |||
414 | : LLDB_INVALID_PROCESS_ID0, | |||
415 | stop_when_images_change ? "true" : "false"); | |||
416 | return stop_when_images_change; | |||
417 | } | |||
418 | ||||
419 | void DynamicLoaderPOSIXDYLD::RefreshModules() { | |||
420 | if (!m_rendezvous.Resolve()) | |||
421 | return; | |||
422 | ||||
423 | DYLDRendezvous::iterator I; | |||
424 | DYLDRendezvous::iterator E; | |||
425 | ||||
426 | ModuleList &loaded_modules = m_process->GetTarget().GetImages(); | |||
427 | ||||
428 | if (m_rendezvous.ModulesDidLoad()) { | |||
429 | ModuleList new_modules; | |||
430 | ||||
431 | E = m_rendezvous.loaded_end(); | |||
432 | for (I = m_rendezvous.loaded_begin(); I != E; ++I) { | |||
433 | ModuleSP module_sp = | |||
434 | LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); | |||
435 | if (module_sp.get()) { | |||
436 | loaded_modules.AppendIfNeeded(module_sp); | |||
437 | new_modules.Append(module_sp); | |||
438 | } | |||
439 | } | |||
440 | m_process->GetTarget().ModulesDidLoad(new_modules); | |||
441 | } | |||
442 | ||||
443 | if (m_rendezvous.ModulesDidUnload()) { | |||
444 | ModuleList old_modules; | |||
445 | ||||
446 | E = m_rendezvous.unloaded_end(); | |||
447 | for (I = m_rendezvous.unloaded_begin(); I != E; ++I) { | |||
448 | ModuleSpec module_spec{I->file_spec}; | |||
449 | ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec); | |||
450 | ||||
451 | if (module_sp.get()) { | |||
452 | old_modules.Append(module_sp); | |||
453 | UnloadSections(module_sp); | |||
454 | } | |||
455 | } | |||
456 | loaded_modules.Remove(old_modules); | |||
457 | m_process->GetTarget().ModulesDidUnload(old_modules, false); | |||
458 | } | |||
459 | } | |||
460 | ||||
461 | ThreadPlanSP | |||
462 | DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, | |||
463 | bool stop) { | |||
464 | ThreadPlanSP thread_plan_sp; | |||
465 | ||||
466 | StackFrame *frame = thread.GetStackFrameAtIndex(0).get(); | |||
467 | const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol); | |||
468 | Symbol *sym = context.symbol; | |||
469 | ||||
470 | if (sym == NULL__null || !sym->IsTrampoline()) | |||
471 | return thread_plan_sp; | |||
472 | ||||
473 | ConstString sym_name = sym->GetName(); | |||
474 | if (!sym_name) | |||
475 | return thread_plan_sp; | |||
476 | ||||
477 | SymbolContextList target_symbols; | |||
478 | Target &target = thread.GetProcess()->GetTarget(); | |||
479 | const ModuleList &images = target.GetImages(); | |||
480 | ||||
481 | images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols); | |||
482 | size_t num_targets = target_symbols.GetSize(); | |||
483 | if (!num_targets) | |||
484 | return thread_plan_sp; | |||
485 | ||||
486 | typedef std::vector<lldb::addr_t> AddressVector; | |||
487 | AddressVector addrs; | |||
488 | for (size_t i = 0; i < num_targets; ++i) { | |||
489 | SymbolContext context; | |||
490 | AddressRange range; | |||
491 | if (target_symbols.GetContextAtIndex(i, context)) { | |||
492 | context.GetAddressRange(eSymbolContextEverything, 0, false, range); | |||
493 | lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); | |||
494 | if (addr != LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
495 | addrs.push_back(addr); | |||
496 | } | |||
497 | } | |||
498 | ||||
499 | if (addrs.size() > 0) { | |||
500 | AddressVector::iterator start = addrs.begin(); | |||
501 | AddressVector::iterator end = addrs.end(); | |||
502 | ||||
503 | std::sort(start, end); | |||
504 | addrs.erase(std::unique(start, end), end); | |||
505 | thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop)); | |||
506 | } | |||
507 | ||||
508 | return thread_plan_sp; | |||
509 | } | |||
510 | ||||
511 | void DynamicLoaderPOSIXDYLD::LoadVDSO() { | |||
512 | if (m_vdso_base == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
513 | return; | |||
514 | ||||
515 | FileSpec file("[vdso]", false); | |||
516 | ||||
517 | MemoryRegionInfo info; | |||
518 | Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info); | |||
519 | if (status.Fail()) { | |||
520 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
521 | LLDB_LOG(log, "Failed to get vdso region info: {0}", status)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Failed to get vdso region info: {0}", status); } while (0); | |||
522 | return; | |||
523 | } | |||
524 | ||||
525 | if (ModuleSP module_sp = m_process->ReadModuleFromMemory( | |||
526 | file, m_vdso_base, info.GetRange().GetByteSize())) { | |||
527 | UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS(18446744073709551615UL), m_vdso_base, false); | |||
528 | m_process->GetTarget().GetImages().AppendIfNeeded(module_sp); | |||
529 | } | |||
530 | } | |||
531 | ||||
532 | ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { | |||
533 | if (m_interpreter_base == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
534 | return nullptr; | |||
535 | ||||
536 | MemoryRegionInfo info; | |||
537 | Target &target = m_process->GetTarget(); | |||
538 | Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info); | |||
539 | if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes || | |||
540 | info.GetName().IsEmpty()) { | |||
541 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
542 | LLDB_LOG(log, "Failed to get interpreter region info: {0}", status)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "Failed to get interpreter region info: {0}", status ); } while (0); | |||
543 | return nullptr; | |||
544 | } | |||
545 | ||||
546 | FileSpec file(info.GetName().GetCString(), false); | |||
547 | ModuleSpec module_spec(file, target.GetArchitecture()); | |||
548 | ||||
549 | if (ModuleSP module_sp = target.GetSharedModule(module_spec)) { | |||
550 | UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS(18446744073709551615UL), m_interpreter_base, | |||
551 | false); | |||
552 | return module_sp; | |||
553 | } | |||
554 | return nullptr; | |||
555 | } | |||
556 | ||||
557 | void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { | |||
558 | DYLDRendezvous::iterator I; | |||
559 | DYLDRendezvous::iterator E; | |||
560 | ModuleList module_list; | |||
561 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
562 | ||||
563 | LoadVDSO(); | |||
564 | ||||
565 | if (!m_rendezvous.Resolve()) { | |||
566 | if (log) | |||
567 | log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD " | |||
568 | "rendezvous address", | |||
569 | __FUNCTION__); | |||
570 | return; | |||
571 | } | |||
572 | ||||
573 | // The rendezvous class doesn't enumerate the main module, so track that | |||
574 | // ourselves here. | |||
575 | ModuleSP executable = GetTargetExecutable(); | |||
576 | m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); | |||
577 | ||||
578 | std::vector<FileSpec> module_names; | |||
579 | for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) | |||
580 | module_names.push_back(I->file_spec); | |||
581 | m_process->PrefetchModuleSpecs( | |||
582 | module_names, m_process->GetTarget().GetArchitecture().GetTriple()); | |||
583 | ||||
584 | for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { | |||
585 | ModuleSP module_sp = | |||
586 | LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); | |||
587 | if (module_sp.get()) { | |||
588 | LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "LoadAllCurrentModules loading module: {0}", I-> file_spec.GetFilename()); } while (0) | |||
589 | I->file_spec.GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp" , __func__, "LoadAllCurrentModules loading module: {0}", I-> file_spec.GetFilename()); } while (0); | |||
590 | module_list.Append(module_sp); | |||
591 | } else { | |||
592 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
593 | if (log) | |||
594 | log->Printf( | |||
595 | "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64"l" "x", | |||
596 | __FUNCTION__, I->file_spec.GetCString(), I->base_addr); | |||
597 | } | |||
598 | } | |||
599 | ||||
600 | m_process->GetTarget().ModulesDidLoad(module_list); | |||
601 | } | |||
602 | ||||
603 | addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { | |||
604 | addr_t virt_entry; | |||
605 | ||||
606 | if (m_load_offset != LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
607 | return m_load_offset; | |||
608 | ||||
609 | if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
610 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
611 | ||||
612 | ModuleSP module = m_process->GetTarget().GetExecutableModule(); | |||
613 | if (!module) | |||
614 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
615 | ||||
616 | ObjectFile *exe = module->GetObjectFile(); | |||
617 | if (!exe) | |||
618 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
619 | ||||
620 | Address file_entry = exe->GetEntryPointAddress(); | |||
621 | ||||
622 | if (!file_entry.IsValid()) | |||
623 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
624 | ||||
625 | m_load_offset = virt_entry - file_entry.GetFileAddress(); | |||
626 | return m_load_offset; | |||
627 | } | |||
628 | ||||
629 | void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() { | |||
630 | auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR); | |||
631 | if (I != m_auxv->end() && I->value != 0) | |||
632 | m_vdso_base = I->value; | |||
633 | ||||
634 | I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE); | |||
635 | if (I != m_auxv->end() && I->value != 0) | |||
636 | m_interpreter_base = I->value; | |||
637 | } | |||
638 | ||||
639 | addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() { | |||
640 | if (m_entry_point != LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
641 | return m_entry_point; | |||
642 | ||||
643 | if (m_auxv.get() == NULL__null) | |||
644 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
645 | ||||
646 | AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_ENTRY); | |||
647 | ||||
648 | if (I == m_auxv->end()) | |||
649 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
650 | ||||
651 | m_entry_point = static_cast<addr_t>(I->value); | |||
652 | ||||
653 | const ArchSpec &arch = m_process->GetTarget().GetArchitecture(); | |||
654 | ||||
655 | // On ppc64, the entry point is actually a descriptor. Dereference it. | |||
656 | if (arch.GetMachine() == llvm::Triple::ppc64) | |||
657 | m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8); | |||
658 | ||||
659 | return m_entry_point; | |||
660 | } | |||
661 | ||||
662 | lldb::addr_t | |||
663 | DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, | |||
664 | const lldb::ThreadSP thread, | |||
665 | lldb::addr_t tls_file_addr) { | |||
666 | auto it = m_loaded_modules.find(module_sp); | |||
667 | if (it == m_loaded_modules.end()) | |||
668 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
669 | ||||
670 | addr_t link_map = it->second; | |||
671 | if (link_map == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
672 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
673 | ||||
674 | const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo(); | |||
675 | if (!metadata.valid) | |||
676 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
677 | ||||
678 | // Get the thread pointer. | |||
679 | addr_t tp = thread->GetThreadPointer(); | |||
680 | if (tp == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
681 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
682 | ||||
683 | // Find the module's modid. | |||
684 | int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit | |||
685 | int64_t modid = ReadUnsignedIntWithSizeInBytes( | |||
686 | link_map + metadata.modid_offset, modid_size); | |||
687 | if (modid == -1) | |||
688 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
689 | ||||
690 | // Lookup the DTV structure for this thread. | |||
691 | addr_t dtv_ptr = tp + metadata.dtv_offset; | |||
692 | addr_t dtv = ReadPointer(dtv_ptr); | |||
693 | if (dtv == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
694 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
695 | ||||
696 | // Find the TLS block for this module. | |||
697 | addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid; | |||
698 | addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); | |||
699 | ||||
700 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
701 | if (log) | |||
702 | log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: " | |||
703 | "module=%s, link_map=0x%" PRIx64"l" "x" ", tp=0x%" PRIx64"l" "x" | |||
704 | ", modid=%" PRId64"l" "d" ", tls_block=0x%" PRIx64"l" "x" "\n", | |||
705 | module_sp->GetObjectName().AsCString(""), link_map, tp, | |||
706 | (int64_t)modid, tls_block); | |||
707 | ||||
708 | if (tls_block == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
709 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | |||
710 | else | |||
711 | return tls_block + tls_file_addr; | |||
712 | } | |||
713 | ||||
714 | void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( | |||
715 | lldb::ModuleSP &module_sp) { | |||
716 | Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER(1u << 3))); | |||
717 | ||||
718 | if (m_process == nullptr) | |||
719 | return; | |||
720 | ||||
721 | auto &target = m_process->GetTarget(); | |||
722 | const auto platform_sp = target.GetPlatform(); | |||
723 | ||||
724 | ProcessInstanceInfo process_info; | |||
725 | if (!m_process->GetProcessInfo(process_info)) { | |||
726 | if (log) | |||
727 | log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for " | |||
728 | "pid %" PRIu64"l" "u", | |||
729 | __FUNCTION__, m_process->GetID()); | |||
730 | return; | |||
731 | } | |||
732 | ||||
733 | if (log) | |||
734 | log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64"l" "u" | |||
735 | ": %s", | |||
736 | __FUNCTION__, m_process->GetID(), | |||
737 | process_info.GetExecutableFile().GetPath().c_str()); | |||
738 | ||||
739 | ModuleSpec module_spec(process_info.GetExecutableFile(), | |||
740 | process_info.GetArchitecture()); | |||
741 | if (module_sp && module_sp->MatchesModuleSpec(module_spec)) | |||
742 | return; | |||
743 | ||||
744 | const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths()); | |||
745 | auto error = platform_sp->ResolveExecutable( | |||
746 | module_spec, module_sp, | |||
747 | !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr); | |||
748 | if (error.Fail()) { | |||
749 | StreamString stream; | |||
750 | module_spec.Dump(stream); | |||
751 | ||||
752 | if (log) | |||
753 | log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable " | |||
754 | "with module spec \"%s\": %s", | |||
755 | __FUNCTION__, stream.GetData(), error.AsCString()); | |||
756 | return; | |||
757 | } | |||
758 | ||||
759 | target.SetExecutableModule(module_sp, eLoadDependentsNo); | |||
760 | } | |||
761 | ||||
762 | bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo( | |||
763 | lldb_private::SymbolContext &sym_ctx) { | |||
764 | ModuleSP module_sp; | |||
765 | if (sym_ctx.symbol) | |||
766 | module_sp = sym_ctx.symbol->GetAddressRef().GetModule(); | |||
767 | if (!module_sp && sym_ctx.function) | |||
768 | module_sp = | |||
769 | sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule(); | |||
770 | if (!module_sp) | |||
771 | return false; | |||
772 | ||||
773 | return module_sp->GetFileSpec().GetPath() == "[vdso]"; | |||
774 | } |