Coverage Report

Created: 2022-01-25 06:29

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SymbolFileDWARFDebugMap.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
#include "SymbolFileDWARFDebugMap.h"
10
#include "DWARFDebugAranges.h"
11
12
#include "lldb/Core/Module.h"
13
#include "lldb/Core/ModuleList.h"
14
#include "lldb/Core/PluginManager.h"
15
#include "lldb/Core/Section.h"
16
#include "lldb/Host/FileSystem.h"
17
#include "lldb/Utility/RangeMap.h"
18
#include "lldb/Utility/RegularExpression.h"
19
#include "lldb/Utility/Timer.h"
20
21
//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
22
#if defined(DEBUG_OSO_DMAP)
23
#include "lldb/Core/StreamFile.h"
24
#endif
25
26
#include "lldb/Symbol/CompileUnit.h"
27
#include "lldb/Symbol/LineTable.h"
28
#include "lldb/Symbol/ObjectFile.h"
29
#include "lldb/Symbol/SymbolVendor.h"
30
#include "lldb/Symbol/TypeMap.h"
31
#include "lldb/Symbol/VariableList.h"
32
#include "llvm/Support/ScopedPrinter.h"
33
34
#include "LogChannelDWARF.h"
35
#include "SymbolFileDWARF.h"
36
37
#include <memory>
38
39
using namespace lldb;
40
using namespace lldb_private;
41
42
char SymbolFileDWARFDebugMap::ID;
43
44
// Subclass lldb_private::Module so we can intercept the
45
// "Module::GetObjectFile()" (so we can fixup the object file sections) and
46
// also for "Module::GetSymbolFile()" (so we can fixup the symbol file id.
47
48
const SymbolFileDWARFDebugMap::FileRangeMap &
49
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
50
64.6k
    SymbolFileDWARFDebugMap *exe_symfile) {
51
64.6k
  if (file_range_map_valid)
52
63.1k
    return file_range_map;
53
54
1.47k
  file_range_map_valid = true;
55
56
1.47k
  Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
57
1.47k
  if (!oso_module)
58
0
    return file_range_map;
59
60
1.47k
  ObjectFile *oso_objfile = oso_module->GetObjectFile();
61
1.47k
  if (!oso_objfile)
62
0
    return file_range_map;
63
64
1.47k
  Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
65
1.47k
  LLDB_LOGF(
66
1.47k
      log,
67
1.47k
      "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
68
1.47k
      static_cast<void *>(this),
69
1.47k
      oso_module->GetSpecificationDescription().c_str());
70
71
1.47k
  std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
72
1.47k
  if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
73
1.47k
    for (auto comp_unit_info : cu_infos) {
74
1.47k
      Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
75
1.47k
      ModuleSP oso_module_sp(oso_objfile->GetModule());
76
1.47k
      Symtab *oso_symtab = oso_objfile->GetSymtab();
77
78
      /// const uint32_t fun_resolve_flags = SymbolContext::Module |
79
      /// eSymbolContextCompUnit | eSymbolContextFunction;
80
      // SectionList *oso_sections = oso_objfile->Sections();
81
      // Now we need to make sections that map from zero based object file
82
      // addresses to where things ended up in the main executable.
83
84
1.47k
      assert(comp_unit_info->first_symbol_index != UINT32_MAX);
85
      // End index is one past the last valid symbol index
86
0
      const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
87
1.47k
      for (uint32_t idx = comp_unit_info->first_symbol_index +
88
1.47k
                          2; // Skip the N_SO and N_OSO
89
44.0k
           idx < oso_end_idx; 
++idx42.6k
) {
90
42.6k
        Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
91
42.6k
        if (exe_symbol) {
92
42.6k
          if (!exe_symbol->IsDebug())
93
0
            continue;
94
95
42.6k
          switch (exe_symbol->GetType()) {
96
1.09k
          default:
97
1.09k
            break;
98
99
35.7k
          case eSymbolTypeCode: {
100
            // For each N_FUN, or function that we run into in the debug map we
101
            // make a new section that we add to the sections found in the .o
102
            // file. This new section has the file address set to what the
103
            // addresses are in the .o file, and the load address is adjusted
104
            // to match where it ended up in the final executable! We do this
105
            // before we parse any dwarf info so that when it goes get parsed
106
            // all section/offset addresses that get registered will resolve
107
            // correctly to the new addresses in the main executable.
108
109
            // First we find the original symbol in the .o file's symbol table
110
35.7k
            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(
111
35.7k
                exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
112
35.7k
                eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
113
35.7k
            if (oso_fun_symbol) {
114
              // Add the inverse OSO file address to debug map entry mapping
115
35.7k
              exe_symfile->AddOSOFileRange(
116
35.7k
                  this, exe_symbol->GetAddressRef().GetFileAddress(),
117
35.7k
                  exe_symbol->GetByteSize(),
118
35.7k
                  oso_fun_symbol->GetAddressRef().GetFileAddress(),
119
35.7k
                  oso_fun_symbol->GetByteSize());
120
35.7k
            }
121
35.7k
          } break;
122
123
5.76k
          case eSymbolTypeData: {
124
            // For each N_GSYM we remap the address for the global by making a
125
            // new section that we add to the sections found in the .o file.
126
            // This new section has the file address set to what the addresses
127
            // are in the .o file, and the load address is adjusted to match
128
            // where it ended up in the final executable! We do this before we
129
            // parse any dwarf info so that when it goes get parsed all
130
            // section/offset addresses that get registered will resolve
131
            // correctly to the new addresses in the main executable. We
132
            // initially set the section size to be 1 byte, but will need to
133
            // fix up these addresses further after all globals have been
134
            // parsed to span the gaps, or we can find the global variable
135
            // sizes from the DWARF info as we are parsing.
136
137
            // Next we find the non-stab entry that corresponds to the N_GSYM
138
            // in the .o file
139
5.76k
            Symbol *oso_gsym_symbol =
140
5.76k
                oso_symtab->FindFirstSymbolWithNameAndType(
141
5.76k
                    exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
142
5.76k
                    eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny);
143
5.76k
            if (exe_symbol && oso_gsym_symbol && 
exe_symbol->ValueIsAddress()4.46k
&&
144
5.76k
                
oso_gsym_symbol->ValueIsAddress()4.46k
) {
145
              // Add the inverse OSO file address to debug map entry mapping
146
4.46k
              exe_symfile->AddOSOFileRange(
147
4.46k
                  this, exe_symbol->GetAddressRef().GetFileAddress(),
148
4.46k
                  exe_symbol->GetByteSize(),
149
4.46k
                  oso_gsym_symbol->GetAddressRef().GetFileAddress(),
150
4.46k
                  oso_gsym_symbol->GetByteSize());
151
4.46k
            }
152
5.76k
          } break;
153
42.6k
          }
154
42.6k
        }
155
42.6k
      }
156
157
1.47k
      exe_symfile->FinalizeOSOFileRanges(this);
158
      // We don't need the symbols anymore for the .o files
159
1.47k
      oso_objfile->ClearSymtab();
160
1.47k
    }
161
1.47k
  }
162
1.47k
  return file_range_map;
163
1.47k
}
164
165
class DebugMapModule : public Module {
166
public:
167
  DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
168
                 const FileSpec &file_spec, const ArchSpec &arch,
169
                 const ConstString *object_name, off_t object_offset,
170
                 const llvm::sys::TimePoint<> object_mod_time)
