LLVM 18.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_DWARFLINKERPARALLEL_OUTPUTSECTIONS_H
10#define LLVM_LIB_DWARFLINKERPARALLEL_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 dwarflinker_parallel {
33
34class TypeUnit;
35
36/// List of tracked debug tables.
37enum class DebugSectionKind : uint8_t {
38 DebugInfo = 0,
60 NumberOfEnumEntries // must be last
61};
62constexpr static size_t SectionKindsNum =
63 static_cast<size_t>(DebugSectionKind::NumberOfEnumEntries);
64
65/// Recognise the table name and match it with the DebugSectionKind.
66std::optional<DebugSectionKind> parseDebugTableName(StringRef Name);
67
68/// Return the name of the section.
70
71/// There are fields(sizes, offsets) which should be updated after
72/// sections are generated. To remember offsets and related data
73/// the descendants of SectionPatch structure should be used.
74
77};
78
79/// This structure is used to update strings offsets into .debug_str.
81 const StringEntry *String = nullptr;
82};
83
84/// This structure is used to update strings offsets into .debug_line_str.
86 const StringEntry *String = nullptr;
87};
88
89/// This structure is used to update range list offset into
90/// .debug_ranges/.debug_rnglists.
92 /// Indicates patch which points to immediate compile unit's attribute.
93 bool IsCompileUnitRanges = false;
94};
95
96/// This structure is used to update location list offset into
97/// .debug_loc/.debug_loclists.
100};
101
102/// This structure is used to update offset with start of another section.
103struct SectionDescriptor;
106 bool AddLocalValue = false)
107 : SectionPatch({PatchOffset}), SectionPtr(SectionPtr, AddLocalValue) {}
108
110};
111
112/// This structure is used to update reference to the DIE.
115 uint32_t RefIdx);
116
119};
120
121/// This structure is used to update reference to the DIE of ULEB128 form.
124 CompileUnit *RefCU, uint32_t RefIdx);
125
128};
129
130/// This structure is used to update reference to the type DIE.
133
135};
136
137/// This structure is used to update reference to the type DIE.
141
142 DIE *Die = nullptr;
143 TypeEntry *TypeName = nullptr;
145};
146
150
151 DIE *Die = nullptr;
152 TypeEntry *TypeName = nullptr;
153 StringEntry *String = nullptr;
154};
155
159
160 DIE *Die = nullptr;
161 TypeEntry *TypeName = nullptr;
162 StringEntry *String = nullptr;
163};
164
168
169 DIE *Die = nullptr;
170 TypeEntry *TypeName = nullptr;
174};
175
176/// Type for section data.
178
179/// Type for list of pointers to patches offsets.
181
182class OutputSections;
183
184/// This structure is used to keep data of the concrete section.
185/// Like data bits, list of patches, format.
188
191 : OS(Contents), ListDebugStrPatch(&GlobalData.getAllocator()),
192 ListDebugLineStrPatch(&GlobalData.getAllocator()),
193 ListDebugRangePatch(&GlobalData.getAllocator()),
194 ListDebugLocPatch(&GlobalData.getAllocator()),
195 ListDebugDieRefPatch(&GlobalData.getAllocator()),
196 ListDebugULEB128DieRefPatch(&GlobalData.getAllocator()),
197 ListDebugOffsetPatch(&GlobalData.getAllocator()),
198 ListDebugDieTypeRefPatch(&GlobalData.getAllocator()),
199 ListDebugType2TypeDieRefPatch(&GlobalData.getAllocator()),
200 ListDebugTypeStrPatch(&GlobalData.getAllocator()),
201 ListDebugTypeLineStrPatch(&GlobalData.getAllocator()),
202 ListDebugTypeDeclFilePatch(&GlobalData.getAllocator()),
205
206 /// Erase whole section contents(data bits, list of patches).
207 void clearAllSectionData();
208
209 /// Erase only section output data bits.
210 void clearSectionContent();
211
212 /// When objects(f.e. compile units) are glued into the single file,
213 /// the debug sections corresponding to the concrete object are assigned
214 /// with offsets inside the whole file. This field keeps offset
215 /// to the debug section, corresponding to this object.
217
218 /// Stream which stores data to the Contents.
220
221 /// Section patches.
222#define ADD_PATCHES_LIST(T) \
223 T &notePatch(const T &Patch) { return List##T.add(Patch); } \
224 ArrayList<T> List##T;
225
226 ADD_PATCHES_LIST(DebugStrPatch)
227 ADD_PATCHES_LIST(DebugLineStrPatch)
228 ADD_PATCHES_LIST(DebugRangePatch)
229 ADD_PATCHES_LIST(DebugLocPatch)
230 ADD_PATCHES_LIST(DebugDieRefPatch)
231 ADD_PATCHES_LIST(DebugULEB128DieRefPatch)
232 ADD_PATCHES_LIST(DebugOffsetPatch)
233 ADD_PATCHES_LIST(DebugDieTypeRefPatch)
234 ADD_PATCHES_LIST(DebugType2TypeDieRefPatch)
235 ADD_PATCHES_LIST(DebugTypeStrPatch)
236 ADD_PATCHES_LIST(DebugTypeLineStrPatch)
237 ADD_PATCHES_LIST(DebugTypeDeclFilePatch)
238
239 /// While creating patches, offsets to attributes may be partially
240 /// unknown(because size of abbreviation number is unknown). In such case we
241 /// remember patch itself and pointer to patch application offset to add size
242 /// of abbreviation number later.
243 template <typename T>
244 void notePatchWithOffsetUpdate(const T &Patch,
245 OffsetsPtrVector &PatchesOffsetsList) {
246 PatchesOffsetsList.emplace_back(&notePatch(Patch).PatchOffset);
247 }
248
249 /// Some sections are emitted using AsmPrinter. In that case "Contents"
250 /// member of SectionDescriptor contains elf file. This method searches
251 /// for section data inside elf file and remember offset to it.
253
254 /// Returns section content.
257 return StringRef(Contents.data(), Contents.size());
258
261 }
262
263 /// Emit unit length into the current section contents.
267 }
268
269 /// Emit DWARF64 mark into the current section contents.
272 return;
274 }
275
276 /// Emit specified offset value into the current section contents.
279 }
280
281 /// Emit specified integer value into the current section contents.
282 void emitIntVal(uint64_t Val, unsigned Size);
283
284 void emitString(dwarf::Form StringForm, const char *StringVal);
285
286 /// Emit specified inplace string value into the current section contents.
289 emitIntVal(0, 1);
290 }
291
292 /// Emit string placeholder into the current section contents.
294 // emit bad offset which should be updated later.
295 emitOffset(0xBADDEF);
296 }
297
298 /// Write specified \p Value of \p AttrForm to the \p PatchOffset.
299 void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val);
300
301 /// Returns section kind.
303
304 /// Returns section name.
306
307 /// Returns endianess used by section.
309
310 /// Returns FormParams used by section.
312
313 /// Returns integer value of \p Size located by specified \p PatchOffset.
314 uint64_t getIntVal(uint64_t PatchOffset, unsigned Size);
315
316protected:
317 /// Writes integer value \p Val of \p Size by specified \p PatchOffset.
318 void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size);
319
320 /// Writes integer value \p Val of ULEB128 format by specified \p PatchOffset.
321 void applyULEB128(uint64_t PatchOffset, uint64_t Val);
322
323 /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
324 void applySLEB128(uint64_t PatchOffset, uint64_t Val);
325
326 /// Sets output format.
328 this->Format = Format;
329 this->Endianess = Endianess;
330 }
331
333
334 /// The section kind.
336
337 /// Section data bits.
339
340 /// Some sections are generated using AsmPrinter. The real section data
341 /// located inside elf file in that case. Following fields points to the
342 /// real section content inside elf file.
345
346 /// Output format.
349};
350
351/// This class keeps contents and offsets to the debug sections. Any objects
352/// which is supposed to be emitted into the debug sections should use this
353/// class to track debug sections offsets and keep sections data.
355public:
357
358 /// Sets output format for all keeping sections.
360 this->Format = Format;
361 this->Endianness = Endianness;
362 }
363
364 /// Returns descriptor for the specified section of \p SectionKind.
365 /// The descriptor should already be created. The llvm_unreachable
366 /// would be raised if it is not.
367 const SectionDescriptor &
369 SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind);
370
371 if (It == SectionDescriptors.end())
373 formatv("Section {0} does not exist", getSectionName(SectionKind))
374 .str()
375 .c_str());
376
377 return It->second;
378 }
379
380 /// Returns descriptor for the specified section of \p SectionKind.
381 /// The descriptor should already be created. The llvm_unreachable
382 /// would be raised if it is not.
384 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
385
386 if (It == SectionDescriptors.end())
388 formatv("Section {0} does not exist", getSectionName(SectionKind))
389 .str()
390 .c_str());
391
392 return It->second;
393 }
394
395 /// Returns descriptor for the specified section of \p SectionKind.
396 /// Returns std::nullopt if section descriptor is not created yet.
397 std::optional<const SectionDescriptor *>
399 SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind);
400
401 if (It == SectionDescriptors.end())
402 return std::nullopt;
403
404 return &It->second;
405 }
406
407 /// Returns descriptor for the specified section of \p SectionKind.
408 /// Returns std::nullopt if section descriptor is not created yet.
409 std::optional<SectionDescriptor *>
411 SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
412
413 if (It == SectionDescriptors.end())
414 return std::nullopt;
415
416 return &It->second;
417 }
418
419 /// Returns descriptor for the specified section of \p SectionKind.
420 /// If descriptor does not exist then creates it.
423 return SectionDescriptors
425 .first->second;
426 }
427
428 /// Erases data of all sections.
430 for (auto &Section : SectionDescriptors)
431 Section.second.clearAllSectionData();
432 }
433
434 /// Enumerate all sections and call \p Handler for each.
435 void forEach(function_ref<void(SectionDescriptor &)> Handler) {
436 for (auto &Section : SectionDescriptors)
437 Handler(Section.second);
438 }
439
440 /// Enumerate all sections, for each section set current offset
441 /// (kept by \p SectionSizesAccumulator), update current offset with section
442 /// length.
444 std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) {
445 for (auto &Section : SectionDescriptors) {
446 Section.second.StartOffset = SectionSizesAccumulator[static_cast<uint8_t>(
447 Section.second.getKind())];
448 SectionSizesAccumulator[static_cast<uint8_t>(Section.second.getKind())] +=
449 Section.second.getContents().size();
450 }
451 }
452
453 /// Enumerate all sections, for each section apply all section patches.
454 void applyPatches(SectionDescriptor &Section,
456 StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings,
457 TypeUnit *TypeUnitPtr);
458
459 /// Endiannes for the sections.
461
462 /// Return DWARF version.
463 uint16_t getVersion() const { return Format.Version; }
464
465 /// Return size of header of debug_info table.
467 return Format.Version >= 5 ? 12 : 11;
468 }
469
470 /// Return size of header of debug_ table.
472 assert(Format.Version >= 5);
473 return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
474 }
475
476 /// Return size of header of debug_str_offsets table.
478 assert(Format.Version >= 5);
479 return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
480 }
481
482 /// Return size of address.
483 const dwarf::FormParams &getFormParams() const { return Format; }
484
485protected:
487
488 /// Format for sections.
490
491 /// Endiannes for sections.
493
494 /// All keeping sections.
495 using SectionsSetTy = std::map<DebugSectionKind, SectionDescriptor>;
497};
498
499} // end of namespace dwarflinker_parallel
500} // end namespace llvm
501
502#endif // LLVM_LIB_DWARFLINKERPARALLEL_OUTPUTSECTIONS_H
This file contains constants used for implementing Dwarf debug support.
std::string Name
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:254
size_t size() const
Definition: SmallVector.h:91
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
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
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.
StringRef translateString(StringRef String)
Translate specified string.
This class keeps contents and offsets to the debug sections.
uint16_t getVersion() const
Return DWARF version.
void assignSectionsOffsetAndAccumulateSize(std::array< uint64_t, SectionKindsNum > &SectionSizesAccumulator)
Enumerate all sections, for each section set current offset (kept by SectionSizesAccumulator),...
uint16_t getDebugStrOffsetsHeaderSize() const
Return size of header of debug_str_offsets table.
void forEach(function_ref< void(SectionDescriptor &)> Handler)
Enumerate all sections and call Handler for each.
uint16_t getDebugAddrHeaderSize() const
Return size of header of debug_ table.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)
Sets output format for all keeping sections.
void applyPatches(SectionDescriptor &Section, StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, TypeUnit *TypeUnitPtr)
Enumerate all sections, for each section apply all section patches.
void eraseSections()
Erases data of all sections.
std::map< DebugSectionKind, SectionDescriptor > SectionsSetTy
All keeping sections.
std::optional< SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
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.
llvm::endianness Endianness
Endiannes for sections.
llvm::endianness getEndianness() const
Endiannes for the sections.
OutputSections(LinkingGlobalData &GlobalData)
const dwarf::FormParams & getFormParams() const
Return size of address.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
uint16_t getDebugInfoHeaderSize() const
Return size of header of debug_info table.
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.
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:672
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ 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:730
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition: Dwarf.h:55
std::optional< DebugSectionKind > parseDebugTableName(llvm::StringRef SecName)
Recognise the table name and match it with the DebugSectionKind.
DebugSectionKind
List of tracked debug tables.
static constexpr size_t SectionKindsNum
const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:456
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
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:743
DwarfFormat Format
Definition: Dwarf.h:746
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.
PointerIntPair< SectionDescriptor *, 1 > SectionPtr
DebugOffsetPatch(uint64_t PatchOffset, SectionDescriptor *SectionPtr, bool AddLocalValue=false)
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.
PointerIntPair< CompileUnit *, 1 > RefCU
This structure is used to keep data of the concrete section.
DebugSectionKind SectionKind
The section kind.
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 notePatchWithOffsetUpdate(const T &Patch, OffsetsPtrVector &PatchesOffsetsList)
While creating patches, offsets to attributes may be partially unknown(because size of abbreviation n...
void emitOffset(uint64_t Val)
Emit specified offset 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.
SectionDescriptor(DebugSectionKind SectionKind, LinkingGlobalData &GlobalData, dwarf::FormParams Format, llvm::endianness Endianess)
raw_svector_ostream OS
Stream which stores data to the Contents.
dwarf::FormParams Format
Output format.
llvm::endianness getEndianess() const
Returns endianess used by section.
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.
DebugSectionKind getKind()
Returns section kind.
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
const StringLiteral & getName() const
Returns section name.
void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size)
Writes integer value Val of Size by specified PatchOffset.
void maybeEmitDwarf64Mark()
Emit DWARF64 mark into the current section contents.
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.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianess)
Sets output format.
There are fields(sizes, offsets) which should be updated after sections are generated.