Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/Section.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Section.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 "lldb/Core/Section.h"
10
#include "lldb/Core/Address.h"
11
#include "lldb/Core/Module.h"
12
#include "lldb/Symbol/ObjectFile.h"
13
#include "lldb/Target/SectionLoadList.h"
14
#include "lldb/Target/Target.h"
15
#include "lldb/Utility/FileSpec.h"
16
#include "lldb/Utility/VMRange.h"
17
18
#include <cinttypes>
19
#include <limits>
20
#include <utility>
21
22
namespace lldb_private {
23
class DataExtractor;
24
}
25
using namespace lldb;
26
using namespace lldb_private;
27
28
68.0k
const char *Section::GetTypeAsCString() const {
29
68.0k
  switch (m_type) {
30
0
  case eSectionTypeInvalid:
31
0
    return "invalid";
32
397
  case eSectionTypeCode:
33
397
    return "code";
34
440
  case eSectionTypeContainer:
35
440
    return "container";
36
98
  case eSectionTypeData:
37
98
    return "data";
38
183
  case eSectionTypeDataCString:
39
183
    return "data-cstr";
40
12
  case eSectionTypeDataCStringPointers:
41
12
    return "data-cstr-ptr";
42
0
  case eSectionTypeDataSymbolAddress:
43
0
    return "data-symbol-addr";
44
0
  case eSectionTypeData4:
45
0
    return "data-4-byte";
46
0
  case eSectionTypeData8:
47
0
    return "data-8-byte";
48
0
  case eSectionTypeData16:
49
0
    return "data-16-byte";
50
399
  case eSectionTypeDataPointers:
51
399
    return "data-ptrs";
52
18
  case eSectionTypeDebug:
53
18
    return "debug";
54
142
  case eSectionTypeZeroFill:
55
142
    return "zero-fill";
56
0
  case eSectionTypeDataObjCMessageRefs:
57
0
    return "objc-message-refs";
58
0
  case eSectionTypeDataObjCCFStrings:
59
0
    return "objc-cfstrings";
60
18
  case eSectionTypeDWARFDebugAbbrev:
61
18
    return "dwarf-abbrev";
62
1
  case eSectionTypeDWARFDebugAbbrevDwo:
63
1
    return "dwarf-abbrev-dwo";
64
3
  case eSectionTypeDWARFDebugAddr:
65
3
    return "dwarf-addr";
66
7
  case eSectionTypeDWARFDebugAranges:
67
7
    return "dwarf-aranges";
68
1
  case eSectionTypeDWARFDebugCuIndex:
69
1
    return "dwarf-cu-index";
70
1
  case eSectionTypeDWARFDebugTuIndex:
71
1
    return "dwarf-tu-index";
72
3
  case eSectionTypeDWARFDebugFrame:
73
3
    return "dwarf-frame";
74
20
  case eSectionTypeDWARFDebugInfo:
75
20
    return "dwarf-info";
76
1
  case eSectionTypeDWARFDebugInfoDwo:
77
1
    return "dwarf-info-dwo";
78
16
  case eSectionTypeDWARFDebugLine:
79
16
    return "dwarf-line";
80
2
  case eSectionTypeDWARFDebugLineStr:
81
2
    return "dwarf-line-str";
82
2
  case eSectionTypeDWARFDebugLoc:
83
2
    return "dwarf-loc";
84
2
  case eSectionTypeDWARFDebugLocDwo:
85
2
    return "dwarf-loc-dwo";
86
2
  case eSectionTypeDWARFDebugLocLists:
87
2
    return "dwarf-loclists";
88
2
  case eSectionTypeDWARFDebugLocListsDwo:
89
2
    return "dwarf-loclists-dwo";
90
1
  case eSectionTypeDWARFDebugMacInfo:
91
1
    return "dwarf-macinfo";
92
2
  case eSectionTypeDWARFDebugMacro:
93
2
    return "dwarf-macro";
94
1
  case eSectionTypeDWARFDebugPubNames:
95
1
    return "dwarf-pubnames";
96
1
  case eSectionTypeDWARFDebugPubTypes:
97
1
    return "dwarf-pubtypes";
98
3
  case eSectionTypeDWARFDebugRanges:
99
3
    return "dwarf-ranges";
100
2
  case eSectionTypeDWARFDebugRngLists:
101
2
    return "dwarf-rnglists";
102
2
  case eSectionTypeDWARFDebugRngListsDwo:
103
2
    return "dwarf-rnglists-dwo";
104
15
  case eSectionTypeDWARFDebugStr:
105
15
    return "dwarf-str";
106
1
  case eSectionTypeDWARFDebugStrDwo:
107
1
    return "dwarf-str-dwo";
108
1
  case eSectionTypeDWARFDebugStrOffsets:
109
1
    return "dwarf-str-offsets";
110
1
  case eSectionTypeDWARFDebugStrOffsetsDwo:
111
1
    return "dwarf-str-offsets-dwo";
112
3
  case eSectionTypeDWARFDebugTypes:
113
3
    return "dwarf-types";
114
2
  case eSectionTypeDWARFDebugTypesDwo:
115
2
    return "dwarf-types-dwo";
116
2
  case eSectionTypeDWARFDebugNames:
117
2
    return "dwarf-names";
118
12
  case eSectionTypeELFSymbolTable:
119
12
    return "elf-symbol-table";
120
1
  case eSectionTypeELFDynamicSymbols:
121
1
    return "elf-dynamic-symbols";
122
9
  case eSectionTypeELFRelocationEntries:
123
9
    return "elf-relocation-entries";
124
1
  case eSectionTypeELFDynamicLinkInfo:
125
1
    return "elf-dynamic-link-info";
126
8
  case eSectionTypeDWARFAppleNames:
127
8
    return "apple-names";
128
8
  case eSectionTypeDWARFAppleTypes:
129
8
    return "apple-types";
130
8
  case eSectionTypeDWARFAppleNamespaces:
131
8
    return "apple-namespaces";
132
8
  case eSectionTypeDWARFAppleObjC:
133
8
    return "apple-objc";
134
70
  case eSectionTypeEHFrame:
135
70
    return "eh-frame";
136
0
  case eSectionTypeARMexidx:
137
0
    return "ARM.exidx";
138
0
  case eSectionTypeARMextab:
139
0
    return "ARM.extab";
140
127
  case eSectionTypeCompactUnwind:
141
127
    return "compact-unwind";
142
0
  case eSectionTypeGoSymtab:
143
0
    return "go-symtab";
144
0
  case eSectionTypeAbsoluteAddress:
145
0
    return "absolute";
146
1
  case eSectionTypeDWARFGNUDebugAltLink:
147
1
    return "dwarf-gnu-debugaltlink";
148
66.0k
  case eSectionTypeOther:
149
66.0k
    return "regular";
150
68.0k
  }
151
0
  return "unknown";
152
68.0k
}
153
154
Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
155
                 user_id_t sect_id, ConstString name,
