1//===- OutputSections.h -----------------------------------------*- C++ -*-===//
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
7//===----------------------------------------------------------------------===//
9#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
10#define LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
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.
45/// This structure is used to update strings offsets into .debug_str.
50/// This structure is used to update strings offsets into .debug_line_str.
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.
62/// This structure is used to update location list offset into
63/// .debug_loc/.debug_loclists.
68/// This structure is used to update offset with start of another section.
72 bool AddLocalValue =
false)
78/// This structure is used to update reference to the DIE.
87/// This structure is used to update reference to the DIE of ULEB128 form.
96/// This structure is used to update reference to the type DIE.
103/// This structure is used to update reference to the type DIE.
142/// Type for section data.
145/// Type for list of pointers to patches offsets.
150/// This structure is used to keep data of the concrete section.
151/// Like data bits, list of patches, format.
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()),
172 /// Erase whole section content(data bits, list of patches).
175 /// Erase only section output data bits.
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.
185 /// Section data bits.
189 /// Stream which stores data to the Contents.
193 #define ADD_PATCHES_LIST(T) \
194 T ¬ePatch(const T &Patch) { return List##T.add(Patch); } \
195 ArrayList<T> List##T;
210 /// While creating patches, offsets to attributes may be partially
211 /// unknown(because size of abbreviation number is unknown). In such case we
212 /// remember patch itself and pointer to patch application offset to add size
213 /// of abbreviation number later.
214 template <
typename T>
217 PatchesOffsetsList.
emplace_back(¬ePatch(Patch).PatchOffset);
220 /// Some sections are emitted using AsmPrinter. In that case "Contents"
221 /// member of SectionDescriptor contains elf file. This method searches
222 /// for section data inside elf file and remember offset to it.
225 /// Returns section content.
234 /// Emit unit length into the current section contents.
240 /// Emit DWARF64 mark into the current section contents.
247 /// Emit specified offset value into the current section contents.
252 /// Emit specified integer value into the current section contents.
259 /// Emit specified inplace string value into the current section contents.
265 /// Emit string placeholder into the current section contents.
267 // emit bad offset which should be updated later.
271 /// Write specified \p Value of \p AttrForm to the \p PatchOffset.
274 /// Returns integer value of \p Size located by specified \p PatchOffset.
278 /// Writes integer value \p Val of \p Size by specified \p PatchOffset.
281 /// Writes integer value \p Val of ULEB128 format by specified \p PatchOffset.
284 /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
287 /// Sets output format.
295 /// Some sections are generated using AsmPrinter. The real section data
296 /// located inside elf file in that case. Following fields points to the
297 /// real section content inside elf file.
302/// This class keeps contents and offsets to the debug sections. Any objects
303/// which is supposed to be emitted into the debug sections should use this
304/// class to track debug sections offsets and keep sections data.
309 /// Sets output format for all keeping sections.
315 /// Returns descriptor for the specified section of \p SectionKind.
316 /// The descriptor should already be created. The llvm_unreachable
317 /// would be raised if it is not.
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.
343 assert(It->second.get() !=
nullptr);
348 /// Returns descriptor for the specified section of \p SectionKind.
349 /// Returns std::nullopt if section descriptor is not created yet.
350 std::optional<const SectionDescriptor *>
357 return It->second.get();
360 /// Returns descriptor for the specified section of \p SectionKind.
361 /// Returns std::nullopt if section descriptor is not created yet.
362 std::optional<SectionDescriptor *>
369 return It->second.get();
372 /// Returns descriptor for the specified section of \p SectionKind.
373 /// If descriptor does not exist then creates it.
385 /// Erases data of all sections.
388 Section.second->clearAllSectionData();
391 /// Enumerate all sections and call \p Handler for each.
394 assert(Section.second.get() !=
nullptr);
395 Handler(*(Section.second));
399 /// Enumerate all sections and call \p Handler for each.
401 function_ref<
void(std::shared_ptr<SectionDescriptor> Section)> Handler) {
403 Handler(Section.second);
406 /// Enumerate all sections, for each section set current offset
407 /// (kept by \p SectionSizesAccumulator), update current offset with section
410 std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) {
412 Section.second->StartOffset =
413 SectionSizesAccumulator[
static_cast<uint8_t >(
414 Section.second->getKind())];
415 SectionSizesAccumulator[
static_cast<uint8_t >(
416 Section.second->getKind())] += Section.second->getContents().size();
420 /// Enumerate all sections, for each section apply all section patches.
426 /// Endiannes for the sections.
429 /// Return DWARF version.
432 /// Return size of header of debug_info table.
434 return Format.Version >= 5 ? 12 : 11;
437 /// Return size of header of debug_ table.
443 /// Return size of header of debug_str_offsets table.
449 /// Return size of address.
455 /// Format for sections.
458 /// Endiannes for sections.
461 /// All keeping sections.
463 std::map<DebugSectionKind, std::shared_ptr<SectionDescriptor>>;
467}
// end of namespace parallel
468}
// end of namespace dwarf_linker
469}
// end of namespace llvm
471#endif // LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains constants used for implementing Dwarf debug support.
#define ADD_PATCHES_LIST(T)
Section patches.
This file defines the SmallString class.
A structured debug information entry.
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.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
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)
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.
SectionsSetTy SectionDescriptors
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
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...
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
This is an optimization pass for GlobalISel generic memory operations.
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t RefDieIdxOrClonedOffset
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.
const StringEntry * String
This structure is used to update location list offset into .debug_loc/.debug_loclists.
int64_t AddrAdjustmentValue
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.
const StringEntry * String
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)
uint64_t RefDieIdxOrClonedOffset
PointerIntPair< CompileUnit *, 1 > RefCU
DebugSectionKind SectionKind
The section kind.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
llvm::endianness Endianess
SectionDescriptorBase(DebugSectionKind SectionKind, dwarf::FormParams Format, llvm::endianness Endianess)
dwarf::FormParams Format
Output format.
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.
void emitBinaryData(llvm::StringRef Data)
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).
size_t SectionOffsetInsideAsmPrinterOutputEnd
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...
LinkingGlobalData & GlobalData
uint64_t StartOffset
When objects(f.e.
There are fields(sizes, offsets) which should be updated after sections are generated.