Coverage Report

Created: 2022-01-18 06:27

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