156
                 SectionType sect_type, addr_t file_addr, addr_t byte_size,
157
                 lldb::offset_t file_offset, lldb::offset_t file_size,
158
                 uint32_t log2align, uint32_t flags,
159
                 uint32_t target_byte_size /*=1*/)
160
    : ModuleChild(module_sp), UserID(sect_id), Flags(flags),
161
      m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
162
      m_file_addr(file_addr), m_byte_size(byte_size),
163
      m_file_offset(file_offset), m_file_size(file_size),
164
      m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
165
      m_thread_specific(false), m_readable(false), m_writable(false),
166
484k
      m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
167
  //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
168
  //    addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
169
  //    - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
170
  //            this, module_sp.get(), sect_id, file_addr, file_addr +
171
  //            byte_size, file_offset, file_offset + file_size, flags,
172
  //            name.GetCString());
173
484k
}
174
175
Section::Section(const lldb::SectionSP &parent_section_sp,
176
                 const ModuleSP &module_sp, ObjectFile *obj_file,
177
                 user_id_t sect_id, ConstString name,
178
                 SectionType sect_type, addr_t file_addr, addr_t byte_size,
179
                 lldb::offset_t file_offset, lldb::offset_t file_size,
180
                 uint32_t log2align, uint32_t flags,
181
                 uint32_t target_byte_size /*=1*/)
