LLVM 24.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"
13#include "ModulePool.h"
16#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/Endian.h"
24#include "llvm/Support/Error.h"
26#include "llvm/Support/LEB128.h"
29#include <array>
30#include <cstdint>
31
32namespace llvm {
33namespace dwarf_linker {
34namespace parallel {
35
36class TypeUnit;
37
38/// There are fields(sizes, offsets) which should be updated after
39/// sections are generated. To remember offsets and related data
40/// the descendants of SectionPatch structure should be used.
41
45
46/// This structure is used to update strings offsets into .debug_str.
48 const StringEntry *String = nullptr;
49};
50
51/// This structure is used to update strings offsets into .debug_line_str.
53 const StringEntry *String = nullptr;
54};
55
56/// This structure is used to update range list offset into
57/// .debug_ranges/.debug_rnglists.
59 /// Indicates patch which points to immediate compile unit's attribute.
60 bool IsCompileUnitRanges = false;
61};
62
63/// This structure is used to update location list offset into
64/// .debug_loc/.debug_loclists.
68
69/// This structure is used to update offset with start of another section.
78
79/// This structure is used to update reference to the DIE.
87
88/// This structure is used to update reference to the DIE of ULEB128 form.
96
97/// This structure is used to update reference to the type DIE.
103
104/// This structure is used to update a DW_AT_import reference to a
105/// DW_TAG_module. The reference resolves to the module's anchor once the link
106/// has filled it in, and to the inherited target otherwise. The inherited
107/// target is always resolved as an inter-CU reference, so that the attribute
108/// keeps the width it was emitted with whichever of the two wins.
116
117/// This structure is used to update reference to the type DIE.
126
135
144
155
156/// Type for section data.
158
159/// Type for list of pointers to patches offsets.
161
162class OutputSections;
163
164/// This structure is used to keep data of the concrete section.
165/// Like data bits, list of patches, format.
168
172 ListDebugStrPatch(&GlobalData.getAllocator()),
173 ListDebugLineStrPatch(&GlobalData.getAllocator()),
174 ListDebugRangePatch(&GlobalData.getAllocator()),
175 ListDebugLocPatch(&GlobalData.getAllocator()),
176 ListDebugDieRefPatch(&GlobalData.getAllocator()),
177 ListDebugULEB128DieRefPatch(&GlobalData.getAllocator()),
178 ListDebugOffsetPatch(&GlobalData.getAllocator()),
179 ListDebugDieTypeRefPatch(&GlobalData.getAllocator()),
180 ListDebugDieModuleRefPatch(&GlobalData.getAllocator()),
181 ListDebugType2TypeDieRefPatch(&GlobalData.getAllocator()),
182 ListDebugTypeStrPatch(&GlobalData.getAllocator()),
183 ListDebugTypeLineStrPatch(&GlobalData.getAllocator()),
184 ListDebugTypeDeclFilePatch(&GlobalData.getAllocator()),
186
187 /// Erase whole section content(data bits, list of patches).
188 void clearAllSectionData();
189
190 /// Erase only section output data bits.
191 void clearSectionContent();
192
193 /// When objects(f.e. compile units) are glued into the single file,
194 /// the debug sections corresponding to the concrete object are assigned
195 /// with offsets inside the whole file. This field keeps offset
196 /// to the debug section, corresponding to this object.
198
199protected:
200 /// Section data bits.
202
203public:
204 /// Stream which stores data to the Contents.
206
207 /// Section patches.
208#define ADD_PATCHES_LIST(T) \
209 T &notePatch(const T &Patch) { return List##T.add(Patch); } \
210 ArrayList<T> List##T;
211
212 ADD_PATCHES_LIST(DebugStrPatch)
213 ADD_PATCHES_LIST(DebugLineStrPatch)
214 ADD_PATCHES_LIST(DebugRangePatch)
215 ADD_PATCHES_LIST(DebugLocPatch)
216 ADD_PATCHES_LIST(DebugDieRefPatch)
217 ADD_PATCHES_LIST(DebugULEB128DieRefPatch)
218 ADD_PATCHES_LIST(DebugOffsetPatch)
219 ADD_PATCHES_LIST(DebugDieTypeRefPatch)
220 ADD_PATCHES_LIST(DebugDieModuleRefPatch)
221 ADD_PATCHES_LIST(DebugType2TypeDieRefPatch)
222 ADD_PATCHES_LIST(DebugTypeStrPatch)
223 ADD_PATCHES_LIST(DebugTypeLineStrPatch)
224 ADD_PATCHES_LIST(DebugTypeDeclFilePatch)
225
226 /// While creating patches, offsets to attributes may be partially
227 /// unknown(because size of abbreviation number is unknown). In such case we
228 /// remember patch itself and pointer to patch application offset to add size
229 /// of abbreviation number later.
230 template <typename T>
231 void notePatchWithOffsetUpdate(const T &Patch,
232 OffsetsPtrVector &PatchesOffsetsList) {
233 PatchesOffsetsList.emplace_back(&notePatch(Patch).PatchOffset);
234 }
235
236 /// Some sections are emitted using AsmPrinter. In that case "Contents"
237 /// member of SectionDescriptor contains elf file. This method searches
238 /// for section data inside elf file and remember offset to it.
240
241 /// Returns section content.
249
250 /// Emit unit length into the current section contents.
253 emitIntVal(Length, getFormParams().getDwarfOffsetByteSize());
254 }
255
256 /// Emit DWARF64 mark into the current section contents.
262
263 /// Emit specified offset value into the current section contents.
265 emitIntVal(Val, getFormParams().getDwarfOffsetByteSize());
266 }
267
268 /// Emit specified integer value into the current section contents.
269 void emitIntVal(uint64_t Val, unsigned Size);
270
271 void emitString(dwarf::Form StringForm, const char *StringVal);
272
274
275 /// Emit specified inplace string value into the current section contents.
277 OS << String;
278 emitIntVal(0, 1);
279 }
280
281 /// Emit string placeholder into the current section contents.
283 // emit bad offset which should be updated later.
284 emitOffset(0xBADDEF);
285 }
286
287 /// Write specified \p Value of \p AttrForm to the \p PatchOffset.
288 void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val);
289
290 /// Returns integer value of \p Size located by specified \p PatchOffset.
291 uint64_t getIntVal(uint64_t PatchOffset, unsigned Size);
292
293protected:
294 /// Writes integer value \p Val of \p Size by specified \p PatchOffset.
295 void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size);
296
297 /// Writes integer value \p Val of ULEB128 format by specified \p PatchOffset.
298 void applyULEB128(uint64_t PatchOffset, uint64_t Val);
299
300 /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
301 void applySLEB128(uint64_t PatchOffset, uint64_t Val);
302
303 /// Sets output format.
305 this->Format = Format;
306 this->Endianess = Endianess;
307 }
308
310
311 /// Some sections are generated using AsmPrinter. The real section data
312 /// located inside elf file in that case. Following fields points to the
313 /// real section content inside elf file.
316};
317
318/// This class keeps contents and offsets to the debug sections. Any objects
319/// which is supposed to be emitted into the debug sections should use this
320/// class to track debug sections offsets and keep sections data.
322public:
324
325 /// Sets output format for all keeping sections.
327 this->Format = Format;
328 this->Endianness = Endianness;
329 }
330
331 /// Returns descriptor for the specified section of \p SectionKind.
332 /// The descriptor should already be created. The llvm_unreachable
333 /// would be raised if it is not.
334 const SectionDescriptor &
336 SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind);
337
338 if (It == SectionDescriptors.end())
340 formatv("Section {0} does not exist", getSectionName(SectionKind))
341 .str()
342 .c_str());
343
344 return *It->second;
345 }
346
347 /// Returns descriptor for the specified section of \p SectionKind.
348 /// The descriptor should already be created. The llvm_unreachable
349 /// would be raised if it is not.
351 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
352
353 if (It == SectionDescriptors.end())
355 formatv("Section {0} does not exist", getSectionName(SectionKind))
356 .str()
357 .c_str());
358
359 assert(It->second.get() != nullptr);
360
361 return *It->second;
362 }
363
364 /// Returns descriptor for the specified section of \p SectionKind.
365 /// Returns std::nullopt if section descriptor is not created yet.
366 std::optional<const SectionDescriptor *>
368 SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind);
369
370 if (It == SectionDescriptors.end())
371 return std::nullopt;
372
373 return It->second.get();
374 }
375
376 /// Returns descriptor for the specified section of \p SectionKind.
377 /// Returns std::nullopt if section descriptor is not created yet.
378 std::optional<SectionDescriptor *>
380 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
381
382 if (It == SectionDescriptors.end())
383 return std::nullopt;
384
385 return It->second.get();
386 }
387
388 /// Returns descriptor for the specified section of \p SectionKind.
389 /// If descriptor does not exist then creates it.
392 auto [It, Inserted] = SectionDescriptors.try_emplace(SectionKind);
393
394 if (Inserted)
395 It->second = std::make_shared<SectionDescriptor>(SectionKind, GlobalData,
397
398 return *It->second;
399 }
400
401 /// Erases data of all sections.
403 for (auto &Section : SectionDescriptors)
404 Section.second->clearAllSectionData();
405 }
406
407 /// Enumerate all sections and call \p Handler for each.
408 void forEach(function_ref<void(SectionDescriptor &)> Handler) {
409 for (auto &Section : SectionDescriptors) {
410 assert(Section.second.get() != nullptr);
411 Handler(*(Section.second));
412 }
413 }
414
415 /// Enumerate all sections and call \p Handler for each.
417 function_ref<void(std::shared_ptr<SectionDescriptor> Section)> Handler) {
418 for (auto &Section : SectionDescriptors)
419 Handler(Section.second);
420 }
421
422 /// Enumerate all sections, for each section set current offset
423 /// (kept by \p SectionSizesAccumulator), update current offset with section
424 /// length.
426 std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) {
427 for (auto &Section : SectionDescriptors) {
428 Section.second->StartOffset =
429 SectionSizesAccumulator[static_cast<uint8_t>(
430 Section.second->getKind())];
431 SectionSizesAccumulator[static_cast<uint8_t>(
432 Section.second->getKind())] += Section.second->getContents().size();
433 }
434 }
435
436 /// Enumerate all sections, for each section apply all section patches.
437 void applyPatches(SectionDescriptor &Section,
439 StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings,
440 TypeUnit *TypeUnitPtr);
441
442 /// Endiannes for the sections.
444
445 /// Return DWARF version.
446 uint16_t getVersion() const { return Format.Version; }
447
448 /// Return size of header of debug_info table.
450 return Format.Version >= 5 ? 12 : 11;
451 }
452
453 /// Return size of header of debug_ table.
455 assert(Format.Version >= 5);
456 return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
457 }
458
459 /// Return size of header of debug_str_offsets table.
461 assert(Format.Version >= 5);
462 return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
463 }
464
465 /// Return size of address.
466 const dwarf::FormParams &getFormParams() const { return Format; }
467
468protected:
470
471 /// Format for sections.
473
474 /// Endiannes for sections.
476
477 /// All keeping sections.
479 std::map<DebugSectionKind, std::shared_ptr<SectionDescriptor>>;
481};
482
483} // end of namespace parallel
484} // end of namespace dwarf_linker
485} // end of namespace llvm
486
487#endif // LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file contains constants used for implementing Dwarf debug support.
#define T
#define ADD_PATCHES_LIST(T)
Section patches.
This file defines the SmallString class.
A structured debug information entry.
Definition DIE.h:842
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
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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.
std::map< DebugSectionKind, std::shared_ptr< SectionDescriptor > > SectionsSetTy
All keeping sections.
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.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SmallString< 0 > OutSectionDataTy
Type for section data.
SmallVector< uint64_t * > OffsetsPtrVector
Type for list of pointers to patches offsets.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
Definition TypePool.h:28
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
DebugSectionKind
List of tracked debug tables.
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
Definition StringPool.h:23
@ DWARF64
Definition Dwarf.h:93
@ DWARF32
Definition Dwarf.h:93
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition Dwarf.h:57
This is an optimization pass for GlobalISel generic memory operations.
@ Length
Definition DWP.cpp:577
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
endianness
Definition bit.h:71
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition Dwarf.h:1199
DebugDieModuleRefPatch(uint64_t PatchOffset, CompileUnit *RefCU, uint32_t RefIdx, ModuleAnchor *Anchor)
PointerIntPair< CompileUnit *, 1 > RefCU
DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, uint32_t RefIdx)
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.
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.
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)
DebugULEB128DieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, uint32_t RefIdx)
Where the DW_TAG_module DIE describing a clang module ended up in the output.
Definition ModulePool.h:30
DebugSectionKind SectionKind
The section kind.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
SectionDescriptorBase(DebugSectionKind SectionKind, dwarf::FormParams Format, llvm::endianness Endianess)
Definition DWARFLinker.h:95
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.