171
      : Module(file_spec, arch, object_name, object_offset, object_mod_time),
172
1.81k
        m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
173
174
1.65k
  ~DebugMapModule() override = default;
175
176
  SymbolFile *
177
  GetSymbolFile(bool can_create = true,
178
643k
                lldb_private::Stream *feedback_strm = nullptr) override {
179
    // Scope for locker
180
643k
    if (m_symfile_up.get() || 
!can_create1.79k
)
181
641k
      return m_symfile_up ? m_symfile_up->GetSymbolFile() : 
nullptr0
;
182
183
1.79k
    ModuleSP exe_module_sp(m_exe_module_wp.lock());
184
1.79k
    if (exe_module_sp) {
185
      // Now get the object file outside of a locking scope
186
1.79k
      ObjectFile *oso_objfile = GetObjectFile();
187
1.79k
      if (oso_objfile) {
188
1.79k
        std::lock_guard<std::recursive_mutex> guard(m_mutex);
189
1.79k
        if (SymbolFile *symfile =
190
1.79k
                Module::GetSymbolFile(can_create, feedback_strm)) {
191
          // Set a pointer to this class to set our OSO DWARF file know that
192
          // the DWARF is being used along with a debug map and that it will
193
          // have the remapped sections that we do below.
194
1.79k
          SymbolFileDWARF *oso_symfile =
195
1.79k
              SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symfile);
196
197
1.79k
          if (!oso_symfile)
198
0
            return nullptr;
199
200
1.79k
          ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
201
1.79k
          SymbolFile *exe_symfile = exe_module_sp->GetSymbolFile();
202
203
1.79k
          if (exe_objfile && exe_symfile) {
204
1.79k
            oso_symfile->SetDebugMapModule(exe_module_sp);
205
            // Set the ID of the symbol file DWARF to the index of the OSO
206
            // shifted left by 32 bits to provide a unique prefix for any
207
            // UserID's that get created in the symbol file.
208
1.79k
            oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
209
1.79k
          }
210
1.79k
          return symfile;
211
1.79k
        }
212
1.79k
      }
213
1.79k
    }
214
0
    return nullptr;
215
1.79k
  }
216
217
protected:
218
  ModuleWP m_exe_module_wp;
219
  const uint32_t m_cu_idx;
220
};
221
222
3.47k
void SymbolFileDWARFDebugMap::Initialize() {
223
3.47k
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
224
3.47k
                                GetPluginDescriptionStatic(), CreateInstance);
225
3.47k
}
226
227
3.46k
void SymbolFileDWARFDebugMap::Terminate() {
228
3.46k
  PluginManager::UnregisterPlugin(CreateInstance);
229
3.46k
}
230
231
3.47k
llvm::StringRef SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
232
3.47k
  return "DWARF and DWARF3 debug symbol file reader (debug map).";
233
3.47k
}
234
235
132k
SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) {
236
132k
  return new SymbolFileDWARFDebugMap(std::move(objfile_sp));
237
132k
}
238
239
SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
240
    : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(),
241
      m_func_indexes(), m_glob_indexes(),
242
132k
      m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
243
244
132k
SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() = default;
245
246
1.50k
void SymbolFileDWARFDebugMap::InitializeObject() {}
247
248
133k
void SymbolFileDWARFDebugMap::InitOSO() {
249
133k
  if (m_flags.test(kHaveInitializedOSOs))
250
1.50k
    return;
251
252
132k
  m_flags.set(kHaveInitializedOSOs);
253
254
  // If the object file has been stripped, there is no sense in looking further
255
  // as all of the debug symbols for the debug map will not be available
256
132k
  if (m_objfile_sp->IsStripped())
257
13.8k
    return;
258
259
  // Also make sure the file type is some sort of executable. Core files, debug
260
  // info files (dSYM), object files (.o files), and stub libraries all can
261
118k
  switch (m_objfile_sp->GetType()) {
262
0
  case ObjectFile::eTypeInvalid:
263
1
  case ObjectFile::eTypeCoreFile:
264
31
  case ObjectFile::eTypeDebugInfo:
265
77
  case ObjectFile::eTypeObjectFile:
266
77
  case ObjectFile::eTypeStubLibrary:
267
77
  case ObjectFile::eTypeUnknown:
268
77
  case ObjectFile::eTypeJIT:
269
77
    return;
270
271
1.53k
  case ObjectFile::eTypeExecutable:
272
4.13k
  case ObjectFile::eTypeDynamicLinker:
273
118k
  case ObjectFile::eTypeSharedLibrary:
274
118k
    break;
275
118k
  }
276
277
  // In order to get the abilities of this plug-in, we look at the list of
278
  // N_OSO entries (object files) from the symbol table and make sure that
279
  // these files exist and also contain valid DWARF. If we get any of that then
280
  // we return the abilities of the first N_OSO's DWARF.
281
282
118k
  Symtab *symtab = m_objfile_sp->GetSymtab();
283
118k
  if (symtab) {
284
118k
    Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
285
286
118k
    std::vector<uint32_t> oso_indexes;
287
    // When a mach-o symbol is encoded, the n_type field is encoded in bits
288
    // 23:16, and the n_desc field is encoded in bits 15:0.
289
    //
290
    // To find all N_OSO entries that are part of the DWARF + debug map we find
291
    // only object file symbols with the flags value as follows: bits 23:16 ==
292
    // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
293
    // file)
294
118k
    const uint32_t k_oso_symbol_flags_value = 0x660001u;
295
296
118k
    const uint32_t oso_index_count =
297
118k
        symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
298
118k
            eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
299
300
118k
    if (oso_index_count > 0) {
301
1.50k
      symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes,
302
1.50k
                                          Symtab::eVisibilityAny,
303
1.50k
                                          m_func_indexes);
304
1.50k
      symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes,
305
1.50k
                                          Symtab::eVisibilityAny,
306
1.50k
                                          m_glob_indexes);
307
308
1.50k
      symtab->SortSymbolIndexesByValue(m_func_indexes, true);
309
1.50k
      symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
310
311
40.1k
      for (uint32_t sym_idx : m_func_indexes) {
312
40.1k
        const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
313
40.1k
        lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
314
40.1k
        lldb::addr_t byte_size = symbol->GetByteSize();
315
40.1k
        DebugMap::Entry debug_map_entry(
316
40.1k
            file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
317
40.1k
        m_debug_map.Append(debug_map_entry);
318
40.1k
      }
319
7.02k
      for (uint32_t sym_idx : m_glob_indexes) {
320
7.02k
        const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
321
7.02k
        lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
322
7.02k
        lldb::addr_t byte_size = symbol->GetByteSize();
323
7.02k
        DebugMap::Entry debug_map_entry(
324
7.02k
            file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
325
7.02k
        m_debug_map.Append(debug_map_entry);
326
7.02k
      }
327
1.50k
      m_debug_map.Sort();
328
329
1.50k
      m_compile_unit_infos.resize(oso_index_count);
330
331
3.58k
      for (uint32_t i = 0; i < oso_index_count; 
++i2.08k
) {
332
2.08k
        const uint32_t so_idx = oso_indexes[i] - 1;
333
2.08k
        const uint32_t oso_idx = oso_indexes[i];
334
2.08k
        const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
335
2.08k
        const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
336
2.08k
        if (so_symbol && oso_symbol &&
337
2.08k
            so_symbol->GetType() == eSymbolTypeSourceFile &&
338
2.08k
            oso_symbol->GetType() == eSymbolTypeObjectFile) {
339
2.08k
          m_compile_unit_infos[i].so_file.SetFile(
340
2.08k
              so_symbol->GetName().AsCString(), FileSpec::Style::native);
341
2.08k
          m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
342
2.08k
          m_compile_unit_infos[i].oso_mod_time =
343
2.08k
              llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
344
2.08k
          uint32_t sibling_idx = so_symbol->GetSiblingIndex();
345
          // The sibling index can't be less that or equal to the current index
346
          // "i"
347
2.08k
          if (sibling_idx == UINT32_MAX) {
348
0
            m_objfile_sp->GetModule()->ReportError(
349
0
                "N_SO in symbol with UID %u has invalid sibling in debug map, "
350
0
                "please file a bug and attach the binary listed in this error",
351
0
                so_symbol->GetID());
352
2.08k
          } else {
353
2.08k
            const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
354
2.08k
            m_compile_unit_infos[i].first_symbol_index = so_idx;
355
2.08k
            m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
356
2.08k
            m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
357
2.08k
            m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
358
359
2.08k
            LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i,
360
2.08k
                      oso_symbol->GetName().GetCString());
361
2.08k
          }
362
2.08k
        } else {
363
0
          if (oso_symbol == nullptr)
364
0
            m_objfile_sp->GetModule()->ReportError(
365
0
                "N_OSO symbol[%u] can't be found, please file a bug and attach "
366
0
                "the binary listed in this error",
367
0
                oso_idx);
368
0
          else if (so_symbol == nullptr)
369
0
            m_objfile_sp->GetModule()->ReportError(
370
0
                "N_SO not found for N_OSO symbol[%u], please file a bug and "
371
0
                "attach the binary listed in this error",
372
0
                oso_idx);
373
0
          else if (so_symbol->GetType() != eSymbolTypeSourceFile)
374
0
            m_objfile_sp->GetModule()->ReportError(
375
0
                "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
376
0
                "please file a bug and attach the binary listed in this error",
377
0
                so_symbol->GetType(), oso_idx);
378
0
          else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
379
0
            m_objfile_sp->GetModule()->ReportError(
380
0
                "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
381
0
                "please file a bug and attach the binary listed in this error",
382
0
                oso_symbol->GetType(), oso_idx);
383
0
        }
384
2.08k
      }
385
1.50k
    }
386
118k
  }