182
    : ModuleChild(module_sp), UserID(sect_id), Flags(flags),
183
      m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
184
      m_file_addr(file_addr), m_byte_size(byte_size),
185
      m_file_offset(file_offset), m_file_size(file_size),
186
      m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
187
      m_thread_specific(false), m_readable(false), m_writable(false),
188
2.11M
      m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
189
  //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
190
  //    addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
191
  //    - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
192
  //            this, module_sp.get(), sect_id, file_addr, file_addr +
193
  //            byte_size, file_offset, file_offset + file_size, flags,
194
  //            parent_section_sp->GetName().GetCString(), name.GetCString());
195
2.11M
  if (parent_section_sp)
196
2.03M
    m_parent_wp = parent_section_sp;
197
2.11M
}
198
199
2.51M
Section::~Section() {
200
  //    printf ("Section::~Section(%p)\n", this);
201
2.51M
}
202
203
1.47G
addr_t Section::GetFileAddress() const {
204
1.47G
  SectionSP parent_sp(GetParent());
205
1.47G
  if (parent_sp) {
206
    // This section has a parent which means m_file_addr is an offset into the
207
    // parent section, so the file address for this section is the file address
208
    // of the parent plus the offset
209
723M
    return parent_sp->GetFileAddress() + m_file_addr;
210
723M
  }
211
  // This section has no parent, so m_file_addr is the file base address
212
754M
  return m_file_addr;
213
1.47G
}
214
215
0
bool Section::SetFileAddress(lldb::addr_t file_addr) {
216
0
  SectionSP parent_sp(GetParent());
217
0
  if (parent_sp) {
218
0
    if (m_file_addr >= file_addr)
219
0
      return parent_sp->SetFileAddress(m_file_addr - file_addr);
220
0
    return false;
221
0
  } else {
222
    // This section has no parent, so m_file_addr is the file base address
223
0
    m_file_addr = file_addr;
224
0
    return true;
225
0
  }
226
0
}
227
228
5.47M
lldb::addr_t Section::GetOffset() const {
229
  // This section has a parent which means m_file_addr is an offset.
230
5.47M
  SectionSP parent_sp(GetParent());
231
5.47M
  if (parent_sp)
232
5.47M
    return m_file_addr;
233
234
  // This section has no parent, so there is no offset to be had
235
0
  return 0;
236
5.47M
}
237
238
9.39M
addr_t Section::GetLoadBaseAddress(Target *target) const {
239
9.39M
  addr_t load_base_addr = LLDB_INVALID_ADDRESS;
240
9.39M
  SectionSP parent_sp(GetParent());
241
9.39M
  if (parent_sp) {
242
4.69M
    load_base_addr = parent_sp->GetLoadBaseAddress(target);
243
4.69M
    if (load_base_addr != LLDB_INVALID_ADDRESS)
244
4.68M
      load_base_addr += GetOffset();
245
4.69M
  }
246
9.39M
  if (load_base_addr == LLDB_INVALID_ADDRESS) {
247
4.70M
    load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress(
248
4.70M
        const_cast<Section *>(this)->shared_from_this());
249
4.70M
  }
250
9.39M
  return load_base_addr;
251
9.39M
}
252
253
bool Section::ResolveContainedAddress(addr_t offset, Address &so_addr,
254
466k
                                      bool allow_section_end) const {
255
466k
  const size_t num_children = m_children.GetSize();
256
1.04M
  for (size_t i = 0; i < num_children; 
i++573k
) {
257
785k
    Section *child_section = m_children.GetSectionAtIndex(i).get();
258
259
785k
    addr_t child_offset = child_section->GetOffset();
260
785k
    if (child_offset <= offset &&
261
785k
        offset - child_offset <
262
769k
            child_section->GetByteSize() + (allow_section_end ? 
185.3k
:
0684k
))
263
212k
      return child_section->ResolveContainedAddress(offset - child_offset,
264
212k
                                                    so_addr, allow_section_end);
265
785k
  }
266
254k
  so_addr.SetOffset(offset);
267
254k
  so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
268
269
  // Ensure that there are no orphaned (i.e., moduleless) sections.
270
254k
  assert(GetModule().get());
271
0
  return true;
272
466k
}
273
274
101M
bool Section::ContainsFileAddress(addr_t vm_addr) const {
275
101M
  const addr_t file_addr = GetFileAddress();
276
101M
  if (file_addr != LLDB_INVALID_ADDRESS && !IsThreadSpecific()) {
277
101M
    if (file_addr <= vm_addr) {
278
101M
      const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
279
101M
      return offset < GetByteSize();
280
101M
    }
281
101M
  }
282
23.4k
  return false;
283
101M
}
284
285
void Section::Dump(llvm::raw_ostream &s, unsigned indent, Target *target,
286
2.29k
                   uint32_t depth) const {
287
2.29k
  s.indent(indent);
288
2.29k
  s << llvm::format("0x%8.8" PRIx64 " %-16s ", GetID(), GetTypeAsCString());
289
2.29k
  bool resolved = true;
290
2.29k
  addr_t addr = LLDB_INVALID_ADDRESS;
291
292
2.29k
  if (GetByteSize() == 0)
293
53
    s.indent(39);
294
2.23k
  else {
295
2.23k
    if (target)
296
138
      addr = GetLoadBaseAddress(target);
297
298
2.23k
    if (addr == LLDB_INVALID_ADDRESS) {
299
2.16k
      if (target)
300
60
        resolved = false;
301
2.16k
      addr = GetFileAddress();
302
2.16k
    }
303
304
2.23k
    VMRange range(addr, addr + m_byte_size);
305
2.23k
    range.Dump(s, 0);
306
2.23k
  }
307
308
2.29k
  s << llvm::format("%c %c%c%c  0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ",
309
2.29k
                    resolved ? 
' '2.23k
:
'*'60
, m_readable ?
'r'2.23k
:
'-'54
,
310
2.29k
                    m_writable ? 
'w'1.06k
:
'-'1.22k
, m_executable ?
'x'1.05k
:
'-'1.23k
,
311
2.29k
                    m_file_offset, m_file_size, Get());
312
313
2.29k
  DumpName(s);
314
315
2.29k
  s << "\n";
316
317
2.29k
  if (depth > 0)
318
2.29k
    m_children.Dump(s, indent, target, false, depth - 1);
319
2.29k
}
320
321
59.0k
void Section::DumpName(llvm::raw_ostream &s) const {
322
59.0k
  SectionSP parent_sp(GetParent());
323
59.0k
  if (parent_sp) {
324
29.2k
    parent_sp->DumpName(s);
325
29.2k
    s << '.';
326
29.7k
  } else {
327
    // The top most section prints the module basename
328
29.7k
    const char *name = nullptr;
329
29.7k
    ModuleSP module_sp(GetModule());
330
331
29.7k
    if (m_obj_file) {
332
29.7k
      const FileSpec &file_spec = m_obj_file->GetFileSpec();
333
29.7k
      name = file_spec.GetFilename().AsCString();
334
29.7k
    }
335
29.7k
    if ((!name || !name[0]) && 
module_sp0
)
336
0
      name = module_sp->GetFileSpec().GetFilename().AsCString();
337
29.7k
    if (name && name[0])
338
29.7k
      s << name << '.';
339
29.7k
  }
340
59.0k
  s << m_name;
341
59.0k
}
342
343
215M
bool Section::IsDescendant(const Section *section) {
344
215M
  if (this == section)
345
43.0M
    return true;
346
172M
  SectionSP parent_sp(GetParent());
347
172M
  if (parent_sp)
348
107M
    return parent_sp->IsDescendant(section);
349
64.7M
  return false;
350
172M
}
351
352
202
bool Section::Slide(addr_t slide_amount, bool slide_children) {
353
202
  if (m_file_addr != LLDB_INVALID_ADDRESS) {
354
202
    if (slide_amount == 0)
355
0
      return true;
356
357
202
    m_file_addr += slide_amount;
358
359
202
    if (slide_children)
360
0
      m_children.Slide(slide_amount, slide_children);
361
362
202
    return true;
363
202
  }
364
0
  return false;
365
202
}
366
367
/// Get the permissions as OR'ed bits from lldb::Permissions
368
87.6k
uint32_t Section::GetPermissions() const {
369
87.6k
  uint32_t permissions = 0;
370
87.6k
  if (m_readable)
371
21.9k
    permissions |= ePermissionsReadable;
372
87.6k
  if (m_writable)
373
197
    permissions |= ePermissionsWritable;
374
87.6k
  if (m_executable)
375
21.7k
    permissions |= ePermissionsExecutable;
376
87.6k
  return permissions;
377
87.6k
}
378
379
/// Set the permissions using bits OR'ed from lldb::Permissions
380
2.52M
void Section::SetPermissions(uint32_t permissions) {
381
2.52M
  m_readable = (permissions & ePermissionsReadable) != 0;
382
2.52M
  m_writable = (permissions & ePermissionsWritable) != 0;
383
2.52M
  m_executable = (permissions & ePermissionsExecutable) != 0;
384
2.52M
}
385
386
lldb::offset_t Section::GetSectionData(void *dst, lldb::offset_t dst_len,
387
0
                                       lldb::offset_t offset) {
388
0
  if (m_obj_file)
389
0
    return m_obj_file->ReadSectionData(this, offset, dst, dst_len);
390
0
  return 0;
391
0
}
392
393
43.5k
lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {
394
43.5k
  if (m_obj_file)
395
43.5k
    return m_obj_file->ReadSectionData(this, section_data);
396
0
  return 0;
397
43.5k
}
398
399
6.82k
bool Section::ContainsOnlyDebugInfo() const {
400
6.82k
  switch (m_type) {
401
48
  case eSectionTypeInvalid:
402
1.28k
  case eSectionTypeCode:
403
1.75k
  case eSectionTypeContainer:
404
2.04k
  case eSectionTypeData:
405
2.68k
  case eSectionTypeDataCString:
406
2.73k
  case eSectionTypeDataCStringPointers:
407
2.73k
  case eSectionTypeDataSymbolAddress:
408
2.73k
  case eSectionTypeData4:
409
2.73k
  case eSectionTypeData8:
410
2.73k
  case eSectionTypeData16:
411
4.13k
  case eSectionTypeDataPointers:
412
4.62k
  case eSectionTypeZeroFill:
413
4.62k
  case eSectionTypeDataObjCMessageRefs:
414
4.62k
  case eSectionTypeDataObjCCFStrings:
415
4.62k
  case eSectionTypeELFSymbolTable:
416
4.62k
  case eSectionTypeELFDynamicSymbols:
417
4.62k
  case eSectionTypeELFRelocationEntries:
418
4.62k
  case eSectionTypeELFDynamicLinkInfo:
419
4.87k
  case eSectionTypeEHFrame:
420
4.87k
  case eSectionTypeARMexidx:
421
4.87k
  case eSectionTypeARMextab:
422
5.29k
  case eSectionTypeCompactUnwind:
423
5.29k
  case eSectionTypeGoSymtab:
424
5.29k
  case eSectionTypeAbsoluteAddress:
425
6.57k
  case eSectionTypeOther:
426
6.57k
    return false;
427
428
66
  case eSectionTypeDebug:
429
93
  case eSectionTypeDWARFDebugAbbrev:
430
93
  case eSectionTypeDWARFDebugAbbrevDwo:
431
93
  case eSectionTypeDWARFDebugAddr:
432
102
  case eSectionTypeDWARFDebugAranges:
433
102
  case eSectionTypeDWARFDebugCuIndex:
434
102
  case eSectionTypeDWARFDebugTuIndex:
435
114
  case eSectionTypeDWARFDebugFrame:
436
141
  case eSectionTypeDWARFDebugInfo:
437
141
  case eSectionTypeDWARFDebugInfoDwo:
438
168
  case eSectionTypeDWARFDebugLine:
439
168
  case eSectionTypeDWARFDebugLineStr:
440
168
  case eSectionTypeDWARFDebugLoc:
441
168
  case eSectionTypeDWARFDebugLocDwo:
442
168
  case eSectionTypeDWARFDebugLocLists:
443
168
  case eSectionTypeDWARFDebugLocListsDwo:
444
168
  case eSectionTypeDWARFDebugMacInfo:
445
168
  case eSectionTypeDWARFDebugMacro:
446
168
  case eSectionTypeDWARFDebugPubNames:
447
168
  case eSectionTypeDWARFDebugPubTypes:
448
168
  case eSectionTypeDWARFDebugRanges:
449
168
  case eSectionTypeDWARFDebugRngLists:
450
168
  case eSectionTypeDWARFDebugRngListsDwo:
451
195
  case eSectionTypeDWARFDebugStr:
452
195
  case eSectionTypeDWARFDebugStrDwo:
453
195
  case eSectionTypeDWARFDebugStrOffsets:
454
195
  case eSectionTypeDWARFDebugStrOffsetsDwo:
455
195
  case eSectionTypeDWARFDebugTypes:
456
195
  case eSectionTypeDWARFDebugTypesDwo:
457
195
  case eSectionTypeDWARFDebugNames:
458
208
  case eSectionTypeDWARFAppleNames:
459
221
  case eSectionTypeDWARFAppleTypes:
460
234
  case eSectionTypeDWARFAppleNamespaces:
461
247
  case eSectionTypeDWARFAppleObjC:
462
247
  case eSectionTypeDWARFGNUDebugAltLink:
463
247
    return true;
464
6.82k
  }
465
0
  return false;
466
6.82k
}
467
468
469
#pragma mark SectionList
470
471
6.17k
SectionList &SectionList::operator=(const SectionList &rhs) {
472
6.17k
  if (this != &rhs)
473
6.17k
    m_sections = rhs.m_sections;
474
6.17k
  return *this;
475
6.17k
}
476
477
3.03M
size_t SectionList::AddSection(const lldb::SectionSP &section_sp) {
478
3.03M
  if (section_sp) {
479
3.03M
    size_t section_index = m_sections.size();
480
3.03M
    m_sections.push_back(section_sp);
481
3.03M
    return section_index;
482
3.03M
  }
483
484
0
  return std::numeric_limits<size_t>::max();
485
3.03M
}
486
487
// Warning, this can be slow as it's removing items from a std::vector.
488
0
bool SectionList::DeleteSection(size_t idx) {
489
0
  if (idx < m_sections.size()) {
490
0
    m_sections.erase(m_sections.begin() + idx);
491
0
    return true;
492
0
  }
493
0
  return false;
494
0
}
495
496
0
size_t SectionList::FindSectionIndex(const Section *sect) {
497
0
  iterator sect_iter;
498
0
  iterator begin = m_sections.begin();
499
0
  iterator end = m_sections.end();
500
0
  for (sect_iter = begin; sect_iter != end; ++sect_iter) {
501
0
    if (sect_iter->get() == sect) {
502
      // The secton was already in this section list
503
0
      return std::distance(begin, sect_iter);
504
0
    }
505
0
  }
506
0
  return UINT32_MAX;
507
0
}
508
509
0
size_t SectionList::AddUniqueSection(const lldb::SectionSP &sect_sp) {
510
0
  size_t sect_idx = FindSectionIndex(sect_sp.get());
511
0
  if (sect_idx == UINT32_MAX) {
512
0
    sect_idx = AddSection(sect_sp);
513
0
  }
514
0
  return sect_idx;
515
0
}
516
517
bool SectionList::ReplaceSection(user_id_t sect_id,
518
                                 const lldb::SectionSP &sect_sp,
519
41
                                 uint32_t depth) {
520
41
  iterator sect_iter, end = m_sections.end();
521
73
  for (sect_iter = m_sections.begin(); sect_iter != end; 
++sect_iter32
) {
522
41
    if ((*sect_iter)->GetID() == sect_id) {
523
9
      *sect_iter = sect_sp;
524
9
      return true;
525
32
    } else if (depth > 0) {
526
32
      if ((*sect_iter)
527
32
              ->GetChildren()
528
32
              .ReplaceSection(sect_id, sect_sp, depth - 1))
529
0
        return true;
530
32
    }
531
41
  }
532
32
  return false;
533
41
}
534
535
3.56M
size_t SectionList::GetNumSections(uint32_t depth) const {
536
3.56M
  size_t count = m_sections.size();
537
3.56M
  if (depth > 0) {
538
135k
    const_iterator sect_iter, end = m_sections.end();
539
550k
    for (sect_iter = m_sections.begin(); sect_iter != end; 
++sect_iter415k
) {
540
415k
      count += (*sect_iter)->GetChildren().GetNumSections(depth - 1);
541
415k
    }
542
135k
  }
543
3.56M
  return count;
544
3.56M
}
545
546
4.21M
SectionSP SectionList::GetSectionAtIndex(size_t idx) const {
547
4.21M
  SectionSP sect_sp;
548
4.21M
  if (idx < m_sections.size())
549
4.21M
    sect_sp = m_sections[idx];
550
4.21M
  return sect_sp;
551
4.21M
}
552
553
SectionSP
554
26.7M
SectionList::FindSectionByName(ConstString section_dstr) const {
555
26.7M
  SectionSP sect_sp;
556
  // Check if we have a valid section string
557
26.7M
  if (section_dstr && 
!m_sections.empty()26.7M
) {
558
4.95M
    const_iterator sect_iter;
559
4.95M
    const_iterator end = m_sections.end();
560
4.95M
    for (sect_iter = m_sections.begin();
561
30.5M
         sect_iter != end && 
sect_sp.get() == nullptr26.3M
;
++sect_iter25.6M
) {
562
25.6M
      Section *child_section = sect_iter->get();
563
25.6M
      if (child_section) {
564
25.6M
        if (child_section->GetName() == section_dstr) {
565
1.13M
          sect_sp = *sect_iter;
566
24.4M
        } else {
567
24.4M
          sect_sp =
568
24.4M
              child_section->GetChildren().FindSectionByName(section_dstr);
569
24.4M
        }
570
25.6M
      }
571
25.6M
    }
572
4.95M
  }
573
26.7M
  return sect_sp;
574
26.7M
}
575
576
10.3M
SectionSP SectionList::FindSectionByID(user_id_t sect_id) const {
577
10.3M
  SectionSP sect_sp;
578
10.3M
  if (sect_id) {
579
10.3M
    const_iterator sect_iter;
580
10.3M
    const_iterator end = m_sections.end();
581
10.3M
    for (sect_iter = m_sections.begin();
582
19.8M
         sect_iter != end && 
sect_sp.get() == nullptr11.0M
;
++sect_iter9.52M
) {
583
10.3M
      if ((*sect_iter)->GetID() == sect_id) {
584
800k
        sect_sp = *sect_iter;
585
800k
        break;
586
9.52M
      } else {
587
9.52M
        sect_sp = (*sect_iter)->GetChildren().FindSectionByID(sect_id);
588
9.52M
      }
589
10.3M
    }
590
10.3M
  }
591
10.3M
  return sect_sp;
592
10.3M
}
593
594
SectionSP SectionList::FindSectionByType(SectionType sect_type,
595
                                         bool check_children,
596
5.17M
                                         size_t start_idx) const {
597
5.17M
  SectionSP sect_sp;
598
5.17M
  size_t num_sections = m_sections.size();
599
9.94M
  for (size_t idx = start_idx; idx < num_sections; 
++idx4.77M
) {
600
4.97M
    if (m_sections[idx]->GetType() == sect_type) {
601
129k
      sect_sp = m_sections[idx];
602
129k
      break;
603
4.84M
    } else if (check_children) {
604
4.84M
      sect_sp = m_sections[idx]->GetChildren().FindSectionByType(
605
4.84M
          sect_type, check_children, 0);
606
4.84M
      if (sect_sp)
607
71.6k
        break;
608
4.84M
    }
609
4.97M
  }
610
5.17M
  return sect_sp;
611
5.17M
}
612
613
SectionSP SectionList::FindSectionContainingFileAddress(addr_t vm_addr,
614
85.6M
                                                        uint32_t depth) const {
615
85.6M
  SectionSP sect_sp;
616
85.6M
  const_iterator sect_iter;
617
85.6M
  const_iterator end = m_sections.end();
618
85.6M
  for (sect_iter = m_sections.begin();
619
158M
       sect_iter != end && 
sect_sp.get() == nullptr130M
;
++sect_iter73.0M
) {
620
73.0M
    Section *sect = sect_iter->get();
621
73.0M
    if (sect->ContainsFileAddress(vm_addr)) {
622
      // The file address is in this section. We need to make sure one of our
623
      // child sections doesn't contain this address as well as obeying the
624
      // depth limit that was passed in.
625
57.0M
      if (depth > 0)
626
57.0M
        sect_sp = sect->GetChildren().FindSectionContainingFileAddress(
627
57.0M
            vm_addr, depth - 1);
628
629
57.0M
      if (sect_sp.get() == nullptr && 
!sect->IsFake()28.5M
)
630
28.5M
        sect_sp = *sect_iter;
631
57.0M
    }
632
73.0M
  }
633
85.6M
  return sect_sp;
634
85.6M
}
635
636
0
bool SectionList::ContainsSection(user_id_t sect_id) const {
637
0
  return FindSectionByID(sect_id).get() != nullptr;
638
0
}
639
640
void SectionList::Dump(llvm::raw_ostream &s, unsigned indent, Target *target,
641
2.43k
                       bool show_header, uint32_t depth) const {
642
2.43k
  bool target_has_loaded_sections =
643
2.43k
      target && 
!target->GetSectionLoadList().IsEmpty()145
;
644
2.43k
  if (show_header && 
!m_sections.empty()139
) {
645
139
    s.indent(indent);
646
139
    s << llvm::formatv(
647
139
        "SectID     Type             {0} Address                          "
648
139
        "   Perm File Off.  File Size  Flags "
649
139
        "     Section Name\n",
650
139
        target_has_loaded_sections ? 
"Load"6
:
"File"133
);
651
139
    s.indent(indent);
652
139
    s << "---------- ---------------- "
653
139
         "---------------------------------------  ---- ---------- "
654
139
         "---------- "
655
139
         "---------- ----------------------------\n";
656
139
  }
657
658
2.43k
  for (const auto &section_sp : m_sections)
659
2.29k
    section_sp->Dump(s, indent, target_has_loaded_sections ? 
target138
:
nullptr2.15k
,
660
2.29k
                     depth);
661
2.43k
}
662
663
101
size_t SectionList::Slide(addr_t slide_amount, bool slide_children) {
664
101
  size_t count = 0;
665
101
  const_iterator pos, end = m_sections.end();
666
202
  for (pos = m_sections.begin(); pos != end; 
++pos101
) {
667
101
    if ((*pos)->Slide(slide_amount, slide_children))
668
101
      ++count;
669
101
  }
670
101
  return count;
671
101
}
672
673
1.34k
uint64_t SectionList::GetDebugInfoSize() const {
674
1.34k
  uint64_t debug_info_size = 0;
675
7.71k
  for (const auto &section : m_sections) {
676
7.71k
    const SectionList &sub_sections = section->GetChildren();
677
7.71k
    if (sub_sections.GetSize() > 0)
678
890
      debug_info_size += sub_sections.GetDebugInfoSize();
679
6.82k
    else if (section->ContainsOnlyDebugInfo())
680
247
      debug_info_size += section->GetFileSize();
681
7.71k
  }
682
1.34k
  return debug_info_size;
683
1.34k
}