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