387
118k
}
388
389
0
Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
390
0
  const uint32_t cu_count = GetNumCompileUnits();
391
0
  if (oso_idx < cu_count)
392
0
    return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
393
0
  return nullptr;
394
0
}
395
396
Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
397
575k
    CompileUnitInfo *comp_unit_info) {
398
575k
  if (!comp_unit_info->oso_sp) {
399
1.81k
    auto pos = m_oso_map.find(
400
1.81k
        {comp_unit_info->oso_path, comp_unit_info->oso_mod_time});
401
1.81k
    if (pos != m_oso_map.end()) {
402
0
      comp_unit_info->oso_sp = pos->second;
403
1.81k
    } else {
404
1.81k
      ObjectFile *obj_file = GetObjectFile();
405
1.81k
      comp_unit_info->oso_sp = std::make_shared<OSOInfo>();
406
1.81k
      m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
407
1.81k
          comp_unit_info->oso_sp;
408
1.81k
      const char *oso_path = comp_unit_info->oso_path.GetCString();
409
1.81k
      FileSpec oso_file(oso_path);
410
1.81k
      ConstString oso_object;
411
1.81k
      if (FileSystem::Instance().Exists(oso_file)) {
412
1.61k
        FileSystem::Instance().Collect(oso_file);
413
        // The modification time returned by the FS can have a higher precision
414
        // than the one from the CU.
415
1.61k
        auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
416
1.61k
            FileSystem::Instance().GetModificationTime(oso_file));
417
        // A timestamp of 0 means that the linker was in deterministic mode. In
418
        // that case, we should skip the check against the filesystem last
419
        // modification timestamp, since it will never match.
420
1.61k
        if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() &&
421
1.61k
            
oso_mod_time != comp_unit_info->oso_mod_time1.61k
) {
422
0
          obj_file->GetModule()->ReportError(
423
0
              "debug map object file '%s' has changed (actual time is "
424
0
              "%s, debug map time is %s"
425
0
              ") since this executable was linked, file will be ignored",
426
0
              oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(),
427
0
              llvm::to_string(comp_unit_info->oso_mod_time).c_str());
428
0
          return nullptr;
429
0
        }
430
431
1.61k
      } else {
432
201
        const bool must_exist = true;
433
434
201
        if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
435
201
                                                    oso_object, must_exist)) {
436
0
          return nullptr;
437
0
        }
438
201
      }
439
      // Always create a new module for .o files. Why? Because we use the debug
440
      // map, to add new sections to each .o file and even though a .o file
441
      // might not have changed, the sections that get added to the .o file can
442
      // change.
443
1.81k
      ArchSpec oso_arch;
444
      // Only adopt the architecture from the module (not the vendor or OS)
445
      // since .o files for "i386-apple-ios" will historically show up as "i386
446
      // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
447
      // LC_VERSION_MIN_IPHONEOS load command...
448
1.81k
      oso_arch.SetTriple(m_objfile_sp->GetModule()
449
1.81k
                             ->GetArchitecture()
450
1.81k
                             .GetTriple()
451
1.81k
                             .getArchName()
452
1.81k
                             .str()
453
1.81k
                             .c_str());
454
1.81k
      comp_unit_info->oso_sp->module_sp = std::make_shared<DebugMapModule>(
455
1.81k
          obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
456
1.81k
          oso_arch, oso_object ? 
&oso_object201
:
nullptr1.61k
, 0,
457
1.81k
          oso_object ? 
comp_unit_info->oso_mod_time201
:
llvm::sys::TimePoint<>()1.61k
);
458
1.81k
    }
459
1.81k
  }
460
575k
  if (comp_unit_info->oso_sp)
461
575k
    return comp_unit_info->oso_sp->module_sp.get();
462
0
  return nullptr;
463
575k
}
464
465
bool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx,
466
1.63k
                                               FileSpec &file_spec) {
467
1.63k
  if (oso_idx < m_compile_unit_infos.size()) {
468
1.63k
    if (m_compile_unit_infos[oso_idx].so_file) {
469
1.63k
      file_spec = m_compile_unit_infos[oso_idx].so_file;
470
1.63k
      return true;
471
1.63k
    }
472
1.63k
  }
473
0
  return false;
474
1.63k
}
475
476
0
ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
477
0
  Module *oso_module = GetModuleByOSOIndex(oso_idx);
478
0
  if (oso_module)
479
0
    return oso_module->GetObjectFile();
480
0
  return nullptr;
481
0
}
482
483
SymbolFileDWARF *
484
3.33k
SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
485
3.33k
  return GetSymbolFile(*sc.comp_unit);
486
3.33k
}
487
488
SymbolFileDWARF *
489
12.1k
SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) {
490
12.1k
  CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit);
491
12.1k
  if (comp_unit_info)
492
12.1k
    return GetSymbolFileByCompUnitInfo(comp_unit_info);
493
0
  return nullptr;
