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