1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===// 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 // This file implements ELF object file writer information. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/DenseMap.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/ADT/iterator.h" 22 #include "llvm/BinaryFormat/ELF.h" 23 #include "llvm/MC/MCAsmBackend.h" 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCAssembler.h" 26 #include "llvm/MC/MCContext.h" 27 #include "llvm/MC/MCELFExtras.h" 28 #include "llvm/MC/MCELFObjectWriter.h" 29 #include "llvm/MC/MCExpr.h" 30 #include "llvm/MC/MCFixup.h" 31 #include "llvm/MC/MCFixupKindInfo.h" 32 #include "llvm/MC/MCFragment.h" 33 #include "llvm/MC/MCObjectWriter.h" 34 #include "llvm/MC/MCSection.h" 35 #include "llvm/MC/MCSectionELF.h" 36 #include "llvm/MC/MCSymbol.h" 37 #include "llvm/MC/MCSymbolELF.h" 38 #include "llvm/MC/MCTargetOptions.h" 39 #include "llvm/MC/MCValue.h" 40 #include "llvm/MC/StringTableBuilder.h" 41 #include "llvm/Support/Alignment.h" 42 #include "llvm/Support/Casting.h" 43 #include "llvm/Support/CommandLine.h" 44 #include "llvm/Support/Compression.h" 45 #include "llvm/Support/Endian.h" 46 #include "llvm/Support/EndianStream.h" 47 #include "llvm/Support/Error.h" 48 #include "llvm/Support/ErrorHandling.h" 49 #include "llvm/Support/LEB128.h" 50 #include "llvm/Support/MathExtras.h" 51 #include "llvm/Support/SMLoc.h" 52 #include "llvm/Support/raw_ostream.h" 53 #include "llvm/TargetParser/Host.h" 54 #include <algorithm> 55 #include <cassert> 56 #include <cstddef> 57 #include <cstdint> 58 #include <map> 59 #include <memory> 60 #include <string> 61 #include <utility> 62 #include <vector> 63 64 using namespace llvm; 65 66 #define DEBUG_TYPE "elf-object-writer" 67 68 namespace { 69 namespace stats { 70 71 STATISTIC(ELFHeaderBytes, "Total size of ELF headers"); 72 STATISTIC(SectionHeaderBytes, "Total size of section headers table"); 73 STATISTIC(AllocTextBytes, "Total size of SHF_ALLOC text sections"); 74 STATISTIC(AllocROBytes, "Total size of SHF_ALLOC readonly sections"); 75 STATISTIC(AllocRWBytes, "Total size of SHF_ALLOC read-write sections"); 76 STATISTIC(StrtabBytes, "Total size of SHT_STRTAB sections"); 77 STATISTIC(SymtabBytes, "Total size of SHT_SYMTAB sections"); 78 STATISTIC(RelocationBytes, "Total size of relocation sections"); 79 STATISTIC(DynsymBytes, "Total size of SHT_DYNSYM sections"); 80 STATISTIC(DebugBytes, "Total size of debug info sections"); 81 STATISTIC(UnwindBytes, "Total size of unwind sections"); 82 STATISTIC(OtherBytes, "Total size of uncategorized sections"); 83 84 } // namespace stats 85 86 struct ELFWriter; 87 88 bool isDwoSection(const MCSectionELF &Sec) { 89 return Sec.getName().ends_with(".dwo"); 90 } 91 92 class SymbolTableWriter { 93 ELFWriter &EWriter; 94 bool Is64Bit; 95 96 // indexes we are going to write to .symtab_shndx. 97 std::vector<uint32_t> ShndxIndexes; 98 99 // The numbel of symbols written so far. 100 unsigned NumWritten; 101 102 void createSymtabShndx(); 103 104 template <typename T> void write(T Value); 105 106 public: 107 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit); 108 109 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, 110 uint8_t other, uint32_t shndx, bool Reserved); 111 112 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; } 113 }; 114 115 struct ELFWriter { 116 ELFObjectWriter &OWriter; 117 support::endian::Writer W; 118 119 enum DwoMode { 120 AllSections, 121 NonDwoOnly, 122 DwoOnly, 123 } Mode; 124 125 static uint64_t symbolValue(const MCAssembler &Asm, const MCSymbol &Sym); 126 static bool isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol, 127 bool Used, bool Renamed); 128 129 /// Helper struct for containing some precomputed information on symbols. 130 struct ELFSymbolData { 131 const MCSymbolELF *Symbol; 132 StringRef Name; 133 uint32_t SectionIndex; 134 uint32_t Order; 135 }; 136 137 /// @} 138 /// @name Symbol Table Data 139 /// @{ 140 141 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF}; 142 143 /// @} 144 145 // This holds the symbol table index of the last local symbol. 146 unsigned LastLocalSymbolIndex = ~0u; 147 // This holds the .strtab section index. 148 unsigned StringTableIndex = ~0u; 149 // This holds the .symtab section index. 150 unsigned SymbolTableIndex = ~0u; 151 152 // Sections in the order they are to be output in the section table. 153 std::vector<MCSectionELF *> SectionTable; 154 unsigned addToSectionTable(MCSectionELF *Sec); 155 156 // TargetObjectWriter wrappers. 157 bool is64Bit() const; 158 159 uint64_t align(Align Alignment); 160 161 bool maybeWriteCompression(uint32_t ChType, uint64_t Size, 162 SmallVectorImpl<uint8_t> &CompressedContents, 163 Align Alignment); 164 165 public: 166 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS, 167 bool IsLittleEndian, DwoMode Mode) 168 : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little 169 : llvm::endianness::big), 170 Mode(Mode) {} 171 172 void writeWord(uint64_t Word) { 173 if (is64Bit()) 174 W.write<uint64_t>(Word); 175 else 176 W.write<uint32_t>(Word); 177 } 178 179 template <typename T> void write(T Val) { 180 W.write(Val); 181 } 182 183 void writeHeader(const MCAssembler &Asm); 184 185 void writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer, 186 uint32_t StringIndex, ELFSymbolData &MSD); 187 188 // Map from a signature symbol to the group section index 189 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>; 190 191 /// Compute the symbol table data 192 /// 193 /// \param Asm - The assembler. 194 /// \param RevGroupMap - Maps a signature symbol to the group section. 195 void computeSymbolTable(MCAssembler &Asm, const RevGroupMapTy &RevGroupMap); 196 197 void writeAddrsigSection(); 198 199 MCSectionELF *createRelocationSection(MCContext &Ctx, 200 const MCSectionELF &Sec); 201 202 void writeSectionHeaders(const MCAssembler &Asm); 203 204 void writeSectionData(const MCAssembler &Asm, MCSection &Sec); 205 206 void writeSectionHeaderEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 207 uint64_t Address, uint64_t Offset, uint64_t Size, 208 uint32_t Link, uint32_t Info, 209 MaybeAlign Alignment, uint64_t EntrySize); 210 211 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec); 212 213 uint64_t writeObject(MCAssembler &Asm); 214 void writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset, 215 uint64_t Size, const MCSectionELF &Section); 216 }; 217 } // end anonymous namespace 218 219 uint64_t ELFWriter::align(Align Alignment) { 220 uint64_t Offset = W.OS.tell(); 221 uint64_t NewOffset = alignTo(Offset, Alignment); 222 W.OS.write_zeros(NewOffset - Offset); 223 return NewOffset; 224 } 225 226 unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) { 227 SectionTable.push_back(Sec); 228 StrTabBuilder.add(Sec->getName()); 229 return SectionTable.size(); 230 } 231 232 void SymbolTableWriter::createSymtabShndx() { 233 if (!ShndxIndexes.empty()) 234 return; 235 236 ShndxIndexes.resize(NumWritten); 237 } 238 239 template <typename T> void SymbolTableWriter::write(T Value) { 240 EWriter.write(Value); 241 } 242 243 SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit) 244 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {} 245 246 void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, 247 uint64_t size, uint8_t other, 248 uint32_t shndx, bool Reserved) { 249 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved; 250 251 if (LargeIndex) 252 createSymtabShndx(); 253 254 if (!ShndxIndexes.empty()) { 255 if (LargeIndex) 256 ShndxIndexes.push_back(shndx); 257 else 258 ShndxIndexes.push_back(0); 259 } 260 261 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; 262 263 if (Is64Bit) { 264 write(name); // st_name 265 write(info); // st_info 266 write(other); // st_other 267 write(Index); // st_shndx 268 write(value); // st_value 269 write(size); // st_size 270 } else { 271 write(name); // st_name 272 write(uint32_t(value)); // st_value 273 write(uint32_t(size)); // st_size 274 write(info); // st_info 275 write(other); // st_other 276 write(Index); // st_shndx 277 } 278 279 ++NumWritten; 280 } 281 282 bool ELFWriter::is64Bit() const { 283 return OWriter.TargetObjectWriter->is64Bit(); 284 } 285 286 // Emit the ELF header. 287 void ELFWriter::writeHeader(const MCAssembler &Asm) { 288 // ELF Header 289 // ---------- 290 // 291 // Note 292 // ---- 293 // emitWord method behaves differently for ELF32 and ELF64, writing 294 // 4 bytes in the former and 8 in the latter. 295 296 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3] 297 298 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 299 300 // e_ident[EI_DATA] 301 W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB 302 : ELF::ELFDATA2MSB); 303 304 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION] 305 // e_ident[EI_OSABI] 306 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI(); 307 W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi() 308 ? int(ELF::ELFOSABI_GNU) 309 : OSABI); 310 // e_ident[EI_ABIVERSION] 311 W.OS << char(OWriter.OverrideABIVersion 312 ? *OWriter.OverrideABIVersion 313 : OWriter.TargetObjectWriter->getABIVersion()); 314 315 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD); 316 317 W.write<uint16_t>(ELF::ET_REL); // e_type 318 319 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target 320 321 W.write<uint32_t>(ELF::EV_CURRENT); // e_version 322 writeWord(0); // e_entry, no entry point in .o file 323 writeWord(0); // e_phoff, no program header for .o 324 writeWord(0); // e_shoff = sec hdr table off in bytes 325 326 // e_flags = whatever the target wants 327 W.write<uint32_t>(OWriter.getELFHeaderEFlags()); 328 329 // e_ehsize = ELF header size 330 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr) 331 : sizeof(ELF::Elf32_Ehdr)); 332 333 W.write<uint16_t>(0); // e_phentsize = prog header entry size 334 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0 335 336 // e_shentsize = Section header entry size 337 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr) 338 : sizeof(ELF::Elf32_Shdr)); 339 340 // e_shnum = # of section header ents 341 W.write<uint16_t>(0); 342 343 // e_shstrndx = Section # of '.strtab' 344 assert(StringTableIndex < ELF::SHN_LORESERVE); 345 W.write<uint16_t>(StringTableIndex); 346 } 347 348 uint64_t ELFWriter::symbolValue(const MCAssembler &Asm, const MCSymbol &Sym) { 349 if (Sym.isCommon()) 350 return Sym.getCommonAlignment()->value(); 351 352 uint64_t Res; 353 if (!Asm.getSymbolOffset(Sym, Res)) 354 return 0; 355 356 if (Asm.isThumbFunc(&Sym)) 357 Res |= 1; 358 359 return Res; 360 } 361 362 static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { 363 uint8_t Type = newType; 364 365 // Propagation rules: 366 // IFUNC > FUNC > OBJECT > NOTYPE 367 // TLS_OBJECT > OBJECT > NOTYPE 368 // 369 // dont let the new type degrade the old type 370 switch (origType) { 371 default: 372 break; 373 case ELF::STT_GNU_IFUNC: 374 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT || 375 Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS) 376 Type = ELF::STT_GNU_IFUNC; 377 break; 378 case ELF::STT_FUNC: 379 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || 380 Type == ELF::STT_TLS) 381 Type = ELF::STT_FUNC; 382 break; 383 case ELF::STT_OBJECT: 384 if (Type == ELF::STT_NOTYPE) 385 Type = ELF::STT_OBJECT; 386 break; 387 case ELF::STT_TLS: 388 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || 389 Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC) 390 Type = ELF::STT_TLS; 391 break; 392 } 393 394 return Type; 395 } 396 397 static bool isIFunc(const MCSymbolELF *Symbol) { 398 while (Symbol->getType() != ELF::STT_GNU_IFUNC) { 399 const MCSymbolRefExpr *Value; 400 if (!Symbol->isVariable() || 401 !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) || 402 Value->getKind() != MCSymbolRefExpr::VK_None || 403 mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC) 404 return false; 405 Symbol = &cast<MCSymbolELF>(Value->getSymbol()); 406 } 407 return true; 408 } 409 410 void ELFWriter::writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer, 411 uint32_t StringIndex, ELFSymbolData &MSD) { 412 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol); 413 const MCSymbolELF *Base = 414 cast_or_null<MCSymbolELF>(Asm.getBaseSymbol(Symbol)); 415 416 // This has to be in sync with when computeSymbolTable uses SHN_ABS or 417 // SHN_COMMON. 418 bool IsReserved = !Base || Symbol.isCommon(); 419 420 // Binding and Type share the same byte as upper and lower nibbles 421 uint8_t Binding = Symbol.getBinding(); 422 uint8_t Type = Symbol.getType(); 423 if (isIFunc(&Symbol)) 424 Type = ELF::STT_GNU_IFUNC; 425 if (Base) { 426 Type = mergeTypeForSet(Type, Base->getType()); 427 } 428 uint8_t Info = (Binding << 4) | Type; 429 430 // Other and Visibility share the same byte with Visibility using the lower 431 // 2 bits 432 uint8_t Visibility = Symbol.getVisibility(); 433 uint8_t Other = Symbol.getOther() | Visibility; 434 435 uint64_t Value = symbolValue(Asm, *MSD.Symbol); 436 uint64_t Size = 0; 437 438 const MCExpr *ESize = MSD.Symbol->getSize(); 439 if (!ESize && Base) { 440 // For expressions like .set y, x+1, if y's size is unset, inherit from x. 441 ESize = Base->getSize(); 442 443 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z, 444 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give 445 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most 446 // needs. MCBinaryExpr is not handled. 447 const MCSymbolELF *Sym = &Symbol; 448 while (Sym->isVariable()) { 449 if (auto *Expr = 450 dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) { 451 Sym = cast<MCSymbolELF>(&Expr->getSymbol()); 452 if (!Sym->getSize()) 453 continue; 454 ESize = Sym->getSize(); 455 } 456 break; 457 } 458 } 459 460 if (ESize) { 461 int64_t Res; 462 if (!ESize->evaluateKnownAbsolute(Res, Asm)) 463 report_fatal_error("Size expression must be absolute."); 464 Size = Res; 465 } 466 467 // Write out the symbol table entry 468 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex, 469 IsReserved); 470 } 471 472 bool ELFWriter::isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol, 473 bool Used, bool Renamed) { 474 if (Symbol.isVariable()) { 475 const MCExpr *Expr = Symbol.getVariableValue(); 476 // Target Expressions that are always inlined do not appear in the symtab 477 if (const auto *T = dyn_cast<MCTargetExpr>(Expr)) 478 if (T->inlineAssignedExpr()) 479 return false; 480 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { 481 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) 482 return false; 483 } 484 } 485 486 if (Used) 487 return true; 488 489 if (Renamed) 490 return false; 491 492 if (Symbol.isVariable() && Symbol.isUndefined()) { 493 // FIXME: this is here just to diagnose the case of a var = commmon_sym. 494 Asm.getBaseSymbol(Symbol); 495 return false; 496 } 497 498 if (Symbol.isTemporary()) 499 return false; 500 501 if (Symbol.getType() == ELF::STT_SECTION) 502 return false; 503 504 return true; 505 } 506 507 void ELFWriter::computeSymbolTable(MCAssembler &Asm, 508 const RevGroupMapTy &RevGroupMap) { 509 MCContext &Ctx = Asm.getContext(); 510 SymbolTableWriter Writer(*this, is64Bit()); 511 512 // Symbol table 513 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 514 MCSectionELF *SymtabSection = 515 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize); 516 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4)); 517 SymbolTableIndex = addToSectionTable(SymtabSection); 518 519 uint64_t SecStart = align(SymtabSection->getAlign()); 520 521 // The first entry is the undefined symbol entry. 522 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); 523 524 std::vector<ELFSymbolData> LocalSymbolData; 525 std::vector<ELFSymbolData> ExternalSymbolData; 526 MutableArrayRef<std::pair<std::string, size_t>> FileNames = 527 OWriter.getFileNames(); 528 for (const std::pair<std::string, size_t> &F : FileNames) 529 StrTabBuilder.add(F.first); 530 531 // Add the data for the symbols. 532 bool HasLargeSectionIndex = false; 533 for (auto It : llvm::enumerate(Asm.symbols())) { 534 const auto &Symbol = cast<MCSymbolELF>(It.value()); 535 bool Used = Symbol.isUsedInReloc(); 536 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc(); 537 bool isSignature = Symbol.isSignature(); 538 539 if (!isInSymtab(Asm, Symbol, Used || WeakrefUsed || isSignature, 540 OWriter.Renames.count(&Symbol))) 541 continue; 542 543 if (Symbol.isTemporary() && Symbol.isUndefined()) { 544 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName()); 545 continue; 546 } 547 548 ELFSymbolData MSD; 549 MSD.Symbol = cast<MCSymbolELF>(&Symbol); 550 MSD.Order = It.index(); 551 552 bool Local = Symbol.getBinding() == ELF::STB_LOCAL; 553 assert(Local || !Symbol.isTemporary()); 554 555 if (Symbol.isAbsolute()) { 556 MSD.SectionIndex = ELF::SHN_ABS; 557 } else if (Symbol.isCommon()) { 558 if (Symbol.isTargetCommon()) { 559 MSD.SectionIndex = Symbol.getIndex(); 560 } else { 561 assert(!Local); 562 MSD.SectionIndex = ELF::SHN_COMMON; 563 } 564 } else if (Symbol.isUndefined()) { 565 if (isSignature && !Used) { 566 MSD.SectionIndex = RevGroupMap.lookup(&Symbol); 567 if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 568 HasLargeSectionIndex = true; 569 } else { 570 MSD.SectionIndex = ELF::SHN_UNDEF; 571 } 572 } else { 573 const MCSectionELF &Section = 574 static_cast<const MCSectionELF &>(Symbol.getSection()); 575 576 // We may end up with a situation when section symbol is technically 577 // defined, but should not be. That happens because we explicitly 578 // pre-create few .debug_* sections to have accessors. 579 // And if these sections were not really defined in the code, but were 580 // referenced, we simply error out. 581 if (!Section.isRegistered()) { 582 assert(static_cast<const MCSymbolELF &>(Symbol).getType() == 583 ELF::STT_SECTION); 584 Ctx.reportError(SMLoc(), 585 "Undefined section reference: " + Symbol.getName()); 586 continue; 587 } 588 589 if (Mode == NonDwoOnly && isDwoSection(Section)) 590 continue; 591 MSD.SectionIndex = Section.getOrdinal(); 592 assert(MSD.SectionIndex && "Invalid section index!"); 593 if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 594 HasLargeSectionIndex = true; 595 } 596 597 // Temporary symbols generated for certain assembler features (.eh_frame, 598 // .debug_line) of an empty name may be referenced by relocations due to 599 // linker relaxation. Rename them to ".L0 " to match the gas fake label name 600 // and allow ld/objcopy --discard-locals to discard such symbols. 601 StringRef Name = Symbol.getName(); 602 if (Name.empty()) 603 Name = ".L0 "; 604 605 // Sections have their own string table 606 if (Symbol.getType() != ELF::STT_SECTION) { 607 MSD.Name = Name; 608 StrTabBuilder.add(Name); 609 } 610 611 if (Local) 612 LocalSymbolData.push_back(MSD); 613 else 614 ExternalSymbolData.push_back(MSD); 615 } 616 617 // This holds the .symtab_shndx section index. 618 unsigned SymtabShndxSectionIndex = 0; 619 620 if (HasLargeSectionIndex) { 621 MCSectionELF *SymtabShndxSection = 622 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4); 623 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection); 624 SymtabShndxSection->setAlignment(Align(4)); 625 } 626 627 StrTabBuilder.finalize(); 628 629 // Make the first STT_FILE precede previous local symbols. 630 unsigned Index = 1; 631 auto FileNameIt = FileNames.begin(); 632 if (!FileNames.empty()) 633 FileNames[0].second = 0; 634 635 for (ELFSymbolData &MSD : LocalSymbolData) { 636 // Emit STT_FILE symbols before their associated local symbols. 637 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order; 638 ++FileNameIt) { 639 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first), 640 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT, 641 ELF::SHN_ABS, true); 642 ++Index; 643 } 644 645 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION 646 ? 0 647 : StrTabBuilder.getOffset(MSD.Name); 648 MSD.Symbol->setIndex(Index++); 649 writeSymbol(Asm, Writer, StringIndex, MSD); 650 } 651 for (; FileNameIt != FileNames.end(); ++FileNameIt) { 652 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first), 653 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT, 654 ELF::SHN_ABS, true); 655 ++Index; 656 } 657 658 // Write the symbol table entries. 659 LastLocalSymbolIndex = Index; 660 661 for (ELFSymbolData &MSD : ExternalSymbolData) { 662 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name); 663 MSD.Symbol->setIndex(Index++); 664 writeSymbol(Asm, Writer, StringIndex, MSD); 665 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL); 666 } 667 668 uint64_t SecEnd = W.OS.tell(); 669 SymtabSection->setOffsets(SecStart, SecEnd); 670 671 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes(); 672 if (ShndxIndexes.empty()) { 673 assert(SymtabShndxSectionIndex == 0); 674 return; 675 } 676 assert(SymtabShndxSectionIndex != 0); 677 678 SecStart = W.OS.tell(); 679 MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1]; 680 for (uint32_t Index : ShndxIndexes) 681 write(Index); 682 SecEnd = W.OS.tell(); 683 SymtabShndxSection->setOffsets(SecStart, SecEnd); 684 } 685 686 void ELFWriter::writeAddrsigSection() { 687 for (const MCSymbol *Sym : OWriter.getAddrsigSyms()) 688 if (Sym->getIndex() != 0) 689 encodeULEB128(Sym->getIndex(), W.OS); 690 } 691 692 MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx, 693 const MCSectionELF &Sec) { 694 if (OWriter.Relocations[&Sec].empty()) 695 return nullptr; 696 697 unsigned Flags = ELF::SHF_INFO_LINK; 698 if (Sec.getFlags() & ELF::SHF_GROUP) 699 Flags = ELF::SHF_GROUP; 700 701 const StringRef SectionName = Sec.getName(); 702 const MCTargetOptions *TO = Ctx.getTargetOptions(); 703 if (TO && TO->Crel) { 704 MCSectionELF *RelaSection = 705 Ctx.createELFRelSection(".crel" + SectionName, ELF::SHT_CREL, Flags, 706 /*EntrySize=*/1, Sec.getGroup(), &Sec); 707 return RelaSection; 708 } 709 710 const bool Rela = OWriter.usesRela(TO, Sec); 711 unsigned EntrySize; 712 if (Rela) 713 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 714 else 715 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 716 717 MCSectionELF *RelaSection = 718 Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName), 719 Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, 720 EntrySize, Sec.getGroup(), &Sec); 721 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4)); 722 return RelaSection; 723 } 724 725 // Include the debug info compression header. 726 bool ELFWriter::maybeWriteCompression( 727 uint32_t ChType, uint64_t Size, 728 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) { 729 uint64_t HdrSize = 730 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr); 731 if (Size <= HdrSize + CompressedContents.size()) 732 return false; 733 // Platform specific header is followed by compressed data. 734 if (is64Bit()) { 735 // Write Elf64_Chdr header. 736 write(static_cast<ELF::Elf64_Word>(ChType)); 737 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field. 738 write(static_cast<ELF::Elf64_Xword>(Size)); 739 write(static_cast<ELF::Elf64_Xword>(Alignment.value())); 740 } else { 741 // Write Elf32_Chdr header otherwise. 742 write(static_cast<ELF::Elf32_Word>(ChType)); 743 write(static_cast<ELF::Elf32_Word>(Size)); 744 write(static_cast<ELF::Elf32_Word>(Alignment.value())); 745 } 746 return true; 747 } 748 749 void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec) { 750 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); 751 StringRef SectionName = Section.getName(); 752 auto &Ctx = Asm.getContext(); 753 const DebugCompressionType CompressionType = 754 Ctx.getTargetOptions() ? Ctx.getTargetOptions()->CompressDebugSections 755 : DebugCompressionType::None; 756 if (CompressionType == DebugCompressionType::None || 757 !SectionName.starts_with(".debug_")) { 758 Asm.writeSectionData(W.OS, &Section); 759 return; 760 } 761 762 SmallVector<char, 128> UncompressedData; 763 raw_svector_ostream VecOS(UncompressedData); 764 Asm.writeSectionData(VecOS, &Section); 765 ArrayRef<uint8_t> Uncompressed = 766 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()), 767 UncompressedData.size()); 768 769 SmallVector<uint8_t, 128> Compressed; 770 uint32_t ChType; 771 switch (CompressionType) { 772 case DebugCompressionType::None: 773 llvm_unreachable("has been handled"); 774 case DebugCompressionType::Zlib: 775 ChType = ELF::ELFCOMPRESS_ZLIB; 776 break; 777 case DebugCompressionType::Zstd: 778 ChType = ELF::ELFCOMPRESS_ZSTD; 779 break; 780 } 781 compression::compress(compression::Params(CompressionType), Uncompressed, 782 Compressed); 783 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed, 784 Sec.getAlign())) { 785 W.OS << UncompressedData; 786 return; 787 } 788 789 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); 790 // Alignment field should reflect the requirements of 791 // the compressed section header. 792 Section.setAlignment(is64Bit() ? Align(8) : Align(4)); 793 W.OS << toStringRef(Compressed); 794 } 795 796 void ELFWriter::writeSectionHeaderEntry(uint32_t Name, uint32_t Type, 797 uint64_t Flags, uint64_t Address, 798 uint64_t Offset, uint64_t Size, 799 uint32_t Link, uint32_t Info, 800 MaybeAlign Alignment, 801 uint64_t EntrySize) { 802 W.write<uint32_t>(Name); // sh_name: index into string table 803 W.write<uint32_t>(Type); // sh_type 804 writeWord(Flags); // sh_flags 805 writeWord(Address); // sh_addr 806 writeWord(Offset); // sh_offset 807 writeWord(Size); // sh_size 808 W.write<uint32_t>(Link); // sh_link 809 W.write<uint32_t>(Info); // sh_info 810 writeWord(Alignment ? Alignment->value() : 0); // sh_addralign 811 writeWord(EntrySize); // sh_entsize 812 } 813 814 template <bool Is64> 815 static void encodeCrel(ArrayRef<ELFRelocationEntry> Relocs, raw_ostream &OS) { 816 using uint = std::conditional_t<Is64, uint64_t, uint32_t>; 817 ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) { 818 uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0; 819 return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type, 820 std::make_signed_t<uint>(R.Addend)}; 821 }); 822 } 823 824 void ELFWriter::writeRelocations(const MCAssembler &Asm, 825 const MCSectionELF &Sec) { 826 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec]; 827 const MCTargetOptions *TO = Asm.getContext().getTargetOptions(); 828 const bool Rela = OWriter.usesRela(TO, Sec); 829 830 // Sort the relocation entries. MIPS needs this. 831 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs); 832 833 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) { 834 for (const ELFRelocationEntry &Entry : Relocs) { 835 uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; 836 if (is64Bit()) { 837 write(Entry.Offset); 838 write(uint32_t(SymIdx)); 839 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type)); 840 write(OWriter.TargetObjectWriter->getRType3(Entry.Type)); 841 write(OWriter.TargetObjectWriter->getRType2(Entry.Type)); 842 write(OWriter.TargetObjectWriter->getRType(Entry.Type)); 843 if (Rela) 844 write(Entry.Addend); 845 } else { 846 write(uint32_t(Entry.Offset)); 847 ELF::Elf32_Rela ERE32; 848 ERE32.setSymbolAndType(SymIdx, Entry.Type); 849 write(ERE32.r_info); 850 if (Rela) 851 write(uint32_t(Entry.Addend)); 852 if (uint32_t RType = 853 OWriter.TargetObjectWriter->getRType2(Entry.Type)) { 854 write(uint32_t(Entry.Offset)); 855 ERE32.setSymbolAndType(0, RType); 856 write(ERE32.r_info); 857 write(uint32_t(0)); 858 } 859 if (uint32_t RType = 860 OWriter.TargetObjectWriter->getRType3(Entry.Type)) { 861 write(uint32_t(Entry.Offset)); 862 ERE32.setSymbolAndType(0, RType); 863 write(ERE32.r_info); 864 write(uint32_t(0)); 865 } 866 } 867 } 868 } else if (TO && TO->Crel) { 869 if (is64Bit()) 870 encodeCrel<true>(Relocs, W.OS); 871 else 872 encodeCrel<false>(Relocs, W.OS); 873 } else { 874 for (const ELFRelocationEntry &Entry : Relocs) { 875 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; 876 if (is64Bit()) { 877 write(Entry.Offset); 878 ELF::Elf64_Rela ERE; 879 ERE.setSymbolAndType(Symidx, Entry.Type); 880 write(ERE.r_info); 881 if (Rela) 882 write(Entry.Addend); 883 } else { 884 write(uint32_t(Entry.Offset)); 885 ELF::Elf32_Rela ERE; 886 ERE.setSymbolAndType(Symidx, Entry.Type); 887 write(ERE.r_info); 888 if (Rela) 889 write(uint32_t(Entry.Addend)); 890 } 891 } 892 } 893 } 894 895 void ELFWriter::writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset, 896 uint64_t Size, const MCSectionELF &Section) { 897 uint64_t sh_link = 0; 898 uint64_t sh_info = 0; 899 900 switch(Section.getType()) { 901 default: 902 // Nothing to do. 903 break; 904 905 case ELF::SHT_DYNAMIC: 906 llvm_unreachable("SHT_DYNAMIC in a relocatable object"); 907 908 case ELF::SHT_REL: 909 case ELF::SHT_RELA: 910 case ELF::SHT_CREL: { 911 sh_link = SymbolTableIndex; 912 assert(sh_link && ".symtab not found"); 913 const MCSection *InfoSection = Section.getLinkedToSection(); 914 sh_info = InfoSection->getOrdinal(); 915 break; 916 } 917 918 case ELF::SHT_SYMTAB: 919 sh_link = StringTableIndex; 920 sh_info = LastLocalSymbolIndex; 921 break; 922 923 case ELF::SHT_SYMTAB_SHNDX: 924 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 925 case ELF::SHT_LLVM_ADDRSIG: 926 sh_link = SymbolTableIndex; 927 break; 928 929 case ELF::SHT_GROUP: 930 sh_link = SymbolTableIndex; 931 sh_info = GroupSymbolIndex; 932 break; 933 } 934 935 if (Section.getFlags() & ELF::SHF_LINK_ORDER) { 936 // If the value in the associated metadata is not a definition, Sym will be 937 // undefined. Represent this with sh_link=0. 938 const MCSymbol *Sym = Section.getLinkedToSymbol(); 939 if (Sym && Sym->isInSection()) 940 sh_link = Sym->getSection().getOrdinal(); 941 } 942 943 writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()), 944 Section.getType(), Section.getFlags(), 0, Offset, 945 Size, sh_link, sh_info, Section.getAlign(), 946 Section.getEntrySize()); 947 } 948 949 void ELFWriter::writeSectionHeaders(const MCAssembler &Asm) { 950 uint64_t Start = W.OS.tell(); 951 const unsigned NumSections = SectionTable.size(); 952 953 // Null section first. 954 uint64_t FirstSectionSize = 955 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0; 956 writeSectionHeaderEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 957 0); 958 959 for (const MCSectionELF *Section : SectionTable) { 960 uint32_t GroupSymbolIndex; 961 unsigned Type = Section->getType(); 962 if (Type != ELF::SHT_GROUP) 963 GroupSymbolIndex = 0; 964 else 965 GroupSymbolIndex = Section->getGroup()->getIndex(); 966 967 std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets(); 968 uint64_t Size; 969 if (Type == ELF::SHT_NOBITS) 970 Size = Asm.getSectionAddressSize(*Section); 971 else 972 Size = Offsets.second - Offsets.first; 973 974 auto SectionHasFlag = [&](uint64_t Flag) -> bool { 975 return Section->getFlags() & Flag; 976 }; 977 978 if (Section->getName().starts_with(".debug")) { 979 stats::DebugBytes += Size; 980 } else if (Section->getName().starts_with(".eh_frame")) { 981 stats::UnwindBytes += Size; 982 } else if (SectionHasFlag(ELF::SHF_ALLOC)) { 983 if (SectionHasFlag(ELF::SHF_EXECINSTR)) { 984 stats::AllocTextBytes += Size; 985 } else if (SectionHasFlag(ELF::SHF_WRITE)) { 986 stats::AllocRWBytes += Size; 987 } else { 988 stats::AllocROBytes += Size; 989 } 990 } else { 991 switch (Section->getType()) { 992 case ELF::SHT_STRTAB: 993 stats::StrtabBytes += Size; 994 break; 995 case ELF::SHT_SYMTAB: 996 stats::SymtabBytes += Size; 997 break; 998 case ELF::SHT_DYNSYM: 999 stats::DynsymBytes += Size; 1000 break; 1001 case ELF::SHT_REL: 1002 case ELF::SHT_RELA: 1003 case ELF::SHT_CREL: 1004 stats::RelocationBytes += Size; 1005 break; 1006 default: 1007 stats::OtherBytes += Size; 1008 break; 1009 } 1010 } 1011 1012 writeSectionHeader(GroupSymbolIndex, Offsets.first, Size, *Section); 1013 } 1014 1015 stats::SectionHeaderBytes += W.OS.tell() - Start; 1016 } 1017 1018 uint64_t ELFWriter::writeObject(MCAssembler &Asm) { 1019 uint64_t StartOffset = W.OS.tell(); 1020 1021 MCContext &Ctx = Asm.getContext(); 1022 MCSectionELF *StrtabSection = 1023 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); 1024 StringTableIndex = addToSectionTable(StrtabSection); 1025 1026 RevGroupMapTy RevGroupMap; 1027 1028 // Write out the ELF header ... 1029 writeHeader(Asm); 1030 1031 stats::ELFHeaderBytes += W.OS.tell() - StartOffset; 1032 1033 // ... then the sections ... 1034 SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups; 1035 // Map from group section index to group 1036 SmallVector<unsigned, 0> GroupMap; 1037 SmallVector<MCSectionELF *> Relocations; 1038 for (MCSection &Sec : Asm) { 1039 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); 1040 if (Mode == NonDwoOnly && isDwoSection(Section)) 1041 continue; 1042 if (Mode == DwoOnly && !isDwoSection(Section)) 1043 continue; 1044 1045 // Remember the offset into the file for this section. 1046 const uint64_t SecStart = align(Section.getAlign()); 1047 1048 const MCSymbolELF *SignatureSymbol = Section.getGroup(); 1049 writeSectionData(Asm, Section); 1050 1051 uint64_t SecEnd = W.OS.tell(); 1052 Section.setOffsets(SecStart, SecEnd); 1053 1054 MCSectionELF *RelSection = createRelocationSection(Ctx, Section); 1055 1056 unsigned *GroupIdxEntry = nullptr; 1057 if (SignatureSymbol) { 1058 GroupIdxEntry = &RevGroupMap[SignatureSymbol]; 1059 if (!*GroupIdxEntry) { 1060 MCSectionELF *Group = 1061 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat()); 1062 *GroupIdxEntry = addToSectionTable(Group); 1063 Group->setAlignment(Align(4)); 1064 1065 GroupMap.resize(*GroupIdxEntry + 1); 1066 GroupMap[*GroupIdxEntry] = Groups.size(); 1067 Groups.emplace_back(Group, SmallVector<unsigned>{}); 1068 } 1069 } 1070 1071 Section.setOrdinal(addToSectionTable(&Section)); 1072 if (RelSection) { 1073 RelSection->setOrdinal(addToSectionTable(RelSection)); 1074 Relocations.push_back(RelSection); 1075 } 1076 1077 if (GroupIdxEntry) { 1078 auto &Members = Groups[GroupMap[*GroupIdxEntry]]; 1079 Members.second.push_back(Section.getOrdinal()); 1080 if (RelSection) 1081 Members.second.push_back(RelSection->getOrdinal()); 1082 } 1083 } 1084 1085 for (auto &[Group, Members] : Groups) { 1086 // Remember the offset into the file for this section. 1087 const uint64_t SecStart = align(Group->getAlign()); 1088 1089 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0)); 1090 W.write<unsigned>(Members); 1091 1092 uint64_t SecEnd = W.OS.tell(); 1093 Group->setOffsets(SecStart, SecEnd); 1094 } 1095 1096 if (Mode == DwoOnly) { 1097 // dwo files don't have symbol tables or relocations, but they do have 1098 // string tables. 1099 StrTabBuilder.finalize(); 1100 } else { 1101 MCSectionELF *AddrsigSection; 1102 if (OWriter.getEmitAddrsigSection()) { 1103 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG, 1104 ELF::SHF_EXCLUDE); 1105 addToSectionTable(AddrsigSection); 1106 } 1107 1108 // Compute symbol table information. 1109 computeSymbolTable(Asm, RevGroupMap); 1110 1111 for (MCSectionELF *RelSection : Relocations) { 1112 // Remember the offset into the file for this section. 1113 const uint64_t SecStart = align(RelSection->getAlign()); 1114 1115 writeRelocations(Asm, 1116 cast<MCSectionELF>(*RelSection->getLinkedToSection())); 1117 1118 uint64_t SecEnd = W.OS.tell(); 1119 RelSection->setOffsets(SecStart, SecEnd); 1120 } 1121 1122 if (OWriter.getEmitAddrsigSection()) { 1123 uint64_t SecStart = W.OS.tell(); 1124 writeAddrsigSection(); 1125 uint64_t SecEnd = W.OS.tell(); 1126 AddrsigSection->setOffsets(SecStart, SecEnd); 1127 } 1128 } 1129 1130 { 1131 uint64_t SecStart = W.OS.tell(); 1132 StrTabBuilder.write(W.OS); 1133 StrtabSection->setOffsets(SecStart, W.OS.tell()); 1134 } 1135 1136 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4)); 1137 1138 // ... then the section header table ... 1139 writeSectionHeaders(Asm); 1140 1141 uint16_t NumSections = support::endian::byte_swap<uint16_t>( 1142 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF 1143 : SectionTable.size() + 1, 1144 W.Endian); 1145 unsigned NumSectionsOffset; 1146 1147 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS); 1148 if (is64Bit()) { 1149 uint64_t Val = 1150 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian); 1151 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), 1152 offsetof(ELF::Elf64_Ehdr, e_shoff)); 1153 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum); 1154 } else { 1155 uint32_t Val = 1156 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian); 1157 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), 1158 offsetof(ELF::Elf32_Ehdr, e_shoff)); 1159 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum); 1160 } 1161 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections), 1162 NumSectionsOffset); 1163 1164 return W.OS.tell() - StartOffset; 1165 } 1166 1167 ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW, 1168 raw_pwrite_stream &OS, bool IsLittleEndian) 1169 : TargetObjectWriter(std::move(MOTW)), OS(OS), 1170 IsLittleEndian(IsLittleEndian) {} 1171 ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW, 1172 raw_pwrite_stream &OS, 1173 raw_pwrite_stream &DwoOS, bool IsLittleEndian) 1174 : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS), 1175 IsLittleEndian(IsLittleEndian) {} 1176 1177 void ELFObjectWriter::reset() { 1178 ELFHeaderEFlags = 0; 1179 SeenGnuAbi = false; 1180 OverrideABIVersion.reset(); 1181 Relocations.clear(); 1182 Renames.clear(); 1183 Symvers.clear(); 1184 MCObjectWriter::reset(); 1185 } 1186 1187 bool ELFObjectWriter::hasRelocationAddend() const { 1188 return TargetObjectWriter->hasRelocationAddend(); 1189 } 1190 1191 void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) { 1192 // The presence of symbol versions causes undefined symbols and 1193 // versions declared with @@@ to be renamed. 1194 for (const Symver &S : Symvers) { 1195 StringRef AliasName = S.Name; 1196 const auto &Symbol = cast<MCSymbolELF>(*S.Sym); 1197 size_t Pos = AliasName.find('@'); 1198 assert(Pos != StringRef::npos); 1199 1200 StringRef Prefix = AliasName.substr(0, Pos); 1201 StringRef Rest = AliasName.substr(Pos); 1202 StringRef Tail = Rest; 1203 if (Rest.starts_with("@@@")) 1204 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1); 1205 1206 auto *Alias = 1207 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail)); 1208 Asm.registerSymbol(*Alias); 1209 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext()); 1210 Alias->setVariableValue(Value); 1211 1212 // Aliases defined with .symvar copy the binding from the symbol they alias. 1213 // This is the first place we are able to copy this information. 1214 Alias->setBinding(Symbol.getBinding()); 1215 Alias->setVisibility(Symbol.getVisibility()); 1216 Alias->setOther(Symbol.getOther()); 1217 1218 if (!Symbol.isUndefined() && S.KeepOriginalSym) 1219 continue; 1220 1221 if (Symbol.isUndefined() && Rest.starts_with("@@") && 1222 !Rest.starts_with("@@@")) { 1223 Asm.getContext().reportError(S.Loc, "default version symbol " + 1224 AliasName + " must be defined"); 1225 continue; 1226 } 1227 1228 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) { 1229 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") + 1230 Symbol.getName()); 1231 continue; 1232 } 1233 1234 Renames.insert(std::make_pair(&Symbol, Alias)); 1235 } 1236 1237 for (const MCSymbol *&Sym : AddrsigSyms) { 1238 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym))) 1239 Sym = R; 1240 if (Sym->isInSection() && Sym->getName().starts_with(".L")) 1241 Sym = Sym->getSection().getBeginSymbol(); 1242 Sym->setUsedInReloc(); 1243 } 1244 } 1245 1246 // It is always valid to create a relocation with a symbol. It is preferable 1247 // to use a relocation with a section if that is possible. Using the section 1248 // allows us to omit some local symbols from the symbol table. 1249 bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, 1250 const MCValue &Val, 1251 const MCSymbolELF *Sym, 1252 uint64_t C, 1253 unsigned Type) const { 1254 const MCSymbolRefExpr *RefA = Val.getSymA(); 1255 // A PCRel relocation to an absolute value has no symbol (or section). We 1256 // represent that with a relocation to a null section. 1257 if (!RefA) 1258 return false; 1259 1260 MCSymbolRefExpr::VariantKind Kind = RefA->getKind(); 1261 switch (Kind) { 1262 default: 1263 break; 1264 // The .odp creation emits a relocation against the symbol ".TOC." which 1265 // create a R_PPC64_TOC relocation. However the relocation symbol name 1266 // in final object creation should be NULL, since the symbol does not 1267 // really exist, it is just the reference to TOC base for the current 1268 // object file. Since the symbol is undefined, returning false results 1269 // in a relocation with a null section which is the desired result. 1270 case MCSymbolRefExpr::VK_PPC_TOCBASE: 1271 return false; 1272 1273 // These VariantKind cause the relocation to refer to something other than 1274 // the symbol itself, like a linker generated table. Since the address of 1275 // symbol is not relevant, we cannot replace the symbol with the 1276 // section and patch the difference in the addend. 1277 case MCSymbolRefExpr::VK_GOT: 1278 case MCSymbolRefExpr::VK_PLT: 1279 case MCSymbolRefExpr::VK_GOTPCREL: 1280 case MCSymbolRefExpr::VK_GOTPCREL_NORELAX: 1281 case MCSymbolRefExpr::VK_PPC_GOT_LO: 1282 case MCSymbolRefExpr::VK_PPC_GOT_HI: 1283 case MCSymbolRefExpr::VK_PPC_GOT_HA: 1284 return true; 1285 } 1286 1287 // An undefined symbol is not in any section, so the relocation has to point 1288 // to the symbol itself. 1289 assert(Sym && "Expected a symbol"); 1290 if (Sym->isUndefined()) 1291 return true; 1292 1293 // For memory-tagged symbols, ensure that the relocation uses the symbol. For 1294 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special 1295 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that 1296 // this global needs to be tagged. In addition, the linker needs to know 1297 // whether to emit a special addend when relocating `end` symbols, and this 1298 // can only be determined by the attributes of the symbol itself. 1299 if (Sym->isMemtag()) 1300 return true; 1301 1302 unsigned Binding = Sym->getBinding(); 1303 switch(Binding) { 1304 default: 1305 llvm_unreachable("Invalid Binding"); 1306 case ELF::STB_LOCAL: 1307 break; 1308 case ELF::STB_WEAK: 1309 // If the symbol is weak, it might be overridden by a symbol in another 1310 // file. The relocation has to point to the symbol so that the linker 1311 // can update it. 1312 return true; 1313 case ELF::STB_GLOBAL: 1314 case ELF::STB_GNU_UNIQUE: 1315 // Global ELF symbols can be preempted by the dynamic linker. The relocation 1316 // has to point to the symbol for a reason analogous to the STB_WEAK case. 1317 return true; 1318 } 1319 1320 // Keep symbol type for a local ifunc because it may result in an IRELATIVE 1321 // reloc that the dynamic loader will use to resolve the address at startup 1322 // time. 1323 if (Sym->getType() == ELF::STT_GNU_IFUNC) 1324 return true; 1325 1326 // If a relocation points to a mergeable section, we have to be careful. 1327 // If the offset is zero, a relocation with the section will encode the 1328 // same information. With a non-zero offset, the situation is different. 1329 // For example, a relocation can point 42 bytes past the end of a string. 1330 // If we change such a relocation to use the section, the linker would think 1331 // that it pointed to another string and subtracting 42 at runtime will 1332 // produce the wrong value. 1333 if (Sym->isInSection()) { 1334 auto &Sec = cast<MCSectionELF>(Sym->getSection()); 1335 unsigned Flags = Sec.getFlags(); 1336 if (Flags & ELF::SHF_MERGE) { 1337 if (C != 0) 1338 return true; 1339 1340 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9) 1341 // (http://sourceware.org/PR16794). 1342 if (TargetObjectWriter->getEMachine() == ELF::EM_386 && 1343 Type == ELF::R_386_GOTOFF) 1344 return true; 1345 1346 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so 1347 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an 1348 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in 1349 // range of a MergeInputSection. We could introduce a new RelExpr member 1350 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12) 1351 // but the complexity is unnecessary given that GNU as keeps the original 1352 // symbol for this case as well. 1353 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS && 1354 !hasRelocationAddend()) 1355 return true; 1356 } 1357 1358 // Most TLS relocations use a got, so they need the symbol. Even those that 1359 // are just an offset (@tpoff), require a symbol in gold versions before 1360 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed 1361 // http://sourceware.org/PR16773. 1362 if (Flags & ELF::SHF_TLS) 1363 return true; 1364 } 1365 1366 // If the symbol is a thumb function the final relocation must set the lowest 1367 // bit. With a symbol that is done by just having the symbol have that bit 1368 // set, so we would lose the bit if we relocated with the section. 1369 // FIXME: We could use the section but add the bit to the relocation value. 1370 if (Asm.isThumbFunc(Sym)) 1371 return true; 1372 1373 if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type)) 1374 return true; 1375 return false; 1376 } 1377 1378 bool ELFObjectWriter::checkRelocation(MCContext &Ctx, SMLoc Loc, 1379 const MCSectionELF *From, 1380 const MCSectionELF *To) { 1381 if (DwoOS) { 1382 if (isDwoSection(*From)) { 1383 Ctx.reportError(Loc, "A dwo section may not contain relocations"); 1384 return false; 1385 } 1386 if (To && isDwoSection(*To)) { 1387 Ctx.reportError(Loc, "A relocation may not refer to a dwo section"); 1388 return false; 1389 } 1390 } 1391 return true; 1392 } 1393 1394 void ELFObjectWriter::recordRelocation(MCAssembler &Asm, 1395 const MCFragment *Fragment, 1396 const MCFixup &Fixup, MCValue Target, 1397 uint64_t &FixedValue) { 1398 MCAsmBackend &Backend = Asm.getBackend(); 1399 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & 1400 MCFixupKindInfo::FKF_IsPCRel; 1401 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent()); 1402 uint64_t C = Target.getConstant(); 1403 uint64_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset(); 1404 MCContext &Ctx = Asm.getContext(); 1405 const MCTargetOptions *TO = Ctx.getTargetOptions(); 1406 1407 if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 1408 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol()); 1409 if (SymB.isUndefined()) { 1410 Ctx.reportError(Fixup.getLoc(), 1411 Twine("symbol '") + SymB.getName() + 1412 "' can not be undefined in a subtraction expression"); 1413 return; 1414 } 1415 1416 assert(!SymB.isAbsolute() && "Should have been folded"); 1417 const MCSection &SecB = SymB.getSection(); 1418 if (&SecB != &FixupSection) { 1419 Ctx.reportError(Fixup.getLoc(), 1420 "Cannot represent a difference across sections"); 1421 return; 1422 } 1423 1424 assert(!IsPCRel && "should have been folded"); 1425 IsPCRel = true; 1426 C += FixupOffset - Asm.getSymbolOffset(SymB); 1427 } 1428 1429 // We either rejected the fixup or folded B into C at this point. 1430 const MCSymbolRefExpr *RefA = Target.getSymA(); 1431 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr; 1432 1433 bool ViaWeakRef = false; 1434 if (SymA && SymA->isVariable()) { 1435 const MCExpr *Expr = SymA->getVariableValue(); 1436 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) { 1437 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) { 1438 SymA = cast<MCSymbolELF>(&Inner->getSymbol()); 1439 ViaWeakRef = true; 1440 } 1441 } 1442 } 1443 1444 const MCSectionELF *SecA = (SymA && SymA->isInSection()) 1445 ? cast<MCSectionELF>(&SymA->getSection()) 1446 : nullptr; 1447 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA)) 1448 return; 1449 1450 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel); 1451 const auto *Parent = cast<MCSectionELF>(Fragment->getParent()); 1452 // Emiting relocation with sybmol for CG Profile to help with --cg-profile. 1453 bool RelocateWithSymbol = 1454 shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) || 1455 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE); 1456 uint64_t Addend = !RelocateWithSymbol && SymA && !SymA->isUndefined() 1457 ? C + Asm.getSymbolOffset(*SymA) 1458 : C; 1459 FixedValue = usesRela(TO, FixupSection) ? 0 : Addend; 1460 1461 if (!RelocateWithSymbol) { 1462 const auto *SectionSymbol = 1463 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr; 1464 if (SectionSymbol) 1465 SectionSymbol->setUsedInReloc(); 1466 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); 1467 Relocations[&FixupSection].push_back(Rec); 1468 return; 1469 } 1470 1471 const MCSymbolELF *RenamedSymA = SymA; 1472 if (SymA) { 1473 if (const MCSymbolELF *R = Renames.lookup(SymA)) 1474 RenamedSymA = R; 1475 1476 if (ViaWeakRef) 1477 RenamedSymA->setIsWeakrefUsedInReloc(); 1478 else 1479 RenamedSymA->setUsedInReloc(); 1480 } 1481 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend); 1482 Relocations[&FixupSection].push_back(Rec); 1483 } 1484 1485 bool ELFObjectWriter::usesRela(const MCTargetOptions *TO, 1486 const MCSectionELF &Sec) const { 1487 return (hasRelocationAddend() && 1488 Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE) || 1489 (TO && TO->Crel); 1490 } 1491 1492 bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( 1493 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB, 1494 bool InSet, bool IsPCRel) const { 1495 const auto &SymA = cast<MCSymbolELF>(SA); 1496 if (IsPCRel) { 1497 assert(!InSet); 1498 if (SymA.getBinding() != ELF::STB_LOCAL || 1499 SymA.getType() == ELF::STT_GNU_IFUNC) 1500 return false; 1501 } 1502 return &SymA.getSection() == FB.getParent(); 1503 } 1504 1505 uint64_t ELFObjectWriter::writeObject(MCAssembler &Asm) { 1506 uint64_t Size = 1507 ELFWriter(*this, OS, IsLittleEndian, 1508 DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections) 1509 .writeObject(Asm); 1510 if (DwoOS) 1511 Size += ELFWriter(*this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly) 1512 .writeObject(Asm); 1513 return Size; 1514 } 1515