494
12.1k
}
495
496
ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
497
0
    CompileUnitInfo *comp_unit_info) {
498
0
  Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
499
0
  if (oso_module)
500
0
    return oso_module->GetObjectFile();
501
0
  return nullptr;
502
0
}
503
504
uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
505
1.81k
    const CompileUnitInfo *comp_unit_info) {
506
1.81k
  if (!m_compile_unit_infos.empty()) {
507
1.81k
    const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
508
1.81k
    const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
509
1.81k
    if (first_comp_unit_info <= comp_unit_info &&
510
1.81k
        comp_unit_info <= last_comp_unit_info)
511
1.81k
      return comp_unit_info - first_comp_unit_info;
512
1.81k
  }
513
0
  return UINT32_MAX;
514
1.81k
}
515
516
SymbolFileDWARF *
517
491k
SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
518
491k
  unsigned size = m_compile_unit_infos.size();
519
491k
  if (oso_idx < size)
520
491k
    return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
521
0
  return nullptr;
522
491k
}
523
524
SymbolFileDWARF *
525
551k
SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
526
551k
  if (sym_file &&
527
551k
      sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
528
551k
    return static_cast<SymbolFileDWARF *>(sym_file);
529
0
  return nullptr;
530
551k
}
531
532
SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
533
529k
    CompileUnitInfo *comp_unit_info) {
534
529k
  if (Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info))
535
529k
    return GetSymbolFileAsSymbolFileDWARF(oso_module->GetSymbolFile());
536
0
  return nullptr;
537
529k
}
538
539
132k
uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
540
  // In order to get the abilities of this plug-in, we look at the list of
541
  // N_OSO entries (object files) from the symbol table and make sure that
542
  // these files exist and also contain valid DWARF. If we get any of that then
543
  // we return the abilities of the first N_OSO's DWARF.
544
545
132k
  const uint32_t oso_index_count = GetNumCompileUnits();
546
132k
  if (oso_index_count > 0) {
547
1.50k
    InitOSO();
548
1.50k
    if (!m_compile_unit_infos.empty()) {
549
1.50k
      return SymbolFile::CompileUnits | SymbolFile::Functions |
550
1.50k
             SymbolFile::Blocks | SymbolFile::GlobalVariables |
551
1.50k
             SymbolFile::LocalVariables | SymbolFile::VariableTypes |
552
1.50k
             SymbolFile::LineTables;
553
1.50k
    }
554
1.50k
  }
555
130k
  return 0;
556
132k
}
557
558
132k
uint32_t SymbolFileDWARFDebugMap::CalculateNumCompileUnits() {
559
132k
  InitOSO();
560
132k
  return m_compile_unit_infos.size();
561
132k
}
562
563
1.63k
CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
564
1.63k
  CompUnitSP comp_unit_sp;
565
1.63k
  const uint32_t cu_count = GetNumCompileUnits();
566
567
1.63k
  if (cu_idx < cu_count) {
568
1.63k
    Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
569
1.63k
    if (oso_module) {
570
1.63k
      FileSpec so_file_spec;
571
1.63k
      if (GetFileSpecForSO(cu_idx, so_file_spec)) {
572
        // User zero as the ID to match the compile unit at offset zero in each
573
        // .o file since each .o file can only have one compile unit for now.
574
1.63k
        lldb::user_id_t cu_id = 0;
575
1.63k
        m_compile_unit_infos[cu_idx].compile_unit_sp =
576
1.63k
            std::make_shared<CompileUnit>(
577
1.63k
                m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id,
578
1.63k
                eLanguageTypeUnknown, eLazyBoolCalculate);
579
580
1.63k
        if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
581
1.63k
          SetCompileUnitAtIndex(cu_idx,
582
1.63k
                                m_compile_unit_infos[cu_idx].compile_unit_sp);
583
1.63k
        }
584
1.63k
      }
585
1.63k
    }
586
1.63k
    comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
587
1.63k
  }
588
589
1.63k
  return comp_unit_sp;
590
1.63k
}
591
592
SymbolFileDWARFDebugMap::CompileUnitInfo *
593
4
SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
594
4
  return GetCompUnitInfo(*sc.comp_unit);
595
4
}
596
597
SymbolFileDWARFDebugMap::CompileUnitInfo *
598
12.1k
SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) {
599
12.1k
  const uint32_t cu_count = GetNumCompileUnits();
600
13.3k
  for (uint32_t i = 0; i < cu_count; 
++i1.19k
) {
601
13.3k
    if (&comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
602
12.1k
      return &m_compile_unit_infos[i];
603
13.3k
  }
604
0
  return nullptr;
605
12.1k
}
606
607
size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
608
    const lldb_private::Module *module,
609
1.47k
    std::vector<CompileUnitInfo *> &cu_infos) {
610
1.47k
  const uint32_t cu_count = GetNumCompileUnits();
611
3.34k
  for (uint32_t i = 0; i < cu_count; 
++i1.86k
) {
612
1.86k
    if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i]))
613
1.47k
      cu_infos.push_back(&m_compile_unit_infos[i]);
614
1.86k
  }
615
1.47k
  return cu_infos.size();
616
1.47k
}
617
618
lldb::LanguageType
619
1.18k
SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
620
1.18k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
621
1.18k
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
622
1.18k
  if (oso_dwarf)
623
1.18k
    return oso_dwarf->ParseLanguage(comp_unit);
624
0
  return eLanguageTypeUnknown;
625
1.18k
}
626
627
0
XcodeSDK SymbolFileDWARFDebugMap::ParseXcodeSDK(CompileUnit &comp_unit) {
628
0
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
629
0
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
630
0
  if (oso_dwarf)
631
0
    return oso_dwarf->ParseXcodeSDK(comp_unit);
632
0
  return {};
633
0
}
634
635
8
size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
636
8
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
637
8
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
638
8
  if (oso_dwarf)
639
8
    return oso_dwarf->ParseFunctions(comp_unit);
640
0
  return 0;
641
8
}
642
643
1.35k
bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
644
1.35k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
645
1.35k
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
646
1.35k
  if (oso_dwarf)
647
1.35k
    return oso_dwarf->ParseLineTable(comp_unit);
648
0
  return false;
649
1.35k
}
650
651
678
bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
652
678
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
653
678
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
654
678
  if (oso_dwarf)
655
678
    return oso_dwarf->ParseDebugMacros(comp_unit);
656
0
  return false;
657
678
}
658
659
bool SymbolFileDWARFDebugMap::ForEachExternalModule(
660
    CompileUnit &comp_unit,
661
    llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
662
542
    llvm::function_ref<bool(Module &)> f) {
663
542
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
664
542
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
665
542
  if (oso_dwarf)
666
542
    return oso_dwarf->ForEachExternalModule(comp_unit, visited_symbol_files, f);
667
0
  return false;
668
542
}
669
670
bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
671
1.59k
                                                FileSpecList &support_files) {
672
1.59k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
673
1.59k
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
674
1.59k
  if (oso_dwarf)
675
1.59k
    return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
676
0
  return false;
677
1.59k
}
678
679
1.17k
bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
680
1.17k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
681
1.17k
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
682
1.17k
  if (oso_dwarf)
683
1.17k
    return oso_dwarf->ParseIsOptimized(comp_unit);
684
0
  return false;
685
1.17k
}
686
687
bool SymbolFileDWARFDebugMap::ParseImportedModules(
688
680
    const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
689
680
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
690
680
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
691
680
  if (oso_dwarf)
692
680
    return oso_dwarf->ParseImportedModules(sc, imported_modules);
693
0
  return false;
694
680
}
695
696
2.29k
size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
697
2.29k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
698
2.29k
  CompileUnit *comp_unit = func.GetCompileUnit();
