1*1db9f3b2SDimitry Andric //===- OutputSections.h -----------------------------------------*- C++ -*-===// 2*1db9f3b2SDimitry Andric // 3*1db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*1db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*1db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*1db9f3b2SDimitry Andric // 7*1db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 8*1db9f3b2SDimitry Andric 9*1db9f3b2SDimitry Andric #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H 10*1db9f3b2SDimitry Andric #define LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H 11*1db9f3b2SDimitry Andric 12*1db9f3b2SDimitry Andric #include "ArrayList.h" 13*1db9f3b2SDimitry Andric #include "StringEntryToDwarfStringPoolEntryMap.h" 14*1db9f3b2SDimitry Andric #include "llvm/ADT/SmallString.h" 15*1db9f3b2SDimitry Andric #include "llvm/ADT/StringRef.h" 16*1db9f3b2SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 17*1db9f3b2SDimitry Andric #include "llvm/CodeGen/DwarfStringPoolEntry.h" 18*1db9f3b2SDimitry Andric #include "llvm/DWARFLinker/StringPool.h" 19*1db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 20*1db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFObject.h" 21*1db9f3b2SDimitry Andric #include "llvm/Object/ObjectFile.h" 22*1db9f3b2SDimitry Andric #include "llvm/Support/Endian.h" 23*1db9f3b2SDimitry Andric #include "llvm/Support/Error.h" 24*1db9f3b2SDimitry Andric #include "llvm/Support/FormatVariadic.h" 25*1db9f3b2SDimitry Andric #include "llvm/Support/LEB128.h" 26*1db9f3b2SDimitry Andric #include "llvm/Support/MemoryBufferRef.h" 27*1db9f3b2SDimitry Andric #include "llvm/Support/raw_ostream.h" 28*1db9f3b2SDimitry Andric #include <array> 29*1db9f3b2SDimitry Andric #include <cstdint> 30*1db9f3b2SDimitry Andric 31*1db9f3b2SDimitry Andric namespace llvm { 32*1db9f3b2SDimitry Andric namespace dwarf_linker { 33*1db9f3b2SDimitry Andric namespace parallel { 34*1db9f3b2SDimitry Andric 35*1db9f3b2SDimitry Andric class TypeUnit; 36*1db9f3b2SDimitry Andric 37*1db9f3b2SDimitry Andric /// List of tracked debug tables. 38*1db9f3b2SDimitry Andric enum class DebugSectionKind : uint8_t { 39*1db9f3b2SDimitry Andric DebugInfo = 0, 40*1db9f3b2SDimitry Andric DebugLine, 41*1db9f3b2SDimitry Andric DebugFrame, 42*1db9f3b2SDimitry Andric DebugRange, 43*1db9f3b2SDimitry Andric DebugRngLists, 44*1db9f3b2SDimitry Andric DebugLoc, 45*1db9f3b2SDimitry Andric DebugLocLists, 46*1db9f3b2SDimitry Andric DebugARanges, 47*1db9f3b2SDimitry Andric DebugAbbrev, 48*1db9f3b2SDimitry Andric DebugMacinfo, 49*1db9f3b2SDimitry Andric DebugMacro, 50*1db9f3b2SDimitry Andric DebugAddr, 51*1db9f3b2SDimitry Andric DebugStr, 52*1db9f3b2SDimitry Andric DebugLineStr, 53*1db9f3b2SDimitry Andric DebugStrOffsets, 54*1db9f3b2SDimitry Andric DebugPubNames, 55*1db9f3b2SDimitry Andric DebugPubTypes, 56*1db9f3b2SDimitry Andric DebugNames, 57*1db9f3b2SDimitry Andric AppleNames, 58*1db9f3b2SDimitry Andric AppleNamespaces, 59*1db9f3b2SDimitry Andric AppleObjC, 60*1db9f3b2SDimitry Andric AppleTypes, 61*1db9f3b2SDimitry Andric NumberOfEnumEntries // must be last 62*1db9f3b2SDimitry Andric }; 63*1db9f3b2SDimitry Andric constexpr static size_t SectionKindsNum = 64*1db9f3b2SDimitry Andric static_cast<size_t>(DebugSectionKind::NumberOfEnumEntries); 65*1db9f3b2SDimitry Andric 66*1db9f3b2SDimitry Andric static constexpr StringLiteral SectionNames[SectionKindsNum] = { 67*1db9f3b2SDimitry Andric "debug_info", "debug_line", "debug_frame", "debug_ranges", 68*1db9f3b2SDimitry Andric "debug_rnglists", "debug_loc", "debug_loclists", "debug_aranges", 69*1db9f3b2SDimitry Andric "debug_abbrev", "debug_macinfo", "debug_macro", "debug_addr", 70*1db9f3b2SDimitry Andric "debug_str", "debug_line_str", "debug_str_offsets", "debug_pubnames", 71*1db9f3b2SDimitry Andric "debug_pubtypes", "debug_names", "apple_names", "apple_namespac", 72*1db9f3b2SDimitry Andric "apple_objc", "apple_types"}; 73*1db9f3b2SDimitry Andric 74*1db9f3b2SDimitry Andric static constexpr const StringLiteral & 75*1db9f3b2SDimitry Andric getSectionName(DebugSectionKind SectionKind) { 76*1db9f3b2SDimitry Andric return SectionNames[static_cast<uint8_t>(SectionKind)]; 77*1db9f3b2SDimitry Andric } 78*1db9f3b2SDimitry Andric 79*1db9f3b2SDimitry Andric /// Recognise the table name and match it with the DebugSectionKind. 80*1db9f3b2SDimitry Andric std::optional<DebugSectionKind> parseDebugTableName(StringRef Name); 81*1db9f3b2SDimitry Andric 82*1db9f3b2SDimitry Andric /// There are fields(sizes, offsets) which should be updated after 83*1db9f3b2SDimitry Andric /// sections are generated. To remember offsets and related data 84*1db9f3b2SDimitry Andric /// the descendants of SectionPatch structure should be used. 85*1db9f3b2SDimitry Andric 86*1db9f3b2SDimitry Andric struct SectionPatch { 87*1db9f3b2SDimitry Andric uint64_t PatchOffset = 0; 88*1db9f3b2SDimitry Andric }; 89*1db9f3b2SDimitry Andric 90*1db9f3b2SDimitry Andric /// This structure is used to update strings offsets into .debug_str. 91*1db9f3b2SDimitry Andric struct DebugStrPatch : SectionPatch { 92*1db9f3b2SDimitry Andric const StringEntry *String = nullptr; 93*1db9f3b2SDimitry Andric }; 94*1db9f3b2SDimitry Andric 95*1db9f3b2SDimitry Andric /// This structure is used to update strings offsets into .debug_line_str. 96*1db9f3b2SDimitry Andric struct DebugLineStrPatch : SectionPatch { 97*1db9f3b2SDimitry Andric const StringEntry *String = nullptr; 98*1db9f3b2SDimitry Andric }; 99*1db9f3b2SDimitry Andric 100*1db9f3b2SDimitry Andric /// This structure is used to update range list offset into 101*1db9f3b2SDimitry Andric /// .debug_ranges/.debug_rnglists. 102*1db9f3b2SDimitry Andric struct DebugRangePatch : SectionPatch { 103*1db9f3b2SDimitry Andric /// Indicates patch which points to immediate compile unit's attribute. 104*1db9f3b2SDimitry Andric bool IsCompileUnitRanges = false; 105*1db9f3b2SDimitry Andric }; 106*1db9f3b2SDimitry Andric 107*1db9f3b2SDimitry Andric /// This structure is used to update location list offset into 108*1db9f3b2SDimitry Andric /// .debug_loc/.debug_loclists. 109*1db9f3b2SDimitry Andric struct DebugLocPatch : SectionPatch { 110*1db9f3b2SDimitry Andric int64_t AddrAdjustmentValue = 0; 111*1db9f3b2SDimitry Andric }; 112*1db9f3b2SDimitry Andric 113*1db9f3b2SDimitry Andric /// This structure is used to update offset with start of another section. 114*1db9f3b2SDimitry Andric struct SectionDescriptor; 115*1db9f3b2SDimitry Andric struct DebugOffsetPatch : SectionPatch { 116*1db9f3b2SDimitry Andric DebugOffsetPatch(uint64_t PatchOffset, SectionDescriptor *SectionPtr, 117*1db9f3b2SDimitry Andric bool AddLocalValue = false) 118*1db9f3b2SDimitry Andric : SectionPatch({PatchOffset}), SectionPtr(SectionPtr, AddLocalValue) {} 119*1db9f3b2SDimitry Andric 120*1db9f3b2SDimitry Andric PointerIntPair<SectionDescriptor *, 1> SectionPtr; 121*1db9f3b2SDimitry Andric }; 122*1db9f3b2SDimitry Andric 123*1db9f3b2SDimitry Andric /// This structure is used to update reference to the DIE. 124*1db9f3b2SDimitry Andric struct DebugDieRefPatch : SectionPatch { 125*1db9f3b2SDimitry Andric DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, 126*1db9f3b2SDimitry Andric uint32_t RefIdx); 127*1db9f3b2SDimitry Andric 128*1db9f3b2SDimitry Andric PointerIntPair<CompileUnit *, 1> RefCU; 129*1db9f3b2SDimitry Andric uint64_t RefDieIdxOrClonedOffset = 0; 130*1db9f3b2SDimitry Andric }; 131*1db9f3b2SDimitry Andric 132*1db9f3b2SDimitry Andric /// This structure is used to update reference to the DIE of ULEB128 form. 133*1db9f3b2SDimitry Andric struct DebugULEB128DieRefPatch : SectionPatch { 134*1db9f3b2SDimitry Andric DebugULEB128DieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, 135*1db9f3b2SDimitry Andric CompileUnit *RefCU, uint32_t RefIdx); 136*1db9f3b2SDimitry Andric 137*1db9f3b2SDimitry Andric PointerIntPair<CompileUnit *, 1> RefCU; 138*1db9f3b2SDimitry Andric uint64_t RefDieIdxOrClonedOffset = 0; 139*1db9f3b2SDimitry Andric }; 140*1db9f3b2SDimitry Andric 141*1db9f3b2SDimitry Andric /// This structure is used to update reference to the type DIE. 142*1db9f3b2SDimitry Andric struct DebugDieTypeRefPatch : SectionPatch { 143*1db9f3b2SDimitry Andric DebugDieTypeRefPatch(uint64_t PatchOffset, TypeEntry *RefTypeName); 144*1db9f3b2SDimitry Andric 145*1db9f3b2SDimitry Andric TypeEntry *RefTypeName = nullptr; 146*1db9f3b2SDimitry Andric }; 147*1db9f3b2SDimitry Andric 148*1db9f3b2SDimitry Andric /// This structure is used to update reference to the type DIE. 149*1db9f3b2SDimitry Andric struct DebugType2TypeDieRefPatch : SectionPatch { 150*1db9f3b2SDimitry Andric DebugType2TypeDieRefPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, 151*1db9f3b2SDimitry Andric TypeEntry *RefTypeName); 152*1db9f3b2SDimitry Andric 153*1db9f3b2SDimitry Andric DIE *Die = nullptr; 154*1db9f3b2SDimitry Andric TypeEntry *TypeName = nullptr; 155*1db9f3b2SDimitry Andric TypeEntry *RefTypeName = nullptr; 156*1db9f3b2SDimitry Andric }; 157*1db9f3b2SDimitry Andric 158*1db9f3b2SDimitry Andric struct DebugTypeStrPatch : SectionPatch { 159*1db9f3b2SDimitry Andric DebugTypeStrPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, 160*1db9f3b2SDimitry Andric StringEntry *String); 161*1db9f3b2SDimitry Andric 162*1db9f3b2SDimitry Andric DIE *Die = nullptr; 163*1db9f3b2SDimitry Andric TypeEntry *TypeName = nullptr; 164*1db9f3b2SDimitry Andric StringEntry *String = nullptr; 165*1db9f3b2SDimitry Andric }; 166*1db9f3b2SDimitry Andric 167*1db9f3b2SDimitry Andric struct DebugTypeLineStrPatch : SectionPatch { 168*1db9f3b2SDimitry Andric DebugTypeLineStrPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, 169*1db9f3b2SDimitry Andric StringEntry *String); 170*1db9f3b2SDimitry Andric 171*1db9f3b2SDimitry Andric DIE *Die = nullptr; 172*1db9f3b2SDimitry Andric TypeEntry *TypeName = nullptr; 173*1db9f3b2SDimitry Andric StringEntry *String = nullptr; 174*1db9f3b2SDimitry Andric }; 175*1db9f3b2SDimitry Andric 176*1db9f3b2SDimitry Andric struct DebugTypeDeclFilePatch { 177*1db9f3b2SDimitry Andric DebugTypeDeclFilePatch(DIE *Die, TypeEntry *TypeName, StringEntry *Directory, 178*1db9f3b2SDimitry Andric StringEntry *FilePath); 179*1db9f3b2SDimitry Andric 180*1db9f3b2SDimitry Andric DIE *Die = nullptr; 181*1db9f3b2SDimitry Andric TypeEntry *TypeName = nullptr; 182*1db9f3b2SDimitry Andric StringEntry *Directory = nullptr; 183*1db9f3b2SDimitry Andric StringEntry *FilePath = nullptr; 184*1db9f3b2SDimitry Andric uint32_t FileID = 0; 185*1db9f3b2SDimitry Andric }; 186*1db9f3b2SDimitry Andric 187*1db9f3b2SDimitry Andric /// Type for section data. 188*1db9f3b2SDimitry Andric using OutSectionDataTy = SmallString<0>; 189*1db9f3b2SDimitry Andric 190*1db9f3b2SDimitry Andric /// Type for list of pointers to patches offsets. 191*1db9f3b2SDimitry Andric using OffsetsPtrVector = SmallVector<uint64_t *>; 192*1db9f3b2SDimitry Andric 193*1db9f3b2SDimitry Andric class OutputSections; 194*1db9f3b2SDimitry Andric 195*1db9f3b2SDimitry Andric /// This structure is used to keep data of the concrete section. 196*1db9f3b2SDimitry Andric /// Like data bits, list of patches, format. 197*1db9f3b2SDimitry Andric struct SectionDescriptor { 198*1db9f3b2SDimitry Andric friend OutputSections; 199*1db9f3b2SDimitry Andric 200*1db9f3b2SDimitry Andric SectionDescriptor(DebugSectionKind SectionKind, LinkingGlobalData &GlobalData, 201*1db9f3b2SDimitry Andric dwarf::FormParams Format, llvm::endianness Endianess) 202*1db9f3b2SDimitry Andric : OS(Contents), ListDebugStrPatch(&GlobalData.getAllocator()), 203*1db9f3b2SDimitry Andric ListDebugLineStrPatch(&GlobalData.getAllocator()), 204*1db9f3b2SDimitry Andric ListDebugRangePatch(&GlobalData.getAllocator()), 205*1db9f3b2SDimitry Andric ListDebugLocPatch(&GlobalData.getAllocator()), 206*1db9f3b2SDimitry Andric ListDebugDieRefPatch(&GlobalData.getAllocator()), 207*1db9f3b2SDimitry Andric ListDebugULEB128DieRefPatch(&GlobalData.getAllocator()), 208*1db9f3b2SDimitry Andric ListDebugOffsetPatch(&GlobalData.getAllocator()), 209*1db9f3b2SDimitry Andric ListDebugDieTypeRefPatch(&GlobalData.getAllocator()), 210*1db9f3b2SDimitry Andric ListDebugType2TypeDieRefPatch(&GlobalData.getAllocator()), 211*1db9f3b2SDimitry Andric ListDebugTypeStrPatch(&GlobalData.getAllocator()), 212*1db9f3b2SDimitry Andric ListDebugTypeLineStrPatch(&GlobalData.getAllocator()), 213*1db9f3b2SDimitry Andric ListDebugTypeDeclFilePatch(&GlobalData.getAllocator()), 214*1db9f3b2SDimitry Andric GlobalData(GlobalData), SectionKind(SectionKind), Format(Format), 215*1db9f3b2SDimitry Andric Endianess(Endianess) {} 216*1db9f3b2SDimitry Andric 217*1db9f3b2SDimitry Andric /// Erase whole section contents(data bits, list of patches). 218*1db9f3b2SDimitry Andric void clearAllSectionData(); 219*1db9f3b2SDimitry Andric 220*1db9f3b2SDimitry Andric /// Erase only section output data bits. 221*1db9f3b2SDimitry Andric void clearSectionContent(); 222*1db9f3b2SDimitry Andric 223*1db9f3b2SDimitry Andric /// When objects(f.e. compile units) are glued into the single file, 224*1db9f3b2SDimitry Andric /// the debug sections corresponding to the concrete object are assigned 225*1db9f3b2SDimitry Andric /// with offsets inside the whole file. This field keeps offset 226*1db9f3b2SDimitry Andric /// to the debug section, corresponding to this object. 227*1db9f3b2SDimitry Andric uint64_t StartOffset = 0; 228*1db9f3b2SDimitry Andric 229*1db9f3b2SDimitry Andric /// Stream which stores data to the Contents. 230*1db9f3b2SDimitry Andric raw_svector_ostream OS; 231*1db9f3b2SDimitry Andric 232*1db9f3b2SDimitry Andric /// Section patches. 233*1db9f3b2SDimitry Andric #define ADD_PATCHES_LIST(T) \ 234*1db9f3b2SDimitry Andric T ¬ePatch(const T &Patch) { return List##T.add(Patch); } \ 235*1db9f3b2SDimitry Andric ArrayList<T> List##T; 236*1db9f3b2SDimitry Andric 237*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugStrPatch) 238*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugLineStrPatch) 239*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugRangePatch) 240*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugLocPatch) 241*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugDieRefPatch) 242*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugULEB128DieRefPatch) 243*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugOffsetPatch) 244*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugDieTypeRefPatch) 245*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugType2TypeDieRefPatch) 246*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugTypeStrPatch) 247*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugTypeLineStrPatch) 248*1db9f3b2SDimitry Andric ADD_PATCHES_LIST(DebugTypeDeclFilePatch) 249*1db9f3b2SDimitry Andric 250*1db9f3b2SDimitry Andric /// While creating patches, offsets to attributes may be partially 251*1db9f3b2SDimitry Andric /// unknown(because size of abbreviation number is unknown). In such case we 252*1db9f3b2SDimitry Andric /// remember patch itself and pointer to patch application offset to add size 253*1db9f3b2SDimitry Andric /// of abbreviation number later. 254*1db9f3b2SDimitry Andric template <typename T> 255*1db9f3b2SDimitry Andric void notePatchWithOffsetUpdate(const T &Patch, 256*1db9f3b2SDimitry Andric OffsetsPtrVector &PatchesOffsetsList) { 257*1db9f3b2SDimitry Andric PatchesOffsetsList.emplace_back(¬ePatch(Patch).PatchOffset); 258*1db9f3b2SDimitry Andric } 259*1db9f3b2SDimitry Andric 260*1db9f3b2SDimitry Andric /// Some sections are emitted using AsmPrinter. In that case "Contents" 261*1db9f3b2SDimitry Andric /// member of SectionDescriptor contains elf file. This method searches 262*1db9f3b2SDimitry Andric /// for section data inside elf file and remember offset to it. 263*1db9f3b2SDimitry Andric void setSizesForSectionCreatedByAsmPrinter(); 264*1db9f3b2SDimitry Andric 265*1db9f3b2SDimitry Andric /// Returns section content. 266*1db9f3b2SDimitry Andric StringRef getContents() { 267*1db9f3b2SDimitry Andric if (SectionOffsetInsideAsmPrinterOutputStart == 0) 268*1db9f3b2SDimitry Andric return StringRef(Contents.data(), Contents.size()); 269*1db9f3b2SDimitry Andric 270*1db9f3b2SDimitry Andric return Contents.slice(SectionOffsetInsideAsmPrinterOutputStart, 271*1db9f3b2SDimitry Andric SectionOffsetInsideAsmPrinterOutputEnd); 272*1db9f3b2SDimitry Andric } 273*1db9f3b2SDimitry Andric 274*1db9f3b2SDimitry Andric /// Emit unit length into the current section contents. 275*1db9f3b2SDimitry Andric void emitUnitLength(uint64_t Length) { 276*1db9f3b2SDimitry Andric maybeEmitDwarf64Mark(); 277*1db9f3b2SDimitry Andric emitIntVal(Length, getFormParams().getDwarfOffsetByteSize()); 278*1db9f3b2SDimitry Andric } 279*1db9f3b2SDimitry Andric 280*1db9f3b2SDimitry Andric /// Emit DWARF64 mark into the current section contents. 281*1db9f3b2SDimitry Andric void maybeEmitDwarf64Mark() { 282*1db9f3b2SDimitry Andric if (getFormParams().Format != dwarf::DWARF64) 283*1db9f3b2SDimitry Andric return; 284*1db9f3b2SDimitry Andric emitIntVal(dwarf::DW_LENGTH_DWARF64, 4); 285*1db9f3b2SDimitry Andric } 286*1db9f3b2SDimitry Andric 287*1db9f3b2SDimitry Andric /// Emit specified offset value into the current section contents. 288*1db9f3b2SDimitry Andric void emitOffset(uint64_t Val) { 289*1db9f3b2SDimitry Andric emitIntVal(Val, getFormParams().getDwarfOffsetByteSize()); 290*1db9f3b2SDimitry Andric } 291*1db9f3b2SDimitry Andric 292*1db9f3b2SDimitry Andric /// Emit specified integer value into the current section contents. 293*1db9f3b2SDimitry Andric void emitIntVal(uint64_t Val, unsigned Size); 294*1db9f3b2SDimitry Andric 295*1db9f3b2SDimitry Andric void emitString(dwarf::Form StringForm, const char *StringVal); 296*1db9f3b2SDimitry Andric 297*1db9f3b2SDimitry Andric void emitBinaryData(llvm::StringRef Data); 298*1db9f3b2SDimitry Andric 299*1db9f3b2SDimitry Andric /// Emit specified inplace string value into the current section contents. 300*1db9f3b2SDimitry Andric void emitInplaceString(StringRef String) { 301*1db9f3b2SDimitry Andric OS << GlobalData.translateString(String); 302*1db9f3b2SDimitry Andric emitIntVal(0, 1); 303*1db9f3b2SDimitry Andric } 304*1db9f3b2SDimitry Andric 305*1db9f3b2SDimitry Andric /// Emit string placeholder into the current section contents. 306*1db9f3b2SDimitry Andric void emitStringPlaceholder() { 307*1db9f3b2SDimitry Andric // emit bad offset which should be updated later. 308*1db9f3b2SDimitry Andric emitOffset(0xBADDEF); 309*1db9f3b2SDimitry Andric } 310*1db9f3b2SDimitry Andric 311*1db9f3b2SDimitry Andric /// Write specified \p Value of \p AttrForm to the \p PatchOffset. 312*1db9f3b2SDimitry Andric void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val); 313*1db9f3b2SDimitry Andric 314*1db9f3b2SDimitry Andric /// Returns section kind. 315*1db9f3b2SDimitry Andric DebugSectionKind getKind() { return SectionKind; } 316*1db9f3b2SDimitry Andric 317*1db9f3b2SDimitry Andric /// Returns section name. 318*1db9f3b2SDimitry Andric const StringLiteral &getName() const { return getSectionName(SectionKind); } 319*1db9f3b2SDimitry Andric 320*1db9f3b2SDimitry Andric /// Returns endianess used by section. 321*1db9f3b2SDimitry Andric llvm::endianness getEndianess() const { return Endianess; } 322*1db9f3b2SDimitry Andric 323*1db9f3b2SDimitry Andric /// Returns FormParams used by section. 324*1db9f3b2SDimitry Andric dwarf::FormParams getFormParams() const { return Format; } 325*1db9f3b2SDimitry Andric 326*1db9f3b2SDimitry Andric /// Returns integer value of \p Size located by specified \p PatchOffset. 327*1db9f3b2SDimitry Andric uint64_t getIntVal(uint64_t PatchOffset, unsigned Size); 328*1db9f3b2SDimitry Andric 329*1db9f3b2SDimitry Andric protected: 330*1db9f3b2SDimitry Andric /// Writes integer value \p Val of \p Size by specified \p PatchOffset. 331*1db9f3b2SDimitry Andric void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size); 332*1db9f3b2SDimitry Andric 333*1db9f3b2SDimitry Andric /// Writes integer value \p Val of ULEB128 format by specified \p PatchOffset. 334*1db9f3b2SDimitry Andric void applyULEB128(uint64_t PatchOffset, uint64_t Val); 335*1db9f3b2SDimitry Andric 336*1db9f3b2SDimitry Andric /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset. 337*1db9f3b2SDimitry Andric void applySLEB128(uint64_t PatchOffset, uint64_t Val); 338*1db9f3b2SDimitry Andric 339*1db9f3b2SDimitry Andric /// Sets output format. 340*1db9f3b2SDimitry Andric void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianess) { 341*1db9f3b2SDimitry Andric this->Format = Format; 342*1db9f3b2SDimitry Andric this->Endianess = Endianess; 343*1db9f3b2SDimitry Andric } 344*1db9f3b2SDimitry Andric 345*1db9f3b2SDimitry Andric LinkingGlobalData &GlobalData; 346*1db9f3b2SDimitry Andric 347*1db9f3b2SDimitry Andric /// The section kind. 348*1db9f3b2SDimitry Andric DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries; 349*1db9f3b2SDimitry Andric 350*1db9f3b2SDimitry Andric /// Section data bits. 351*1db9f3b2SDimitry Andric OutSectionDataTy Contents; 352*1db9f3b2SDimitry Andric 353*1db9f3b2SDimitry Andric /// Some sections are generated using AsmPrinter. The real section data 354*1db9f3b2SDimitry Andric /// located inside elf file in that case. Following fields points to the 355*1db9f3b2SDimitry Andric /// real section content inside elf file. 356*1db9f3b2SDimitry Andric size_t SectionOffsetInsideAsmPrinterOutputStart = 0; 357*1db9f3b2SDimitry Andric size_t SectionOffsetInsideAsmPrinterOutputEnd = 0; 358*1db9f3b2SDimitry Andric 359*1db9f3b2SDimitry Andric /// Output format. 360*1db9f3b2SDimitry Andric dwarf::FormParams Format = {4, 4, dwarf::DWARF32}; 361*1db9f3b2SDimitry Andric llvm::endianness Endianess = llvm::endianness::little; 362*1db9f3b2SDimitry Andric }; 363*1db9f3b2SDimitry Andric 364*1db9f3b2SDimitry Andric /// This class keeps contents and offsets to the debug sections. Any objects 365*1db9f3b2SDimitry Andric /// which is supposed to be emitted into the debug sections should use this 366*1db9f3b2SDimitry Andric /// class to track debug sections offsets and keep sections data. 367*1db9f3b2SDimitry Andric class OutputSections { 368*1db9f3b2SDimitry Andric public: 369*1db9f3b2SDimitry Andric OutputSections(LinkingGlobalData &GlobalData) : GlobalData(GlobalData) {} 370*1db9f3b2SDimitry Andric 371*1db9f3b2SDimitry Andric /// Sets output format for all keeping sections. 372*1db9f3b2SDimitry Andric void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness) { 373*1db9f3b2SDimitry Andric this->Format = Format; 374*1db9f3b2SDimitry Andric this->Endianness = Endianness; 375*1db9f3b2SDimitry Andric } 376*1db9f3b2SDimitry Andric 377*1db9f3b2SDimitry Andric /// Returns descriptor for the specified section of \p SectionKind. 378*1db9f3b2SDimitry Andric /// The descriptor should already be created. The llvm_unreachable 379*1db9f3b2SDimitry Andric /// would be raised if it is not. 380*1db9f3b2SDimitry Andric const SectionDescriptor & 381*1db9f3b2SDimitry Andric getSectionDescriptor(DebugSectionKind SectionKind) const { 382*1db9f3b2SDimitry Andric SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind); 383*1db9f3b2SDimitry Andric 384*1db9f3b2SDimitry Andric if (It == SectionDescriptors.end()) 385*1db9f3b2SDimitry Andric llvm_unreachable( 386*1db9f3b2SDimitry Andric formatv("Section {0} does not exist", getSectionName(SectionKind)) 387*1db9f3b2SDimitry Andric .str() 388*1db9f3b2SDimitry Andric .c_str()); 389*1db9f3b2SDimitry Andric 390*1db9f3b2SDimitry Andric return It->second; 391*1db9f3b2SDimitry Andric } 392*1db9f3b2SDimitry Andric 393*1db9f3b2SDimitry Andric /// Returns descriptor for the specified section of \p SectionKind. 394*1db9f3b2SDimitry Andric /// The descriptor should already be created. The llvm_unreachable 395*1db9f3b2SDimitry Andric /// would be raised if it is not. 396*1db9f3b2SDimitry Andric SectionDescriptor &getSectionDescriptor(DebugSectionKind SectionKind) { 397*1db9f3b2SDimitry Andric SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind); 398*1db9f3b2SDimitry Andric 399*1db9f3b2SDimitry Andric if (It == SectionDescriptors.end()) 400*1db9f3b2SDimitry Andric llvm_unreachable( 401*1db9f3b2SDimitry Andric formatv("Section {0} does not exist", getSectionName(SectionKind)) 402*1db9f3b2SDimitry Andric .str() 403*1db9f3b2SDimitry Andric .c_str()); 404*1db9f3b2SDimitry Andric 405*1db9f3b2SDimitry Andric return It->second; 406*1db9f3b2SDimitry Andric } 407*1db9f3b2SDimitry Andric 408*1db9f3b2SDimitry Andric /// Returns descriptor for the specified section of \p SectionKind. 409*1db9f3b2SDimitry Andric /// Returns std::nullopt if section descriptor is not created yet. 410*1db9f3b2SDimitry Andric std::optional<const SectionDescriptor *> 411*1db9f3b2SDimitry Andric tryGetSectionDescriptor(DebugSectionKind SectionKind) const { 412*1db9f3b2SDimitry Andric SectionsSetTy::const_iterator It = SectionDescriptors.find(SectionKind); 413*1db9f3b2SDimitry Andric 414*1db9f3b2SDimitry Andric if (It == SectionDescriptors.end()) 415*1db9f3b2SDimitry Andric return std::nullopt; 416*1db9f3b2SDimitry Andric 417*1db9f3b2SDimitry Andric return &It->second; 418*1db9f3b2SDimitry Andric } 419*1db9f3b2SDimitry Andric 420*1db9f3b2SDimitry Andric /// Returns descriptor for the specified section of \p SectionKind. 421*1db9f3b2SDimitry Andric /// Returns std::nullopt if section descriptor is not created yet. 422*1db9f3b2SDimitry Andric std::optional<SectionDescriptor *> 423*1db9f3b2SDimitry Andric tryGetSectionDescriptor(DebugSectionKind SectionKind) { 424*1db9f3b2SDimitry Andric SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind); 425*1db9f3b2SDimitry Andric 426*1db9f3b2SDimitry Andric if (It == SectionDescriptors.end()) 427*1db9f3b2SDimitry Andric return std::nullopt; 428*1db9f3b2SDimitry Andric 429*1db9f3b2SDimitry Andric return &It->second; 430*1db9f3b2SDimitry Andric } 431*1db9f3b2SDimitry Andric 432*1db9f3b2SDimitry Andric /// Returns descriptor for the specified section of \p SectionKind. 433*1db9f3b2SDimitry Andric /// If descriptor does not exist then creates it. 434*1db9f3b2SDimitry Andric SectionDescriptor & 435*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind SectionKind) { 436*1db9f3b2SDimitry Andric return SectionDescriptors 437*1db9f3b2SDimitry Andric .try_emplace(SectionKind, SectionKind, GlobalData, Format, Endianness) 438*1db9f3b2SDimitry Andric .first->second; 439*1db9f3b2SDimitry Andric } 440*1db9f3b2SDimitry Andric 441*1db9f3b2SDimitry Andric /// Erases data of all sections. 442*1db9f3b2SDimitry Andric void eraseSections() { 443*1db9f3b2SDimitry Andric for (auto &Section : SectionDescriptors) 444*1db9f3b2SDimitry Andric Section.second.clearAllSectionData(); 445*1db9f3b2SDimitry Andric } 446*1db9f3b2SDimitry Andric 447*1db9f3b2SDimitry Andric /// Enumerate all sections and call \p Handler for each. 448*1db9f3b2SDimitry Andric void forEach(function_ref<void(SectionDescriptor &)> Handler) { 449*1db9f3b2SDimitry Andric for (auto &Section : SectionDescriptors) 450*1db9f3b2SDimitry Andric Handler(Section.second); 451*1db9f3b2SDimitry Andric } 452*1db9f3b2SDimitry Andric 453*1db9f3b2SDimitry Andric /// Enumerate all sections, for each section set current offset 454*1db9f3b2SDimitry Andric /// (kept by \p SectionSizesAccumulator), update current offset with section 455*1db9f3b2SDimitry Andric /// length. 456*1db9f3b2SDimitry Andric void assignSectionsOffsetAndAccumulateSize( 457*1db9f3b2SDimitry Andric std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) { 458*1db9f3b2SDimitry Andric for (auto &Section : SectionDescriptors) { 459*1db9f3b2SDimitry Andric Section.second.StartOffset = SectionSizesAccumulator[static_cast<uint8_t>( 460*1db9f3b2SDimitry Andric Section.second.getKind())]; 461*1db9f3b2SDimitry Andric SectionSizesAccumulator[static_cast<uint8_t>(Section.second.getKind())] += 462*1db9f3b2SDimitry Andric Section.second.getContents().size(); 463*1db9f3b2SDimitry Andric } 464*1db9f3b2SDimitry Andric } 465*1db9f3b2SDimitry Andric 466*1db9f3b2SDimitry Andric /// Enumerate all sections, for each section apply all section patches. 467*1db9f3b2SDimitry Andric void applyPatches(SectionDescriptor &Section, 468*1db9f3b2SDimitry Andric StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, 469*1db9f3b2SDimitry Andric StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, 470*1db9f3b2SDimitry Andric TypeUnit *TypeUnitPtr); 471*1db9f3b2SDimitry Andric 472*1db9f3b2SDimitry Andric /// Endiannes for the sections. 473*1db9f3b2SDimitry Andric llvm::endianness getEndianness() const { return Endianness; } 474*1db9f3b2SDimitry Andric 475*1db9f3b2SDimitry Andric /// Return DWARF version. 476*1db9f3b2SDimitry Andric uint16_t getVersion() const { return Format.Version; } 477*1db9f3b2SDimitry Andric 478*1db9f3b2SDimitry Andric /// Return size of header of debug_info table. 479*1db9f3b2SDimitry Andric uint16_t getDebugInfoHeaderSize() const { 480*1db9f3b2SDimitry Andric return Format.Version >= 5 ? 12 : 11; 481*1db9f3b2SDimitry Andric } 482*1db9f3b2SDimitry Andric 483*1db9f3b2SDimitry Andric /// Return size of header of debug_ table. 484*1db9f3b2SDimitry Andric uint16_t getDebugAddrHeaderSize() const { 485*1db9f3b2SDimitry Andric assert(Format.Version >= 5); 486*1db9f3b2SDimitry Andric return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16; 487*1db9f3b2SDimitry Andric } 488*1db9f3b2SDimitry Andric 489*1db9f3b2SDimitry Andric /// Return size of header of debug_str_offsets table. 490*1db9f3b2SDimitry Andric uint16_t getDebugStrOffsetsHeaderSize() const { 491*1db9f3b2SDimitry Andric assert(Format.Version >= 5); 492*1db9f3b2SDimitry Andric return Format.Format == dwarf::DwarfFormat::DWARF32 ? 8 : 16; 493*1db9f3b2SDimitry Andric } 494*1db9f3b2SDimitry Andric 495*1db9f3b2SDimitry Andric /// Return size of address. 496*1db9f3b2SDimitry Andric const dwarf::FormParams &getFormParams() const { return Format; } 497*1db9f3b2SDimitry Andric 498*1db9f3b2SDimitry Andric protected: 499*1db9f3b2SDimitry Andric LinkingGlobalData &GlobalData; 500*1db9f3b2SDimitry Andric 501*1db9f3b2SDimitry Andric /// Format for sections. 502*1db9f3b2SDimitry Andric dwarf::FormParams Format = {4, 4, dwarf::DWARF32}; 503*1db9f3b2SDimitry Andric 504*1db9f3b2SDimitry Andric /// Endiannes for sections. 505*1db9f3b2SDimitry Andric llvm::endianness Endianness = llvm::endianness::native; 506*1db9f3b2SDimitry Andric 507*1db9f3b2SDimitry Andric /// All keeping sections. 508*1db9f3b2SDimitry Andric using SectionsSetTy = std::map<DebugSectionKind, SectionDescriptor>; 509*1db9f3b2SDimitry Andric SectionsSetTy SectionDescriptors; 510*1db9f3b2SDimitry Andric }; 511*1db9f3b2SDimitry Andric 512*1db9f3b2SDimitry Andric } // end of namespace parallel 513*1db9f3b2SDimitry Andric } // end of namespace dwarf_linker 514*1db9f3b2SDimitry Andric } // end of namespace llvm 515*1db9f3b2SDimitry Andric 516*1db9f3b2SDimitry Andric #endif // LLVM_LIB_DWARFLINKER_PARALLEL_OUTPUTSECTIONS_H 517