1 //=== OutputSections.cpp --------------------------------------------------===// 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 #include "OutputSections.h" 10 #include "DWARFLinkerCompileUnit.h" 11 #include "DWARFLinkerTypeUnit.h" 12 #include "llvm/ADT/StringSwitch.h" 13 14 using namespace llvm; 15 using namespace dwarf_linker; 16 using namespace dwarf_linker::parallel; 17 18 std::optional<DebugSectionKind> 19 dwarf_linker::parallel::parseDebugTableName(llvm::StringRef SecName) { 20 return llvm::StringSwitch<std::optional<DebugSectionKind>>( 21 SecName.substr(SecName.find_first_not_of("._"))) 22 .Case(getSectionName(DebugSectionKind::DebugInfo), 23 DebugSectionKind::DebugInfo) 24 .Case(getSectionName(DebugSectionKind::DebugLine), 25 DebugSectionKind::DebugLine) 26 .Case(getSectionName(DebugSectionKind::DebugFrame), 27 DebugSectionKind::DebugFrame) 28 .Case(getSectionName(DebugSectionKind::DebugRange), 29 DebugSectionKind::DebugRange) 30 .Case(getSectionName(DebugSectionKind::DebugRngLists), 31 DebugSectionKind::DebugRngLists) 32 .Case(getSectionName(DebugSectionKind::DebugLoc), 33 DebugSectionKind::DebugLoc) 34 .Case(getSectionName(DebugSectionKind::DebugLocLists), 35 DebugSectionKind::DebugLocLists) 36 .Case(getSectionName(DebugSectionKind::DebugARanges), 37 DebugSectionKind::DebugARanges) 38 .Case(getSectionName(DebugSectionKind::DebugAbbrev), 39 DebugSectionKind::DebugAbbrev) 40 .Case(getSectionName(DebugSectionKind::DebugMacinfo), 41 DebugSectionKind::DebugMacinfo) 42 .Case(getSectionName(DebugSectionKind::DebugMacro), 43 DebugSectionKind::DebugMacro) 44 .Case(getSectionName(DebugSectionKind::DebugAddr), 45 DebugSectionKind::DebugAddr) 46 .Case(getSectionName(DebugSectionKind::DebugStr), 47 DebugSectionKind::DebugStr) 48 .Case(getSectionName(DebugSectionKind::DebugLineStr), 49 DebugSectionKind::DebugLineStr) 50 .Case(getSectionName(DebugSectionKind::DebugStrOffsets), 51 DebugSectionKind::DebugStrOffsets) 52 .Case(getSectionName(DebugSectionKind::DebugPubNames), 53 DebugSectionKind::DebugPubNames) 54 .Case(getSectionName(DebugSectionKind::DebugPubTypes), 55 DebugSectionKind::DebugPubTypes) 56 .Case(getSectionName(DebugSectionKind::DebugNames), 57 DebugSectionKind::DebugNames) 58 .Case(getSectionName(DebugSectionKind::AppleNames), 59 DebugSectionKind::AppleNames) 60 .Case(getSectionName(DebugSectionKind::AppleNamespaces), 61 DebugSectionKind::AppleNamespaces) 62 .Case(getSectionName(DebugSectionKind::AppleObjC), 63 DebugSectionKind::AppleObjC) 64 .Case(getSectionName(DebugSectionKind::AppleTypes), 65 DebugSectionKind::AppleTypes) 66 .Default(std::nullopt); 67 68 return std::nullopt; 69 } 70 71 DebugDieRefPatch::DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, 72 CompileUnit *RefCU, uint32_t RefIdx) 73 : SectionPatch({PatchOffset}), 74 RefCU(RefCU, (SrcCU != nullptr) && 75 (SrcCU->getUniqueID() == RefCU->getUniqueID())), 76 RefDieIdxOrClonedOffset(RefIdx) {} 77 78 DebugULEB128DieRefPatch::DebugULEB128DieRefPatch(uint64_t PatchOffset, 79 CompileUnit *SrcCU, 80 CompileUnit *RefCU, 81 uint32_t RefIdx) 82 : SectionPatch({PatchOffset}), 83 RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()), 84 RefDieIdxOrClonedOffset(RefIdx) {} 85 86 DebugDieTypeRefPatch::DebugDieTypeRefPatch(uint64_t PatchOffset, 87 TypeEntry *RefTypeName) 88 : SectionPatch({PatchOffset}), RefTypeName(RefTypeName) {} 89 90 DebugType2TypeDieRefPatch::DebugType2TypeDieRefPatch(uint64_t PatchOffset, 91 DIE *Die, 92 TypeEntry *TypeName, 93 TypeEntry *RefTypeName) 94 : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName), 95 RefTypeName(RefTypeName) {} 96 97 DebugTypeStrPatch::DebugTypeStrPatch(uint64_t PatchOffset, DIE *Die, 98 TypeEntry *TypeName, StringEntry *String) 99 : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName), 100 String(String) {} 101 102 DebugTypeLineStrPatch::DebugTypeLineStrPatch(uint64_t PatchOffset, DIE *Die, 103 TypeEntry *TypeName, 104 StringEntry *String) 105 : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName), 106 String(String) {} 107 108 DebugTypeDeclFilePatch::DebugTypeDeclFilePatch(DIE *Die, TypeEntry *TypeName, 109 StringEntry *Directory, 110 StringEntry *FilePath) 111 : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {} 112 113 void SectionDescriptor::clearAllSectionData() { 114 StartOffset = 0; 115 clearSectionContent(); 116 ListDebugStrPatch.erase(); 117 ListDebugLineStrPatch.erase(); 118 ListDebugRangePatch.erase(); 119 ListDebugLocPatch.erase(); 120 ListDebugDieRefPatch.erase(); 121 ListDebugULEB128DieRefPatch.erase(); 122 ListDebugOffsetPatch.erase(); 123 ListDebugType2TypeDieRefPatch.erase(); 124 ListDebugTypeDeclFilePatch.erase(); 125 ListDebugTypeLineStrPatch.erase(); 126 ListDebugTypeStrPatch.erase(); 127 } 128 129 void SectionDescriptor::clearSectionContent() { Contents = OutSectionDataTy(); } 130 131 void SectionDescriptor::setSizesForSectionCreatedByAsmPrinter() { 132 if (Contents.empty()) 133 return; 134 135 MemoryBufferRef Mem(Contents, "obj"); 136 Expected<std::unique_ptr<object::ObjectFile>> Obj = 137 object::ObjectFile::createObjectFile(Mem); 138 if (!Obj) { 139 consumeError(Obj.takeError()); 140 Contents.clear(); 141 return; 142 } 143 144 for (const object::SectionRef &Sect : (*Obj).get()->sections()) { 145 Expected<StringRef> SectNameOrErr = Sect.getName(); 146 if (!SectNameOrErr) { 147 consumeError(SectNameOrErr.takeError()); 148 continue; 149 } 150 if (std::optional<DebugSectionKind> SectKind = 151 parseDebugTableName(*SectNameOrErr)) { 152 if (*SectKind == SectionKind) { 153 Expected<StringRef> Data = Sect.getContents(); 154 if (!Data) { 155 consumeError(SectNameOrErr.takeError()); 156 Contents.clear(); 157 return; 158 } 159 160 SectionOffsetInsideAsmPrinterOutputStart = 161 Data->data() - Contents.data(); 162 SectionOffsetInsideAsmPrinterOutputEnd = 163 SectionOffsetInsideAsmPrinterOutputStart + Data->size(); 164 } 165 } 166 } 167 } 168 169 void SectionDescriptor::emitString(dwarf::Form StringForm, 170 const char *StringVal) { 171 assert(StringVal != nullptr); 172 173 switch (StringForm) { 174 case dwarf::DW_FORM_string: { 175 emitInplaceString(StringVal); 176 } break; 177 case dwarf::DW_FORM_strp: { 178 notePatch(DebugStrPatch{ 179 {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first}); 180 emitStringPlaceholder(); 181 } break; 182 case dwarf::DW_FORM_line_strp: { 183 notePatch(DebugLineStrPatch{ 184 {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first}); 185 emitStringPlaceholder(); 186 } break; 187 default: 188 llvm_unreachable("Unsupported string form"); 189 break; 190 }; 191 } 192 193 void SectionDescriptor::emitIntVal(uint64_t Val, unsigned Size) { 194 switch (Size) { 195 case 1: { 196 OS.write(static_cast<uint8_t>(Val)); 197 } break; 198 case 2: { 199 uint16_t ShortVal = static_cast<uint16_t>(Val); 200 if (Endianess != llvm::endianness::native) 201 sys::swapByteOrder(ShortVal); 202 OS.write(reinterpret_cast<const char *>(&ShortVal), Size); 203 } break; 204 case 4: { 205 uint32_t ShortVal = static_cast<uint32_t>(Val); 206 if (Endianess != llvm::endianness::native) 207 sys::swapByteOrder(ShortVal); 208 OS.write(reinterpret_cast<const char *>(&ShortVal), Size); 209 } break; 210 case 8: { 211 if (Endianess != llvm::endianness::native) 212 sys::swapByteOrder(Val); 213 OS.write(reinterpret_cast<const char *>(&Val), Size); 214 } break; 215 default: 216 llvm_unreachable("Unsupported integer type size"); 217 } 218 } 219 220 void SectionDescriptor::emitBinaryData(llvm::StringRef Data) { 221 OS.write(Data.data(), Data.size()); 222 } 223 224 void SectionDescriptor::apply(uint64_t PatchOffset, dwarf::Form AttrForm, 225 uint64_t Val) { 226 switch (AttrForm) { 227 case dwarf::DW_FORM_strp: 228 case dwarf::DW_FORM_line_strp: { 229 applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize()); 230 } break; 231 232 case dwarf::DW_FORM_ref_addr: { 233 applyIntVal(PatchOffset, Val, Format.getRefAddrByteSize()); 234 } break; 235 case dwarf::DW_FORM_ref1: { 236 applyIntVal(PatchOffset, Val, 1); 237 } break; 238 case dwarf::DW_FORM_ref2: { 239 applyIntVal(PatchOffset, Val, 2); 240 } break; 241 case dwarf::DW_FORM_ref4: { 242 applyIntVal(PatchOffset, Val, 4); 243 } break; 244 case dwarf::DW_FORM_ref8: { 245 applyIntVal(PatchOffset, Val, 8); 246 } break; 247 248 case dwarf::DW_FORM_data1: { 249 applyIntVal(PatchOffset, Val, 1); 250 } break; 251 case dwarf::DW_FORM_data2: { 252 applyIntVal(PatchOffset, Val, 2); 253 } break; 254 case dwarf::DW_FORM_data4: { 255 applyIntVal(PatchOffset, Val, 4); 256 } break; 257 case dwarf::DW_FORM_data8: { 258 applyIntVal(PatchOffset, Val, 8); 259 } break; 260 case dwarf::DW_FORM_udata: { 261 applyULEB128(PatchOffset, Val); 262 } break; 263 case dwarf::DW_FORM_sdata: { 264 applySLEB128(PatchOffset, Val); 265 } break; 266 case dwarf::DW_FORM_sec_offset: { 267 applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize()); 268 } break; 269 case dwarf::DW_FORM_flag: { 270 applyIntVal(PatchOffset, Val, 1); 271 } break; 272 273 default: 274 llvm_unreachable("Unsupported attribute form"); 275 break; 276 } 277 } 278 279 uint64_t SectionDescriptor::getIntVal(uint64_t PatchOffset, unsigned Size) { 280 assert(PatchOffset < getContents().size()); 281 switch (Size) { 282 case 1: { 283 return *reinterpret_cast<const uint8_t *>( 284 (getContents().data() + PatchOffset)); 285 } 286 case 2: { 287 return support::endian::read16(getContents().data() + PatchOffset, 288 Endianess); 289 } 290 case 4: { 291 return support::endian::read32(getContents().data() + PatchOffset, 292 Endianess); 293 } 294 case 8: { 295 return support::endian::read64(getContents().data() + PatchOffset, 296 Endianess); 297 } 298 } 299 llvm_unreachable("Unsupported integer type size"); 300 return 0; 301 } 302 303 void SectionDescriptor::applyIntVal(uint64_t PatchOffset, uint64_t Val, 304 unsigned Size) { 305 assert(PatchOffset < getContents().size()); 306 307 switch (Size) { 308 case 1: { 309 support::endian::write( 310 const_cast<char *>(getContents().data() + PatchOffset), 311 static_cast<uint8_t>(Val), Endianess); 312 } break; 313 case 2: { 314 support::endian::write( 315 const_cast<char *>(getContents().data() + PatchOffset), 316 static_cast<uint16_t>(Val), Endianess); 317 } break; 318 case 4: { 319 support::endian::write( 320 const_cast<char *>(getContents().data() + PatchOffset), 321 static_cast<uint32_t>(Val), Endianess); 322 } break; 323 case 8: { 324 support::endian::write( 325 const_cast<char *>(getContents().data() + PatchOffset), 326 static_cast<uint64_t>(Val), Endianess); 327 } break; 328 default: 329 llvm_unreachable("Unsupported integer type size"); 330 } 331 } 332 333 void SectionDescriptor::applyULEB128(uint64_t PatchOffset, uint64_t Val) { 334 assert(PatchOffset < getContents().size()); 335 336 uint8_t ULEB[16]; 337 uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1; 338 uint8_t RealSize = encodeULEB128(Val, ULEB, DestSize); 339 340 memcpy(const_cast<char *>(getContents().data() + PatchOffset), ULEB, 341 RealSize); 342 } 343 344 /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset. 345 void SectionDescriptor::applySLEB128(uint64_t PatchOffset, uint64_t Val) { 346 assert(PatchOffset < getContents().size()); 347 348 uint8_t SLEB[16]; 349 uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1; 350 uint8_t RealSize = encodeSLEB128(Val, SLEB, DestSize); 351 352 memcpy(const_cast<char *>(getContents().data() + PatchOffset), SLEB, 353 RealSize); 354 } 355 356 void OutputSections::applyPatches( 357 SectionDescriptor &Section, 358 StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, 359 StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, 360 TypeUnit *TypeUnitPtr) { 361 Section.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) { 362 DwarfStringPoolEntryWithExtString *Entry = 363 DebugStrStrings.getExistingEntry(Patch.String); 364 assert(Entry != nullptr); 365 366 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset); 367 }); 368 Section.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) { 369 assert(TypeUnitPtr != nullptr); 370 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load(); 371 assert(TypeEntry && 372 formatv("No data for type {0}", Patch.TypeName->getKey()) 373 .str() 374 .c_str()); 375 376 if (&TypeEntry->getFinalDie() != Patch.Die) 377 return; 378 379 DwarfStringPoolEntryWithExtString *Entry = 380 DebugStrStrings.getExistingEntry(Patch.String); 381 assert(Entry != nullptr); 382 383 Patch.PatchOffset += 384 Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber()); 385 386 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset); 387 }); 388 389 Section.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) { 390 DwarfStringPoolEntryWithExtString *Entry = 391 DebugLineStrStrings.getExistingEntry(Patch.String); 392 assert(Entry != nullptr); 393 394 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset); 395 }); 396 Section.ListDebugTypeLineStrPatch.forEach([&](DebugTypeLineStrPatch &Patch) { 397 assert(TypeUnitPtr != nullptr); 398 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load(); 399 assert(TypeEntry && 400 formatv("No data for type {0}", Patch.TypeName->getKey()) 401 .str() 402 .c_str()); 403 404 if (&TypeEntry->getFinalDie() != Patch.Die) 405 return; 406 407 DwarfStringPoolEntryWithExtString *Entry = 408 DebugLineStrStrings.getExistingEntry(Patch.String); 409 assert(Entry != nullptr); 410 411 Patch.PatchOffset += 412 Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber()); 413 414 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset); 415 }); 416 417 std::optional<SectionDescriptor *> RangeSection; 418 if (Format.Version >= 5) 419 RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRngLists); 420 else 421 RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRange); 422 423 if (RangeSection) { 424 Section.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) { 425 uint64_t FinalValue = 426 Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); 427 FinalValue += (*RangeSection)->StartOffset; 428 429 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue); 430 }); 431 } 432 433 std::optional<SectionDescriptor *> LocationSection; 434 if (Format.Version >= 5) 435 LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLocLists); 436 else 437 LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLoc); 438 439 if (LocationSection) { 440 Section.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) { 441 uint64_t FinalValue = 442 Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); 443 FinalValue += (*LocationSection)->StartOffset; 444 445 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue); 446 }); 447 } 448 449 Section.ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) { 450 uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset; 451 dwarf::Form FinalForm = dwarf::DW_FORM_ref4; 452 453 // Check whether it is local or inter-CU reference. 454 if (!Patch.RefCU.getInt()) { 455 SectionDescriptor &ReferencedSectionDescriptor = 456 Patch.RefCU.getPointer()->getSectionDescriptor( 457 DebugSectionKind::DebugInfo); 458 459 FinalForm = dwarf::DW_FORM_ref_addr; 460 FinalOffset += ReferencedSectionDescriptor.StartOffset; 461 } 462 463 Section.apply(Patch.PatchOffset, FinalForm, FinalOffset); 464 }); 465 466 Section.ListDebugULEB128DieRefPatch.forEach( 467 [&](DebugULEB128DieRefPatch &Patch) { 468 assert(Patch.RefCU.getInt()); 469 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_udata, 470 Patch.RefDieIdxOrClonedOffset); 471 }); 472 473 Section.ListDebugDieTypeRefPatch.forEach([&](DebugDieTypeRefPatch &Patch) { 474 assert(TypeUnitPtr != nullptr); 475 assert(Patch.RefTypeName != nullptr); 476 477 TypeEntryBody *TypeEntry = Patch.RefTypeName->getValue().load(); 478 assert(TypeEntry && 479 formatv("No data for type {0}", Patch.RefTypeName->getKey()) 480 .str() 481 .c_str()); 482 483 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref_addr, 484 TypeEntry->getFinalDie().getOffset()); 485 }); 486 487 Section.ListDebugType2TypeDieRefPatch.forEach( 488 [&](DebugType2TypeDieRefPatch &Patch) { 489 assert(TypeUnitPtr != nullptr); 490 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load(); 491 assert(TypeEntry && 492 formatv("No data for type {0}", Patch.TypeName->getKey()) 493 .str() 494 .c_str()); 495 496 if (&TypeEntry->getFinalDie() != Patch.Die) 497 return; 498 499 Patch.PatchOffset += Patch.Die->getOffset() + 500 getULEB128Size(Patch.Die->getAbbrevNumber()); 501 502 assert(Patch.RefTypeName != nullptr); 503 TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load(); 504 assert(TypeEntry && 505 formatv("No data for type {0}", Patch.RefTypeName->getKey()) 506 .str() 507 .c_str()); 508 509 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref4, 510 RefTypeEntry->getFinalDie().getOffset()); 511 }); 512 513 Section.ListDebugOffsetPatch.forEach([&](DebugOffsetPatch &Patch) { 514 uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset; 515 516 // Check whether we need to read value from the original location. 517 if (Patch.SectionPtr.getInt()) 518 FinalValue += 519 Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize()); 520 521 Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue); 522 }); 523 } 524