699
2.29k
  if (!comp_unit)
700
0
    return 0;
701
702
2.29k
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit);
703
2.29k
  if (oso_dwarf)
704
2.29k
    return oso_dwarf->ParseBlocksRecursive(func);
705
0
  return 0;
706
2.29k
}
707
708
0
size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
709
0
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
710
0
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
711
0
  if (oso_dwarf)
712
0
    return oso_dwarf->ParseTypes(comp_unit);
713
0
  return 0;
714
0
}
715
716
size_t
717
2.65k
SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
718
2.65k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
719
2.65k
  SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
720
2.65k
  if (oso_dwarf)
721
2.65k
    return oso_dwarf->ParseVariablesForContext(sc);
722
0
  return 0;
723
2.65k
}
724
725
1.07k
Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
726
1.07k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
727
1.07k
  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
728
1.07k
  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
729
1.07k
  if (oso_dwarf)
730
1.07k
    return oso_dwarf->ResolveTypeUID(type_uid);
731
0
  return nullptr;
732
1.07k
}
733
734
llvm::Optional<SymbolFile::ArrayInfo>
735
SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID(
736
26
    lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
737
26
  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
738
26
  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
739
26
  if (oso_dwarf)
740
26
    return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
741
0
  return llvm::None;
742
26
}
743
744
30.4k
bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
745
30.4k
  bool success = false;
746
30.4k
  if (compiler_type) {
747
30.6k
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
748
30.6k
      if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) {
749
1.51k
        oso_dwarf->CompleteType(compiler_type);
750
1.51k
        success = true;
751
1.51k
        return true;
752
1.51k
      }
753
29.1k
      return false;
754
30.6k
    });
755
30.4k
  }
756
30.4k
  return success;
757
30.4k
}
758
759
uint32_t
760
SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
761
                                              SymbolContextItem resolve_scope,
762
42.8k
                                              SymbolContext &sc) {
763
42.8k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
764
42.8k
  uint32_t resolved_flags = 0;
765
42.8k
  Symtab *symtab = m_objfile_sp->GetSymtab();
766
42.8k
  if (symtab) {
767
42.8k
    const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
768
769
42.8k
    const DebugMap::Entry *debug_map_entry =
770
42.8k
        m_debug_map.FindEntryThatContains(exe_file_addr);
771
42.8k
    if (debug_map_entry) {
772
773
40.7k
      sc.symbol =
774
40.7k
          symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
775
776
40.7k
      if (sc.symbol != nullptr) {
777
40.7k
        resolved_flags |= eSymbolContextSymbol;
778
779
40.7k
        uint32_t oso_idx = 0;
780
40.7k
        CompileUnitInfo *comp_unit_info =
781
40.7k
            GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
782
40.7k
        if (comp_unit_info) {
783
40.7k
          comp_unit_info->GetFileRangeMap(this);
784
40.7k
          Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
785
40.7k
          if (oso_module) {
786
40.7k
            lldb::addr_t oso_file_addr =
787
40.7k
                exe_file_addr - debug_map_entry->GetRangeBase() +
788
40.7k
                debug_map_entry->data.GetOSOFileAddress();
789
40.7k
            Address oso_so_addr;
790
40.7k
            if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
791
40.7k
              resolved_flags |=
792
40.7k
                  oso_module->GetSymbolFile()->ResolveSymbolContext(
793
40.7k
                      oso_so_addr, resolve_scope, sc);
794
40.7k
            }
795
40.7k
          }
796
40.7k
        }
797
40.7k
      }
798
40.7k
    }
799
42.8k
  }
800
42.8k
  return resolved_flags;
801
42.8k
}
802
803
uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
804
    const SourceLocationSpec &src_location_spec,
805
0
    SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
806
0
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
807
0
  const uint32_t initial = sc_list.GetSize();
808
0
  const uint32_t cu_count = GetNumCompileUnits();
809
810
0
  for (uint32_t i = 0; i < cu_count; ++i) {
811
    // If we are checking for inlines, then we need to look through all compile
812
    // units no matter if "file_spec" matches.
813
0
    bool resolve = src_location_spec.GetCheckInlines();
814
815
0
    if (!resolve) {
816
0
      FileSpec so_file_spec;
817
0
      if (GetFileSpecForSO(i, so_file_spec))
818
0
        resolve =
819
0
            FileSpec::Match(src_location_spec.GetFileSpec(), so_file_spec);
820
0
    }
821
0
    if (resolve) {
822
0
      SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
823
0
      if (oso_dwarf)
824
0
        oso_dwarf->ResolveSymbolContext(src_location_spec, resolve_scope,
825
0
                                        sc_list);
826
0
    }
827
0
  }
828
0
  return sc_list.GetSize() - initial;
829
0
}
830
831
void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
832
    ConstString name, const CompilerDeclContext &parent_decl_ctx,
833
    const std::vector<uint32_t>
834
        &indexes, // Indexes into the symbol table that match "name"
835
0
    uint32_t max_matches, VariableList &variables) {
836
0
  const size_t match_count = indexes.size();
837
0
  for (size_t i = 0; i < match_count; ++i) {
838
0
    uint32_t oso_idx;
839
0
    CompileUnitInfo *comp_unit_info =
840
0
        GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx);
841
0
    if (comp_unit_info) {
842
0
      SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
843
0
      if (oso_dwarf) {
844
0
        oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
845
0
                                       variables);
846
0
        if (variables.GetSize() > max_matches)
847
0
          break;
848
0
      }
849
0
    }
850
0
  }
851
0
}
852
853
void SymbolFileDWARFDebugMap::FindGlobalVariables(
854
    ConstString name, const CompilerDeclContext &parent_decl_ctx,
855
2.60k
    uint32_t max_matches, VariableList &variables) {
856
2.60k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
857
2.60k
  uint32_t total_matches = 0;
858
859
2.90k
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
860
2.90k
    const uint32_t old_size = variables.GetSize();
861
2.90k
    oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
862
2.90k
                                   variables);
863
2.90k
    const uint32_t oso_matches = variables.GetSize() - old_size;
864
2.90k
    if (oso_matches > 0) {
865
327
      total_matches += oso_matches;
866
867
      // Are we getting all matches?
868
327
      if (max_matches == UINT32_MAX)
869
307
        return false; // Yep, continue getting everything
870
871
      // If we have found enough matches, lets get out
872
20
      if (max_matches >= total_matches)
873
20
        return true;
874
875
      // Update the max matches for any subsequent calls to find globals in any
876
      // other object files with DWARF
877
0
      max_matches -= oso_matches;
878
0
    }
879
880
2.57k
    return false;
881
2.90k
  });
882
2.60k
}
883
884
void SymbolFileDWARFDebugMap::FindGlobalVariables(
885
    const RegularExpression &regex, uint32_t max_matches,
886
0
    VariableList &variables) {
887
0
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
888
0
  uint32_t total_matches = 0;
889
0
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
890
0
    const uint32_t old_size = variables.GetSize();
891
0
    oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
892
893
0
    const uint32_t oso_matches = variables.GetSize() - old_size;
894
0
    if (oso_matches > 0) {
895
0
      total_matches += oso_matches;
896
897
      // Are we getting all matches?
898
0
      if (max_matches == UINT32_MAX)
899
0
        return false; // Yep, continue getting everything
900
901
      // If we have found enough matches, lets get out
902
0
      if (max_matches >= total_matches)
903
0
        return true;
904
905
      // Update the max matches for any subsequent calls to find globals in any
906
      // other object files with DWARF
907
0
      max_matches -= oso_matches;
908
0
    }
909
910
0
    return false;
911
0
  });
