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