LLVM 18.0.0git
OutputSections.cpp
Go to the documentation of this file.
1//=== OutputSections.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 "OutputSections.h"
11#include "DWARFLinkerTypeUnit.h"
13
14namespace llvm {
15namespace dwarflinker_parallel {
16
18 "debug_info", "debug_line", "debug_frame", "debug_ranges",
19 "debug_rnglists", "debug_loc", "debug_loclists", "debug_aranges",
20 "debug_abbrev", "debug_macinfo", "debug_macro", "debug_addr",
21 "debug_str", "debug_line_str", "debug_str_offsets", "debug_pubnames",
22 "debug_pubtypes", "debug_names", "apple_names", "apple_namespac",
23 "apple_objc", "apple_types"};
24
26 return SectionNames[static_cast<uint8_t>(SectionKind)];
27}
28
29std::optional<DebugSectionKind> parseDebugTableName(llvm::StringRef SecName) {
31 SecName.substr(SecName.find_first_not_of("._")))
76 .Default(std::nullopt);
77
78 return std::nullopt;
79}
80
82 CompileUnit *RefCU, uint32_t RefIdx)
84 RefCU(RefCU, (SrcCU != nullptr) &&
85 (SrcCU->getUniqueID() == RefCU->getUniqueID())),
86 RefDieIdxOrClonedOffset(RefIdx) {}
87
89 CompileUnit *SrcCU,
90 CompileUnit *RefCU,
91 uint32_t RefIdx)
93 RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()),
94 RefDieIdxOrClonedOffset(RefIdx) {}
95
97 TypeEntry *RefTypeName)
98 : SectionPatch({PatchOffset}), RefTypeName(RefTypeName) {}
99
101 DIE *Die,
102 TypeEntry *TypeName,
103 TypeEntry *RefTypeName)
104 : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
105 RefTypeName(RefTypeName) {}
106
108 TypeEntry *TypeName, StringEntry *String)
109 : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
110 String(String) {}
111
113 TypeEntry *TypeName,
115 : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
116 String(String) {}
117
119 StringEntry *Directory,
120 StringEntry *FilePath)
121 : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {}
122
124 StartOffset = 0;
126 ListDebugStrPatch.erase();
127 ListDebugLineStrPatch.erase();
128 ListDebugRangePatch.erase();
129 ListDebugLocPatch.erase();
130 ListDebugDieRefPatch.erase();
131 ListDebugULEB128DieRefPatch.erase();
132 ListDebugOffsetPatch.erase();
133 ListDebugType2TypeDieRefPatch.erase();
134 ListDebugTypeDeclFilePatch.erase();
135 ListDebugTypeLineStrPatch.erase();
136 ListDebugTypeStrPatch.erase();
137}
138
140
142 if (Contents.empty())
143 return;
144
145 MemoryBufferRef Mem(Contents, "obj");
148 if (!Obj) {
149 consumeError(Obj.takeError());
150 Contents.clear();
151 return;
152 }
153
154 for (const object::SectionRef &Sect : (*Obj).get()->sections()) {
155 Expected<StringRef> SectNameOrErr = Sect.getName();
156 if (!SectNameOrErr) {
157 consumeError(SectNameOrErr.takeError());
158 continue;
159 }
160 if (std::optional<DebugSectionKind> SectKind =
161 parseDebugTableName(*SectNameOrErr)) {
162 if (*SectKind == SectionKind) {
163 Expected<StringRef> Data = Sect.getContents();
164 if (!Data) {
165 consumeError(SectNameOrErr.takeError());
166 Contents.clear();
167 return;
168 }
169
171 Data->data() - Contents.data();
174 }
175 }
176 }
177}
178
180 const char *StringVal) {
181 assert(StringVal != nullptr);
182
183 switch (StringForm) {
184 case dwarf::DW_FORM_string: {
185 emitInplaceString(StringVal);
186 } break;
187 case dwarf::DW_FORM_strp: {
188 notePatch(DebugStrPatch{
189 {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first});
191 } break;
192 case dwarf::DW_FORM_line_strp: {
193 notePatch(DebugLineStrPatch{
194 {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first});
196 } break;
197 default:
198 llvm_unreachable("Unsupported string form");
199 break;
200 };
201}
202
204 switch (Size) {
205 case 1: {
206 OS.write(static_cast<uint8_t>(Val));
207 } break;
208 case 2: {
209 uint16_t ShortVal = static_cast<uint16_t>(Val);
211 sys::swapByteOrder(ShortVal);
212 OS.write(reinterpret_cast<const char *>(&ShortVal), Size);
213 } break;
214 case 4: {
215 uint32_t ShortVal = static_cast<uint32_t>(Val);
217 sys::swapByteOrder(ShortVal);
218 OS.write(reinterpret_cast<const char *>(&ShortVal), Size);
219 } break;
220 case 8: {
223 OS.write(reinterpret_cast<const char *>(&Val), Size);
224 } break;
225 default:
226 llvm_unreachable("Unsupported integer type size");
227 }
228}
229
231 uint64_t Val) {
232 switch (AttrForm) {
233 case dwarf::DW_FORM_strp:
234 case dwarf::DW_FORM_line_strp: {
235 applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize());
236 } break;
237
238 case dwarf::DW_FORM_ref_addr: {
239 applyIntVal(PatchOffset, Val, Format.getRefAddrByteSize());
240 } break;
241 case dwarf::DW_FORM_ref1: {
242 applyIntVal(PatchOffset, Val, 1);
243 } break;
244 case dwarf::DW_FORM_ref2: {
245 applyIntVal(PatchOffset, Val, 2);
246 } break;
247 case dwarf::DW_FORM_ref4: {
248 applyIntVal(PatchOffset, Val, 4);
249 } break;
250 case dwarf::DW_FORM_ref8: {
251 applyIntVal(PatchOffset, Val, 8);
252 } break;
253
254 case dwarf::DW_FORM_data1: {
255 applyIntVal(PatchOffset, Val, 1);
256 } break;
257 case dwarf::DW_FORM_data2: {
258 applyIntVal(PatchOffset, Val, 2);
259 } break;
260 case dwarf::DW_FORM_data4: {
261 applyIntVal(PatchOffset, Val, 4);
262 } break;
263 case dwarf::DW_FORM_data8: {
264 applyIntVal(PatchOffset, Val, 8);
265 } break;
266 case dwarf::DW_FORM_udata: {
267 applyULEB128(PatchOffset, Val);
268 } break;
269 case dwarf::DW_FORM_sdata: {
270 applySLEB128(PatchOffset, Val);
271 } break;
272 case dwarf::DW_FORM_sec_offset: {
273 applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize());
274 } break;
275 case dwarf::DW_FORM_flag: {
276 applyIntVal(PatchOffset, Val, 1);
277 } break;
278
279 default:
280 llvm_unreachable("Unsupported attribute form");
281 break;
282 }
283}
284
286 assert(PatchOffset < getContents().size());
287 switch (Size) {
288 case 1: {
289 return *reinterpret_cast<const uint8_t *>(
290 (getContents().data() + PatchOffset));
291 }
292 case 2: {
293 return support::endian::read16(getContents().data() + PatchOffset,
294 Endianess);
295 }
296 case 4: {
297 return support::endian::read32(getContents().data() + PatchOffset,
298 Endianess);
299 }
300 case 8: {
301 return support::endian::read64(getContents().data() + PatchOffset,
302 Endianess);
303 }
304 }
305 llvm_unreachable("Unsupported integer type size");
306 return 0;
307}
308
310 unsigned Size) {
311 assert(PatchOffset < getContents().size());
312
313 switch (Size) {
314 case 1: {
316 const_cast<char *>(getContents().data() + PatchOffset),
317 static_cast<uint8_t>(Val), Endianess);
318 } break;
319 case 2: {
321 const_cast<char *>(getContents().data() + PatchOffset),
322 static_cast<uint16_t>(Val), Endianess);
323 } break;
324 case 4: {
326 const_cast<char *>(getContents().data() + PatchOffset),
327 static_cast<uint32_t>(Val), Endianess);
328 } break;
329 case 8: {
331 const_cast<char *>(getContents().data() + PatchOffset),
332 static_cast<uint64_t>(Val), Endianess);
333 } break;
334 default:
335 llvm_unreachable("Unsupported integer type size");
336 }
337}
338
340 assert(PatchOffset < getContents().size());
341
342 uint8_t ULEB[16];
343 uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1;
344 uint8_t RealSize = encodeULEB128(Val, ULEB, DestSize);
345
346 memcpy(const_cast<char *>(getContents().data() + PatchOffset), ULEB,
347 RealSize);
348}
349
350/// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
352 assert(PatchOffset < getContents().size());
353
354 uint8_t SLEB[16];
355 uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1;
356 uint8_t RealSize = encodeSLEB128(Val, SLEB, DestSize);
357
358 memcpy(const_cast<char *>(getContents().data() + PatchOffset), SLEB,
359 RealSize);
360}
361
363 SectionDescriptor &Section,
365 StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings,
366 TypeUnit *TypeUnitPtr) {
367 Section.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
369 DebugStrStrings.getExistingEntry(Patch.String);
370 assert(Entry != nullptr);
371
372 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
373 });
374 Section.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) {
375 assert(TypeUnitPtr != nullptr);
376 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
378 formatv("No data for type {0}", Patch.TypeName->getKey())
379 .str()
380 .c_str());
381
382 if (&TypeEntry->getFinalDie() != Patch.Die)
383 return;
384
386 DebugStrStrings.getExistingEntry(Patch.String);
387 assert(Entry != nullptr);
388
389 Patch.PatchOffset +=
390 Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber());
391
392 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
393 });
394
395 Section.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
397 DebugLineStrStrings.getExistingEntry(Patch.String);
398 assert(Entry != nullptr);
399
400 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
401 });
402 Section.ListDebugTypeLineStrPatch.forEach([&](DebugTypeLineStrPatch &Patch) {
403 assert(TypeUnitPtr != nullptr);
404 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
406 formatv("No data for type {0}", Patch.TypeName->getKey())
407 .str()
408 .c_str());
409
410 if (&TypeEntry->getFinalDie() != Patch.Die)
411 return;
412
414 DebugLineStrStrings.getExistingEntry(Patch.String);
415 assert(Entry != nullptr);
416
417 Patch.PatchOffset +=
418 Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber());
419
420 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
421 });
422
423 std::optional<SectionDescriptor *> RangeSection;
424 if (Format.Version >= 5)
426 else
428
429 if (RangeSection) {
430 Section.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
431 uint64_t FinalValue =
432 Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
433 FinalValue += (*RangeSection)->StartOffset;
434
435 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
436 });
437 }
438
439 std::optional<SectionDescriptor *> LocationSection;
440 if (Format.Version >= 5)
442 else
444
445 if (LocationSection) {
446 Section.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
447 uint64_t FinalValue =
448 Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
449 FinalValue += (*LocationSection)->StartOffset;
450
451 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
452 });
453 }
454
455 Section.ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {
456 uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset;
457 dwarf::Form FinalForm = dwarf::DW_FORM_ref4;
458
459 // Check whether it is local or inter-CU reference.
460 if (!Patch.RefCU.getInt()) {
461 SectionDescriptor &ReferencedSectionDescriptor =
462 Patch.RefCU.getPointer()->getSectionDescriptor(
463 DebugSectionKind::DebugInfo);
464
465 FinalForm = dwarf::DW_FORM_ref_addr;
466 FinalOffset += ReferencedSectionDescriptor.StartOffset;
467 }
468
469 Section.apply(Patch.PatchOffset, FinalForm, FinalOffset);
470 });
471
472 Section.ListDebugULEB128DieRefPatch.forEach(
473 [&](DebugULEB128DieRefPatch &Patch) {
474 assert(Patch.RefCU.getInt());
475 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_udata,
476 Patch.RefDieIdxOrClonedOffset);
477 });
478
479 Section.ListDebugDieTypeRefPatch.forEach([&](DebugDieTypeRefPatch &Patch) {
480 assert(TypeUnitPtr != nullptr);
481 assert(Patch.RefTypeName != nullptr);
482
483 TypeEntryBody *TypeEntry = Patch.RefTypeName->getValue().load();
485 formatv("No data for type {0}", Patch.RefTypeName->getKey())
486 .str()
487 .c_str());
488
489 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref_addr,
490 TypeEntry->getFinalDie().getOffset());
491 });
492
493 Section.ListDebugType2TypeDieRefPatch.forEach(
494 [&](DebugType2TypeDieRefPatch &Patch) {
495 assert(TypeUnitPtr != nullptr);
496 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
498 formatv("No data for type {0}", Patch.TypeName->getKey())
499 .str()
500 .c_str());
501
502 if (&TypeEntry->getFinalDie() != Patch.Die)
503 return;
504
505 Patch.PatchOffset += Patch.Die->getOffset() +
506 getULEB128Size(Patch.Die->getAbbrevNumber());
507
508 assert(Patch.RefTypeName != nullptr);
509 TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load();
511 formatv("No data for type {0}", Patch.RefTypeName->getKey())
512 .str()
513 .c_str());
514
515 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref4,
516 RefTypeEntry->getFinalDie().getOffset());
517 });
518
519 Section.ListDebugOffsetPatch.forEach([&](DebugOffsetPatch &Patch) {
520 uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset;
521
522 // Check whether we need to read value from the original location.
523 if (Patch.SectionPtr.getInt())
524 FinalValue +=
525 Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
526
527 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
528 });
529}
530
531} // end of namespace dwarflinker_parallel
532} // end of namespace llvm
uint64_t Size
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
A structured debug information entry.
Definition: DIE.h:819
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:857
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
bool empty() const
Definition: SmallVector.h:94
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:289
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:857
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:575
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition: StringRef.cpp:251
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
Stores all information related to a compile unit, be it in its original instance of the object file o...
StringPool & getStringPool()
Returns global string pool.
void applyPatches(SectionDescriptor &Section, StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, TypeUnit *TypeUnitPtr)
Enumerate all sections, for each section apply all section patches.
dwarf::FormParams Format
Format for sections.
std::optional< const SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
This class creates a DwarfStringPoolEntry for the corresponding StringEntry.
DwarfStringPoolEntryWithExtString * getExistingEntry(const StringEntry *String) const
Returns already existed DwarfStringPoolEntry for the specified StringEntry.
Keeps cloned data for the type DIE.
Definition: TypePool.h:29
DIE & getFinalDie() const
Returns copy of type DIE which should be emitted into resulting file.
Definition: TypePool.h:32
Type Unit is used to represent an artificial compilation unit which keeps all type information.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:200
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:134
raw_ostream & write(unsigned char C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static constexpr StringLiteral SectionNames[SectionKindsNum]
std::optional< DebugSectionKind > parseDebugTableName(llvm::StringRef SecName)
Recognise the table name and match it with the DebugSectionKind.
DebugSectionKind
List of tracked debug tables.
SmallString< 0 > OutSectionDataTy
Type for section data.
static constexpr size_t SectionKindsNum
const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
uint32_t read32(const void *P, endianness E)
Definition: Endian.h:389
uint64_t read64(const void *P, endianness E)
Definition: Endian.h:392
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:91
uint16_t read16(const void *P, endianness E)
Definition: Endian.h:386
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:61
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1684
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
@ Default
The result values are uniform if and only if all operands are uniform.
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1041
DwarfStringPoolEntry with string keeping externally.
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:761
uint8_t getRefAddrByteSize() const
The definition of the size of form DW_FORM_ref_addr depends on the version.
Definition: Dwarf.h:754
This structure is used to update reference to the DIE.
DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, uint32_t RefIdx)
This structure is used to update reference to the type DIE.
DebugDieTypeRefPatch(uint64_t PatchOffset, TypeEntry *RefTypeName)
This structure is used to update strings offsets into .debug_line_str.
This structure is used to update location list offset into .debug_loc/.debug_loclists.
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
This structure is used to update strings offsets into .debug_str.
This structure is used to update reference to the type DIE.
DebugType2TypeDieRefPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, TypeEntry *RefTypeName)
DebugTypeDeclFilePatch(DIE *Die, TypeEntry *TypeName, StringEntry *Directory, StringEntry *FilePath)
DebugTypeLineStrPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, StringEntry *String)
DebugTypeStrPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, StringEntry *String)
This structure is used to update reference to the DIE of ULEB128 form.
DebugULEB128DieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, uint32_t RefIdx)
This structure is used to keep data of the concrete section.
void clearSectionContent()
Erase only section output data bits.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
void emitInplaceString(StringRef String)
Emit specified inplace string value into the current section contents.
void emitString(dwarf::Form StringForm, const char *StringVal)
void applySLEB128(uint64_t PatchOffset, uint64_t Val)
Writes integer value Val of SLEB128 format by specified PatchOffset.
void applyULEB128(uint64_t PatchOffset, uint64_t Val)
Writes integer value Val of ULEB128 format by specified PatchOffset.
OutSectionDataTy Contents
Section data bits.
raw_svector_ostream OS
Stream which stores data to the Contents.
dwarf::FormParams Format
Output format.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
size_t SectionOffsetInsideAsmPrinterOutputStart
Some sections are generated using AsmPrinter.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size)
Writes integer value Val of Size by specified PatchOffset.
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.
StringRef getContents()
Returns section content.
void clearAllSectionData()
Erase whole section contents(data bits, list of patches).
void emitStringPlaceholder()
Emit string placeholder into the current section contents.
There are fields(sizes, offsets) which should be updated after sections are generated.