912
0
}
913
914
int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
915
42
    uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
916
42
  const uint32_t symbol_idx = *symbol_idx_ptr;
917
918
42
  if (symbol_idx < comp_unit_info->first_symbol_index)
919
12
    return -1;
920
921
30
  if (symbol_idx <= comp_unit_info->last_symbol_index)
922
30
    return 0;
923
924
0
  return 1;
925
30
}
926
927
int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID(
928
44.5k
    user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
929
44.5k
  const user_id_t symbol_id = *symbol_idx_ptr;
930
931
44.5k
  if (symbol_id < comp_unit_info->first_symbol_id)
932
3.45k
    return -1;
933
934
41.0k
  if (symbol_id <= comp_unit_info->last_symbol_id)
935
40.7k
    return 0;
936
937
289
  return 1;
938
41.0k
}
939
940
SymbolFileDWARFDebugMap::CompileUnitInfo *
941
SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
942
30
    uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
943
30
  const uint32_t oso_index_count = m_compile_unit_infos.size();
944
30
  CompileUnitInfo *comp_unit_info = nullptr;
945
30
  if (oso_index_count) {
946
30
    comp_unit_info = (CompileUnitInfo *)bsearch(
947
30
        &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
948
30
        sizeof(CompileUnitInfo),
949
30
        (ComparisonFunction)SymbolContainsSymbolWithIndex);
950
30
  }
951
952
30
  if (oso_idx_ptr) {
953
0
    if (comp_unit_info != nullptr)
954
0
      *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
955
0
    else
956
0
      *oso_idx_ptr = UINT32_MAX;
957
0
  }
958
30
  return comp_unit_info;
959
30
}
960
961
SymbolFileDWARFDebugMap::CompileUnitInfo *
962
SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
963
40.7k
    user_id_t symbol_id, uint32_t *oso_idx_ptr) {
964
40.7k
  const uint32_t oso_index_count = m_compile_unit_infos.size();
965
40.7k
  CompileUnitInfo *comp_unit_info = nullptr;
966
40.7k
  if (oso_index_count) {
967
40.7k
    comp_unit_info = (CompileUnitInfo *)::bsearch(
968
40.7k
        &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
969
40.7k
        sizeof(CompileUnitInfo),
970
40.7k
        (ComparisonFunction)SymbolContainsSymbolWithID);
971
40.7k
  }
972
973
40.7k
  if (oso_idx_ptr) {
974
40.7k
    if (comp_unit_info != nullptr)
975
40.7k
      *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
976
0
    else
977
0
      *oso_idx_ptr = UINT32_MAX;
978
40.7k
  }
979
40.7k
  return comp_unit_info;
980
40.7k
}
981
982
static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
983
                                                SymbolContextList &sc_list,
984
1.30k
                                                uint32_t start_idx) {
985
  // We found functions in .o files. Not all functions in the .o files will
986
  // have made it into the final output file. The ones that did make it into
987
  // the final output file will have a section whose module matches the module
988
  // from the ObjectFile for this SymbolFile. When the modules don't match,
989
  // then we have something that was in a .o file, but doesn't map to anything
990
  // in the final executable.
991
1.30k
  uint32_t i = start_idx;
992
2.63k
  while (i < sc_list.GetSize()) {
993
1.33k
    SymbolContext sc;
994
1.33k
    sc_list.GetContextAtIndex(i, sc);
995
1.33k
    if (sc.function) {
996
1.33k
      const SectionSP section_sp(
997
1.33k
          sc.function->GetAddressRange().GetBaseAddress().GetSection());
998
1.33k
      if (section_sp->GetModule() != module_sp) {
999
4
        sc_list.RemoveContextAtIndex(i);
1000
4
        continue;
1001
4
      }
1002
1.33k
    }
1003
1.32k
    ++i;
1004
1.32k
  }
1005
1.30k
}
1006
1007
void SymbolFileDWARFDebugMap::FindFunctions(
1008
    ConstString name, const CompilerDeclContext &parent_decl_ctx,
1009
    FunctionNameType name_type_mask, bool include_inlines,
1010
11.3k
    SymbolContextList &sc_list) {
1011
11.3k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1012
11.3k
  LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1013
11.3k
                     name.GetCString());
1014
1015
13.4k
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1016
13.4k
    uint32_t sc_idx = sc_list.GetSize();
1017
13.4k
    oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
1018
13.4k
                             include_inlines, sc_list);
1019
13.4k
    if (!sc_list.IsEmpty()) {
1020
1.28k
      RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
1021
1.28k
                                          sc_idx);
1022
1.28k
    }
1023
13.4k
    return false;
1024
13.4k
  });
1025
11.3k
}
1026
1027
void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
1028
                                            bool include_inlines,
1029
8
                                            SymbolContextList &sc_list) {
1030
8
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1031
8
  LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1032
8
                     regex.GetText().str().c_str());
1033
1034
20
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1035
20
    uint32_t sc_idx = sc_list.GetSize();
1036
1037
20
    oso_dwarf->FindFunctions(regex, include_inlines, sc_list);
1038
20
    if (!sc_list.IsEmpty()) {
1039
20
      RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
1040
20
                                          sc_idx);
1041
20
    }
1042
20
    return false;
1043
20
  });
1044
8
}
1045
1046
void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
1047
                                       lldb::TypeClass type_mask,
1048
4
                                       TypeList &type_list) {
1049
4
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1050
4
  LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1051
4
                     type_mask);
1052
1053
4
  SymbolFileDWARF *oso_dwarf = nullptr;
1054
4
  if (sc_scope) {
1055
4
    SymbolContext sc;
1056
4
    sc_scope->CalculateSymbolContext(&sc);
1057
1058
4
    CompileUnitInfo *cu_info = GetCompUnitInfo(sc);
1059
4
    if (cu_info) {
1060
4
      oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info);
1061
4
      if (oso_dwarf)
1062
4
        oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1063
4
    }
1064
4
  } else {
1065
0
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1066
0
      oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1067
0
      return false;
1068
0
    });
1069
0
  }
1070
4
}
1071
1072
std::vector<std::unique_ptr<lldb_private::CallEdge>>
1073
453
SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) {
1074
453
  uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID());
1075
453
  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1076
453
  if (oso_dwarf)
1077
453
    return oso_dwarf->ParseCallEdgesInFunction(func_id);
1078
0
  return {};
1079
453
}
1080
1081
TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
1082
927
    const DWARFDeclContext &die_decl_ctx) {
1083
927
  TypeSP type_sp;
1084
939
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1085
939
    type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
1086
939
    return ((bool)type_sp);
1087
939
  });
1088
927
  return type_sp;
1089
927
}
1090
1091
bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
1092
0
    SymbolFileDWARF *skip_dwarf_oso) {
1093
0
  if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
1094
0
    m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1095
0
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1096
0
      if (skip_dwarf_oso != oso_dwarf &&
1097
0
          oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) {
1098
0
        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1099
0
        return true;
1100
0
      }
1101
0
      return false;
1102
0
    });
1103
0
  }
1104
0
  return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1105
0
}
1106
1107
TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
1108
    const DWARFDIE &die, ConstString type_name,
