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