LLVM 20.0.0git
OutputSections.h
Go to the documentation of this file.
1//===- OutputSections.h -----------------------------------------*- C++ -*-===//
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#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
10#define LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
11
12#include "ArrayList.h"
15#include "llvm/ADT/StringRef.h"
22#include "llvm/Support/Endian.h"
23#include "llvm/Support/Error.h"
25#include "llvm/Support/LEB128.h"
28#include <array>
29#include <cstdint>
30
31namespace llvm {
32namespace dwarf_linker {
33namespace parallel {
34
35class TypeUnit;
36
37/// There are fields(sizes, offsets) which should be updated after
38/// sections are generated. To remember offsets and related data
39/// the descendants of SectionPatch structure should be used.
40
43};
44
45/// This structure is used to update strings offsets into .debug_str.
47 const StringEntry *String = nullptr;
48};
49
50/// This structure is used to update strings offsets into .debug_line_str.
52 const StringEntry *String = nullptr;
53};
54
55/// This structure is used to update range list offset into
56/// .debug_ranges/.debug_rnglists.
58 /// Indicates patch which points to immediate compile unit's attribute.
59 bool IsCompileUnitRanges = false;
60};
61
62/// This structure is used to update location list offset into
63/// .debug_loc/.debug_loclists.
66};
67
68/// This structure is used to update offset with start of another section.
72 bool AddLocalValue = false)
73 : SectionPatch({PatchOffset}), SectionPtr(SectionPtr, AddLocalValue) {}
74
76};
77
78/// This structure is used to update reference to the DIE.
81 uint32_t RefIdx);
82
85};
86
87/// This structure is used to update reference to the DIE of ULEB128 form.
90 CompileUnit *RefCU, uint32_t RefIdx);
91
94};
95
96/// This structure is used to update reference to the type DIE.
99
101};
102
103/// This structure is used to update reference to the type DIE.
107
108 DIE *Die = nullptr;
109 TypeEntry *TypeName = nullptr;
111};
112
116
117 DIE *Die = nullptr;
118 TypeEntry *TypeName = nullptr;
119 StringEntry *String = nullptr;
120};
121
125
126 DIE *Die = nullptr;
127 TypeEntry *TypeName = nullptr;
128 StringEntry *String = nullptr;
129};
130
134
135 DIE *Die = nullptr;
136 TypeEntry *TypeName = nullptr;
140};
141
142/// Type for section data.
144
145/// Type for list of pointers to patches offsets.
147
148class OutputSections;
149
150/// This structure is used to keep data of the concrete section.
151/// Like data bits, list of patches, format.
154
158 ListDebugStrPatch(&GlobalData.getAllocator()),
159 ListDebugLineStrPatch(&GlobalData.getAllocator()),
160 ListDebugRangePatch(&GlobalData.getAllocator()),
161 ListDebugLocPatch(&GlobalData.getAllocator()),
162 ListDebugDieRefPatch(&GlobalData.getAllocator()),
163 ListDebugULEB128DieRefPatch(&GlobalData.getAllocator()),
164 ListDebugOffsetPatch(&GlobalData.getAllocator()),
165 ListDebugDieTypeRefPatch(&GlobalData.getAllocator()),
166 ListDebugType2TypeDieRefPatch(&GlobalData.getAllocator()),
167 ListDebugTypeStrPatch(&GlobalData.getAllocator()),
168 ListDebugTypeLineStrPatch(&GlobalData.getAllocator()),
169 ListDebugTypeDeclFilePatch(&GlobalData.getAllocator()),
171
172 /// Erase whole section content(data bits, list of patches).
173 void clearAllSectionData();
174
175 /// Erase only section output data bits.
176 void clearSectionContent();
177
178 /// When objects(f.e. compile units) are glued into the single file,
179 /// the debug sections corresponding to the concrete object are assigned
180 /// with offsets inside the whole file. This field keeps offset
181 /// to the debug section, corresponding to this object.
183
184 /// Stream which stores data to the Contents.
186
187 /// Section patches.
188#define ADD_PATCHES_LIST(T) \
189 T &notePatch(const T &Patch) { return List##T.add(Patch); } \
190 ArrayList<T> List##T;
191
192 ADD_PATCHES_LIST(DebugStrPatch)
193 ADD_PATCHES_LIST(DebugLineStrPatch)
194 ADD_PATCHES_LIST(DebugRangePatch)
195 ADD_PATCHES_LIST(DebugLocPatch)
196 ADD_PATCHES_LIST(DebugDieRefPatch)
197 ADD_PATCHES_LIST(DebugULEB128DieRefPatch)
198 ADD_PATCHES_LIST(DebugOffsetPatch)
199 ADD_PATCHES_LIST(DebugDieTypeRefPatch)
200 ADD_PATCHES_LIST(DebugType2TypeDieRefPatch)
201 ADD_PATCHES_LIST(DebugTypeStrPatch)
202 ADD_PATCHES_LIST(DebugTypeLineStrPatch)
203 ADD_PATCHES_LIST(DebugTypeDeclFilePatch)
204
205 /// While creating patches, offsets to attributes may be partially
206 /// unknown(because size of abbreviation number is unknown). In such case we
207 /// remember patch itself and pointer to patch application offset to add size
208 /// of abbreviation number later.
209 template <typename T>
210 void notePatchWithOffsetUpdate(const T &Patch,
211 OffsetsPtrVector &PatchesOffsetsList) {
212 PatchesOffsetsList.emplace_back(&notePatch(Patch).PatchOffset);
213 }
214
215 /// Some sections are emitted using AsmPrinter. In that case "Contents"
216 /// member of SectionDescriptor contains elf file. This method searches
217 /// for section data inside elf file and remember offset to it.
219
220 /// Returns section content.
223 return Contents;
224
227 }
228
229 /// Emit unit length into the current section contents.
233 }
234
235 /// Emit DWARF64 mark into the current section contents.
238 return;
240 }
241
242 /// Emit specified offset value into the current section contents.
245 }
246
247 /// Emit specified integer value into the current section contents.
248 void emitIntVal(uint64_t Val, unsigned Size);
249
250 void emitString(dwarf::Form StringForm, const char *StringVal);
251
253
254 /// Emit specified inplace string value into the current section contents.
256 OS << String;
257 emitIntVal(0, 1);
258 }
259
260 /// Emit string placeholder into the current section contents.
262 // emit bad offset which should be updated later.
263 emitOffset(0xBADDEF);
264 }
265
266 /// Write specified \p Value of \p AttrForm to the \p PatchOffset.
267 void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val);
268
269 /// Returns integer value of \p Size located by specified \p PatchOffset.
270 uint64_t getIntVal(uint64_t PatchOffset, unsigned Size);
271
272protected:
273 /// Writes integer value \p Val of \p Size by specified \p PatchOffset.
274 void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size);
275
276 /// Writes integer value \p Val of ULEB128 format by specified \p PatchOffset.
277 void applyULEB128(uint64_t PatchOffset, uint64_t Val);
278
279 /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
280 void applySLEB128(uint64_t PatchOffset, uint64_t Val);
281
282 /// Sets output format.
284 this->Format = Format;
285 this->Endianess = Endianess;
286 }
287
289
290 /// Section data bits.
292
293 /// Some sections are generated using AsmPrinter. The real section data
294 /// located inside elf file in that case. Following fields points to the
295 /// real section content inside elf file.
298};
299
300/// This class keeps contents and offsets to the debug sections. Any objects
301/// which is supposed to be emitted into the debug sections should use this
302/// class to track debug sections offsets and keep sections data.
304public:
306
307 /// Sets output format for all keeping sections.
309 this->Format = Format;
310 this->Endianness = Endianness;
311 }
312
313 /// Returns descriptor for the specified section of \p SectionKind.
314 /// The descriptor should already be created. The llvm_unreachable
315 /// would be raised if it is not.
316 const SectionDescriptor &
318 SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind);
319
320 if (It == SectionDescriptors.end())
322 formatv("Section {0} does not exist", getSectionName(SectionKind))
323 .str()
324 .c_str());
325
326 return *It->second;
327 }
328
329 /// Returns descriptor for the specified section of \p SectionKind.
330 /// The descriptor should already be created. The llvm_unreachable
331 /// would be raised if it is not.
333 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
334
335 if (It == SectionDescriptors.end())
337 formatv("Section {0} does not exist", getSectionName(SectionKind))
338 .str()
339 .c_str());
340
341 assert(It->second.get() != nullptr);
342
343 return *It->second;
344 }
345
346 /// Returns descriptor for the specified section of \p SectionKind.
347 /// Returns std::nullopt if section descriptor is not created yet.
348 std::optional<const SectionDescriptor *>
350 SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind);
351
352 if (It == SectionDescriptors.end())
353 return std::nullopt;
354
355 return It->second.get();
356 }
357
358 /// Returns descriptor for the specified section of \p SectionKind.
359 /// Returns std::nullopt if section descriptor is not created yet.
360 std::optional<SectionDescriptor *>
362 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
363
364 if (It == SectionDescriptors.end())
365 return std::nullopt;
366
367 return It->second.get();
368 }
369
370 /// Returns descriptor for the specified section of \p SectionKind.
371 /// If descriptor does not exist then creates it.
374 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
375
376 if (It == SectionDescriptors.end()) {
377 SectionDescriptor *Section =
379 auto Result = SectionDescriptors.try_emplace(SectionKind, Section);
380 assert(Result.second);
381
382 It = Result.first;
383 }
384
385 return *It->second;
386 }
387
388 /// Erases data of all sections.
390 for (auto &Section : SectionDescriptors)
391 Section.second->clearAllSectionData();
392 }
393
394 /// Enumerate all sections and call \p Handler for each.
395 void forEach(function_ref<void(SectionDescriptor &)> Handler) {
396 for (auto &Section : SectionDescriptors) {
397 assert(Section.second.get() != nullptr);
398 Handler(*(Section.second));
399 }
400 }
401
402 /// Enumerate all sections and call \p Handler for each.
404 function_ref<void(std::shared_ptr<SectionDescriptor> Section)> Handler) {
405 for (auto &Section : SectionDescriptors)
406 Handler(Section.second);
407 }
408
409 /// Enumerate all sections, for each section set current offset
410 /// (kept by \p SectionSizesAccumulator), update current offset with section
411 /// length.
413 std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) {
414 for (auto &Section : SectionDescriptors) {
415 Section.second->StartOffset =
416 SectionSizesAccumulator[static_cast<uint8_t>(
417 Section.second->getKind())];
418 SectionSizesAccumulator[static_cast<uint8_t>(
419 Section.second->getKind())] += Section.second->getContents().size();
420 }
421 }
422
423 /// Enumerate all sections, for each section apply all section patches.
424 void applyPatches(SectionDescriptor &Section,
426 StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings,
427 TypeUnit *TypeUnitPtr);
428
429 /// Endiannes for the sections.
431
432 /// Return DWARF version.
433 uint16_t getVersion() const { return Format.Version; }
434
435 /// Return size of header of debug_info table.
437 return Format.Version >= 5 ? 12 : 11;
438 }
439
440 /// Return size of header of debug_ table.
442 assert(Format.Version >= 5);
443 return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
444 }
445
446 /// Return size of header of debug_str_offsets table.
448 assert(Format.Version >= 5);
449 return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
450 }
451
452 /// Return size of address.
453 const dwarf::FormParams &getFormParams() const { return Format; }
454
455protected:
457
458 /// Format for sections.
460
461 /// Endiannes for sections.
463
464 /// All keeping sections.
466 std::map<DebugSectionKind, std::shared_ptr<SectionDescriptor>>;
468};
469
470} // end of namespace parallel
471} // end of namespace dwarf_linker
472} // end of namespace llvm
473
474#endif // LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
This file contains constants used for implementing Dwarf debug support.
uint64_t Size
#define ADD_PATCHES_LIST(T)
Section patches.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
A structured debug information entry.
Definition: DIE.h:819
PointerIntPair - This class implements a pair of a pointer and small integer.
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: SmallString.h:247
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:951
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
Stores all information related to a compile unit, be it in its original instance of the object file o...
This class keeps data and services common for the whole linking process.
This class keeps contents and offsets to the debug sections.
std::optional< SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
void applyPatches(SectionDescriptor &Section, StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, TypeUnit *TypeUnitPtr)
Enumerate all sections, for each section apply all section patches.
uint16_t getDebugStrOffsetsHeaderSize() const
Return size of header of debug_str_offsets table.
OutputSections(LinkingGlobalData &GlobalData)
llvm::endianness Endianness
Endiannes for sections.
dwarf::FormParams Format
Format for sections.
const dwarf::FormParams & getFormParams() const
Return size of address.
void eraseSections()
Erases data of all sections.
std::optional< const SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)
Sets output format for all keeping sections.
uint16_t getVersion() const
Return DWARF version.
uint16_t getDebugInfoHeaderSize() const
Return size of header of debug_info table.
uint16_t getDebugAddrHeaderSize() const
Return size of header of debug_ table.
std::map< DebugSectionKind, std::shared_ptr< SectionDescriptor > > SectionsSetTy
All keeping sections.
void forEach(function_ref< void(std::shared_ptr< SectionDescriptor > Section)> Handler)
Enumerate all sections and call Handler for each.
void forEach(function_ref< void(SectionDescriptor &)> Handler)
Enumerate all sections and call Handler for each.
llvm::endianness getEndianness() const
Endiannes for the sections.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
void assignSectionsOffsetAndAccumulateSize(std::array< uint64_t, SectionKindsNum > &SectionSizesAccumulator)
Enumerate all sections, for each section set current offset (kept by SectionSizesAccumulator),...
const SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
This class creates a DwarfStringPoolEntry for the corresponding StringEntry.
Type Unit is used to represent an artificial compilation unit which keeps all type information.
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
DebugSectionKind
List of tracked debug tables.
@ DWARF64
Definition: Dwarf.h:91
@ DWARF32
Definition: Dwarf.h:91
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:1064
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition: Dwarf.h:55
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:480
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
endianness
Definition: bit.h:70
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:1077
DwarfFormat Format
Definition: Dwarf.h:1080
This structure is used to update reference to the DIE.
PointerIntPair< CompileUnit *, 1 > RefCU
This structure is used to update reference to the type DIE.
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.
DebugOffsetPatch(uint64_t PatchOffset, SectionDescriptor *SectionPtr, bool AddLocalValue=false)
PointerIntPair< SectionDescriptor *, 1 > SectionPtr
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
bool IsCompileUnitRanges
Indicates patch which points to immediate compile unit's attribute.
This structure is used to update strings offsets into .debug_str.
This structure is used to update reference to the type DIE.
This structure is used to update reference to the DIE of ULEB128 form.
This structure keeps data of the concrete section.
Definition: DWARFLinker.h:93
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
Definition: DWARFLinker.h:107
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
void emitOffset(uint64_t Val)
Emit specified offset value into the current section contents.
OutSectionDataTy Contents
Section data bits.
void emitString(dwarf::Form StringForm, const char *StringVal)
void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size)
Writes integer value Val of Size by specified PatchOffset.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
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.
void maybeEmitDwarf64Mark()
Emit DWARF64 mark into the current section contents.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
void emitInplaceString(StringRef String)
Emit specified inplace string value into the current section contents.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
void clearSectionContent()
Erase only section output data bits.
StringRef getContents() override
Returns section content.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianess)
Sets output format.
size_t SectionOffsetInsideAsmPrinterOutputStart
Some sections are generated using AsmPrinter.
void clearAllSectionData()
Erase whole section content(data bits, list of patches).
SectionDescriptor(DebugSectionKind SectionKind, LinkingGlobalData &GlobalData, dwarf::FormParams Format, llvm::endianness Endianess)
void emitStringPlaceholder()
Emit string placeholder into the current section contents.
void notePatchWithOffsetUpdate(const T &Patch, OffsetsPtrVector &PatchesOffsetsList)
While creating patches, offsets to attributes may be partially unknown(because size of abbreviation n...
There are fields(sizes, offsets) which should be updated after sections are generated.