1109
370
    bool must_be_implementation) {
1110
  // If we have a debug map, we will have an Objective-C symbol whose name is
1111
  // the type name and whose type is eSymbolTypeObjCClass. If we can find that
1112
  // symbol and find its containing parent, we can locate the .o file that will
1113
  // contain the implementation definition since it will be scoped inside the
1114
  // N_SO and we can then locate the SymbolFileDWARF that corresponds to that
1115
  // N_SO.
1116
370
  SymbolFileDWARF *oso_dwarf = nullptr;
1117
370
  TypeSP type_sp;
1118
370
  ObjectFile *module_objfile = m_objfile_sp->GetModule()->GetObjectFile();
1119
370
  if (module_objfile) {
1120
370
    Symtab *symtab = module_objfile->GetSymtab();
1121
370
    if (symtab) {
1122
370
      Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
1123
370
          type_name, eSymbolTypeObjCClass, Symtab::eDebugAny,
1124
370
          Symtab::eVisibilityAny);
1125
370
      if (objc_class_symbol) {
1126
        // Get the N_SO symbol that contains the objective C class symbol as
1127
        // this should be the .o file that contains the real definition...
1128
32
        const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
1129
1130
32
        if (source_file_symbol &&
1131
32
            
source_file_symbol->GetType() == eSymbolTypeSourceFile30
) {
1132
30
          const uint32_t source_file_symbol_idx =
1133
30
              symtab->GetIndexForSymbol(source_file_symbol);
1134
30
          if (source_file_symbol_idx != UINT32_MAX) {
1135
30
            CompileUnitInfo *compile_unit_info =
1136
30
                GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
1137
30
                                                     nullptr);
1138
30
            if (compile_unit_info) {
1139
30
              oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
1140
30
              if (oso_dwarf) {
1141
30
                TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
1142
30
                    die, type_name, must_be_implementation));
1143
30
                if (type_sp) {
1144
30
                  return type_sp;
1145
30
                }
1146
30
              }
1147
30
            }
1148
30
          }
1149
30
        }
1150
32
      }
1151
370
    }
1152
370
  }
1153
1154
  // Only search all .o files for the definition if we don't need the
1155
  // implementation because otherwise, with a valid debug map we should have
1156
  // the ObjC class symbol and the code above should have found it.
1157
340
  if (!must_be_implementation) {
1158
0
    TypeSP type_sp;
1159
1160
0
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1161
0
      type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
1162
0
          die, type_name, must_be_implementation);
1163
0
      return (bool)type_sp;
1164
0
    });
1165
1166
0
    return type_sp;
1167
0
  }
1168
340
  return TypeSP();
1169
340
}
1170
1171
void SymbolFileDWARFDebugMap::FindTypes(
1172
    ConstString name, const CompilerDeclContext &parent_decl_ctx,
1173
    uint32_t max_matches,
1174
    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1175
8.47k
    TypeMap &types) {
1176
8.47k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1177
8.94k
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1178
8.94k
    oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches,
1179
8.94k
                         searched_symbol_files, types);
1180
8.94k
    return types.GetSize() >= max_matches;
1181
8.94k
  });
1182
8.47k
}
1183
1184
void SymbolFileDWARFDebugMap::FindTypes(
1185
    llvm::ArrayRef<CompilerContext> context, LanguageSet languages,
1186
    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1187
0
    TypeMap &types) {
1188
0
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1189
0
    oso_dwarf->FindTypes(context, languages, searched_symbol_files, types);
1190
0
    return false;
1191
0
  });
1192
0
}
1193
1194
//
1195
// uint32_t
1196
// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const
1197
// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding
1198
// encoding, lldb::user_id_t udt_uid, TypeList& types)
1199
//{
1200
//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1201
//  if (oso_dwarf)
1202
//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding,
1203
//      udt_uid, types);
1204
//  return 0;
1205
//}
1206
1207
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
1208
    lldb_private::ConstString name,
1209
36.5k
    const CompilerDeclContext &parent_decl_ctx) {
1210
36.5k
  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1211
36.5k
  CompilerDeclContext matching_namespace;
1212
1213
36.9k
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1214
36.9k
    matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx);
1215
1216
36.9k
    return (bool)matching_namespace;
1217
36.9k
  });
1218
1219
36.5k
  return matching_namespace;
1220
36.5k
}
1221
1222
2
void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
1223
2
  ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool {
1224
2
    oso_dwarf->DumpClangAST(s);
1225
    // The underlying assumption is that DumpClangAST(...) will obtain the
1226
    // AST from the underlying TypeSystem and therefore we only need to do
1227
    // this once and can stop after the first iteration hence we return true.
1228
2
    return true;
1229
2
  });
1230
2
}
1231
1232
lldb::CompUnitSP
1233
302
SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) {
1234
302
  if (oso_dwarf) {
1235
302
    const uint32_t cu_count = GetNumCompileUnits();
1236
377
    for (uint32_t cu_idx = 0; cu_idx < cu_count; 
++cu_idx75
) {
1237
377
      SymbolFileDWARF *oso_symfile =
1238
377
          GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1239
377
      if (oso_symfile == oso_dwarf) {
1240
302
        if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1241
265
          m_compile_unit_infos[cu_idx].compile_unit_sp =
1242
265
              ParseCompileUnitAtIndex(cu_idx);
1243
1244
302
        return m_compile_unit_infos[cu_idx].compile_unit_sp;
1245
302
      }
1246
377
    }
1247
302
  }
1248
0
  llvm_unreachable("this shouldn't happen");
1249
0
}
1250
1251
SymbolFileDWARFDebugMap::CompileUnitInfo *
1252
23.8k
SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
1253
23.8k
  if (oso_dwarf) {
1254
23.8k
    const uint32_t cu_count = GetNumCompileUnits();
1255
25.0k
    for (uint32_t cu_idx = 0; cu_idx < cu_count; 
++cu_idx1.20k
) {
1256
25.0k
      SymbolFileDWARF *oso_symfile =
1257
25.0k
          GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1258
25.0k
      if (oso_symfile == oso_dwarf) {
1259
23.8k
        return &m_compile_unit_infos[cu_idx];
1260
23.8k
      }
1261
25.0k
    }
1262
23.8k
  }
1263
0
  return nullptr;
1264
23.8k
}
1265
1266
void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
1267
0
                                             const CompUnitSP &cu_sp) {
1268
0
  if (oso_dwarf) {
1269
0
    const uint32_t cu_count = GetNumCompileUnits();
1270
0
    for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1271
0
      SymbolFileDWARF *oso_symfile =
1272
0
          GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1273
0
      if (oso_symfile == oso_dwarf) {
1274
0
        if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
1275
0
          assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() ==
1276
0
                 cu_sp.get());
1277
0
        } else {
1278
0
          m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1279
0
          SetCompileUnitAtIndex(cu_idx, cu_sp);
1280
0
        }
1281
0
      }
1282
0
    }
1283
0
  }
1284
0
}
1285
1286
CompilerDeclContext
1287
24.3k
SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
1288
24.3k
  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1289
24.3k
  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1290
24.3k
  if (oso_dwarf)
1291
24.3k
    return oso_dwarf->GetDeclContextForUID(type_uid);
1292
0
  return CompilerDeclContext();
1293
24.3k
}
1294
1295
CompilerDeclContext
1296
0
SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
1297
0
  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1298
0
  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1299
0
  if (oso_dwarf)
1300
0
    return oso_dwarf->GetDeclContextContainingUID(type_uid);
1301
0
  return CompilerDeclContext();
1302
0
}
1303
1304
void SymbolFileDWARFDebugMap::ParseDeclsForContext(
1305
15.5k
    lldb_private::CompilerDeclContext decl_ctx) {
1306
15.5k
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1307
15.5k
    oso_dwarf->ParseDeclsForContext(decl_ctx);
1308
15.5k
    return true; // Keep iterating
1309
15.5k
  });
1310
15.5k
}
1311
1312
bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info,
1313
                                              lldb::addr_t exe_file_addr,
1314
                                              lldb::addr_t exe_byte_size,
1315
                                              lldb::addr_t oso_file_addr,
1316
40.2k
                                              lldb::addr_t oso_byte_size) {
1317
40.2k
  const uint32_t debug_map_idx =
1318
40.2k
      m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1319
40.2k
  if (debug_map_idx != UINT32_MAX) {
1320
40.2k
    DebugMap::Entry *debug_map_entry =
1321
40.2k
        m_debug_map.FindEntryThatContains(exe_file_addr);
1322
40.2k
    debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1323
40.2k
    addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
1324
40.2k
    if (range_size == 0) {
1325
0
      range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
1326
0
      if (range_size == 0)
1327
0
        range_size = 1;
1328
0
    }
1329
40.2k
    cu_info->file_range_map.Append(
1330
40.2k
        FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
1331
40.2k
    return true;
1332
40.2k
  }
1333
0
  return false;
1334
40.2k
}
1335
1336
1.47k
void SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) {
1337
1.47k
  cu_info->file_range_map.Sort();
1338
#if defined(DEBUG_OSO_DMAP)
1339
  const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1340
  const size_t n = oso_file_range_map.GetSize();
1341
  printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1342
         cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1343
  for (size_t i = 0; i < n; ++i) {
1344
    const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1345
    printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
1346
           ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1347
           entry.GetRangeBase(), entry.GetRangeEnd(), entry.data,
1348
           entry.data + entry.GetByteSize());
1349
  }
1350
#endif
1351
1.47k
}
1352
1353
lldb::addr_t
1354
SymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
1355
973
                                            lldb::addr_t oso_file_addr) {
1356
973
  CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile);
1357
973
  if (cu_info) {
1358
973
    const FileRangeMap::Entry *oso_range_entry =
1359
973
        cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1360
973
    if (oso_range_entry) {
1361
973
      const DebugMap::Entry *debug_map_entry =
1362
973
          m_debug_map.FindEntryThatContains(oso_range_entry->data);
1363
973
      if (debug_map_entry) {
1364
973
        const lldb::addr_t offset =
1365
973
            oso_file_addr - oso_range_entry->GetRangeBase();
1366
973
        const lldb::addr_t exe_file_addr =
1367
973
            debug_map_entry->GetRangeBase() + offset;
1368
973
        return exe_file_addr;
1369
973
      }
1370
973
    }
1371
973
  }
1372
0
  return LLDB_INVALID_ADDRESS;
1373
973
}
1374
1375
20.6k
bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
1376
  // Make sure this address hasn't been fixed already
1377
20.6k
  Module *exe_module = GetObjectFile()->GetModule().get();
1378
20.6k
  Module *addr_module = addr.GetModule().get();
1379
20.6k
  if (addr_module == exe_module)
1380
0
    return true; // Address is already in terms of the main executable module
1381
1382
20.6k
  CompileUnitInfo *cu_info = GetCompileUnitInfo(
1383
20.6k
      GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolFile()));
1384
20.6k
  if (cu_info) {
1385
20.6k
    const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1386
20.6k
    const FileRangeMap::Entry *oso_range_entry =
1387
20.6k
        cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1388
20.6k
    if (oso_range_entry) {
1389
20.6k
      const DebugMap::Entry *debug_map_entry =
1390
20.6k
          m_debug_map.FindEntryThatContains(oso_range_entry->data);
1391
20.6k
      if (debug_map_entry) {
1392
20.6k
        const lldb::addr_t offset =
1393
20.6k
            oso_file_addr - oso_range_entry->GetRangeBase();
1394
20.6k
        const lldb::addr_t exe_file_addr =
1395
20.6k
            debug_map_entry->GetRangeBase() + offset;
1396
20.6k
        return exe_module->ResolveFileAddress(exe_file_addr, addr);
1397
20.6k
      }
1398
20.6k
    }
1399
20.6k
  }
1400
2
  return true;
1401
20.6k
}
1402
1403
LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf,
1404
1.35k
                                                     LineTable *line_table) {
1405
1.35k
  CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf);
1406
1.35k
  if (cu_info)
1407
1.35k
    return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1408
0
  return nullptr;
1409
1.35k
}
1410
1411
size_t
1412
SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
1413
914
                                       DWARFDebugAranges *debug_aranges) {
1414
914
  size_t num_line_entries_added = 0;
1415
914
  if (debug_aranges && dwarf2Data) {
1416
914
    CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1417
914
    if (compile_unit_info) {
1418
914
      const FileRangeMap &file_range_map =
1419
914
          compile_unit_info->GetFileRangeMap(this);
1420
33.0k
      for (size_t idx = 0; idx < file_range_map.GetSize(); 
idx++32.1k
) {
1421
32.1k
        const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
1422
32.1k
        if (entry) {
1423
32.1k
          debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
1424
32.1k
                                     entry->GetRangeEnd());
1425
32.1k
          num_line_entries_added++;
1426
32.1k
        }
1427
32.1k
      }
1428
914
    }
1429
914
  }
1430
914
  return num_line_entries_added;
1431
914
}
1432
1433
2
uint64_t SymbolFileDWARFDebugMap::GetDebugInfoSize() {
1434
2
  uint64_t debug_info_size = 0;
1435
2
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1436
2
    ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
1437
2
    if (!oso_objfile)
1438
0
      return false; // Keep iterating
1439
2
    ModuleSP module_sp = oso_objfile->GetModule();
1440
2
    if (!module_sp)
1441
0
      return false; // Keep iterating
1442
2
    SectionList *section_list = module_sp->GetSectionList();
1443
2
    if (section_list)
1444
2
      debug_info_size += section_list->GetDebugInfoSize();
1445
2
    return false; // Keep iterating
1446
2
  });
1447
2
  return debug_info_size;
1448
2
}
1449
1450
2
StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() {
1451
2
  StatsDuration::Duration elapsed(0.0);
1452
2
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1453
2
    ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
1454
2
    if (oso_objfile) {
1455
2
      ModuleSP module_sp = oso_objfile->GetModule();
1456
2
      if (module_sp) {
1457
2
        SymbolFile *symfile = module_sp->GetSymbolFile();
1458
2
        if (symfile)
1459
2
          elapsed += symfile->GetDebugInfoParseTime();
1460
2
      }
1461
2
    }
1462
2
    return false; // Keep iterating
1463
2
  });
1464
2
  return elapsed;
1465
2
}
1466
1467
2
StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() {
1468
2
  StatsDuration::Duration elapsed(0.0);
1469
2
  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1470
2
    ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
1471
2
    if (oso_objfile) {
1472
2
      ModuleSP module_sp = oso_objfile->GetModule();
1473
2
      if (module_sp) {
1474
2
        SymbolFile *symfile = module_sp->GetSymbolFile();
1475
2
        if (symfile)
1476
2
          elapsed += symfile->GetDebugInfoIndexTime();
1477
2
      }
1478
2
    }
1479
2
    return false; // Keep iterating
1480
2
  });
1481
2
  return elapsed;
1482
2
}