1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements ELF object file writer information. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/MC/MCELFObjectWriter.h" 15 #include "llvm/ADT/OwningPtr.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallPtrSet.h" 18 #include "llvm/ADT/SmallString.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/MC/MCAsmBackend.h" 21 #include "llvm/MC/MCAsmLayout.h" 22 #include "llvm/MC/MCAssembler.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCELF.h" 25 #include "llvm/MC/MCELFSymbolFlags.h" 26 #include "llvm/MC/MCExpr.h" 27 #include "llvm/MC/MCFixupKindInfo.h" 28 #include "llvm/MC/MCObjectWriter.h" 29 #include "llvm/MC/MCSectionELF.h" 30 #include "llvm/MC/MCValue.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/ELF.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include <vector> 35 using namespace llvm; 36 37 #undef DEBUG_TYPE 38 #define DEBUG_TYPE "reloc-info" 39 40 namespace { 41 class ELFObjectWriter : public MCObjectWriter { 42 protected: 43 44 static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); 45 static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); 46 static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); 47 static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data, 48 bool Used, bool Renamed); 49 static bool isLocal(const MCSymbolData &Data, bool isSignature, 50 bool isUsedInReloc); 51 static bool IsELFMetaDataSection(const MCSectionData &SD); 52 static uint64_t DataSectionSize(const MCSectionData &SD); 53 static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, 54 const MCSectionData &SD); 55 static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, 56 const MCSectionData &SD); 57 58 void WriteDataSectionData(MCAssembler &Asm, 59 const MCAsmLayout &Layout, 60 const MCSectionELF &Section); 61 62 /*static bool isFixupKindX86RIPRel(unsigned Kind) { 63 return Kind == X86::reloc_riprel_4byte || 64 Kind == X86::reloc_riprel_4byte_movq_load; 65 }*/ 66 67 /// ELFSymbolData - Helper struct for containing some precomputed 68 /// information on symbols. 69 struct ELFSymbolData { 70 MCSymbolData *SymbolData; 71 uint64_t StringIndex; 72 uint32_t SectionIndex; 73 74 // Support lexicographic sorting. 75 bool operator<(const ELFSymbolData &RHS) const { 76 if (MCELF::GetType(*SymbolData) == ELF::STT_FILE) 77 return true; 78 if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE) 79 return false; 80 return SymbolData->getSymbol().getName() < 81 RHS.SymbolData->getSymbol().getName(); 82 } 83 }; 84 85 /// The target specific ELF writer instance. 86 llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter; 87 88 SmallPtrSet<const MCSymbol *, 16> UsedInReloc; 89 SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; 90 DenseMap<const MCSymbol *, const MCSymbol *> Renames; 91 92 llvm::DenseMap<const MCSectionData*, 93 std::vector<ELFRelocationEntry> > Relocations; 94 DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; 95 96 /// @} 97 /// @name Symbol Table Data 98 /// @{ 99 100 SmallString<256> StringTable; 101 std::vector<ELFSymbolData> LocalSymbolData; 102 std::vector<ELFSymbolData> ExternalSymbolData; 103 std::vector<ELFSymbolData> UndefinedSymbolData; 104 105 /// @} 106 107 bool NeedsGOT; 108 109 bool NeedsSymtabShndx; 110 111 // This holds the symbol table index of the last local symbol. 112 unsigned LastLocalSymbolIndex; 113 // This holds the .strtab section index. 114 unsigned StringTableIndex; 115 // This holds the .symtab section index. 116 unsigned SymbolTableIndex; 117 118 unsigned ShstrtabIndex; 119 120 121 const MCSymbol *SymbolToReloc(const MCAssembler &Asm, 122 const MCValue &Target, 123 const MCFragment &F, 124 const MCFixup &Fixup, 125 bool IsPCRel) const; 126 127 // TargetObjectWriter wrappers. 128 const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 129 const MCValue &Target, 130 const MCFragment &F, 131 const MCFixup &Fixup, 132 bool IsPCRel) const { 133 return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 134 } 135 const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, 136 const MCFixup &Fixup, 137 bool IsPCRel) const { 138 return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, 139 IsPCRel); 140 } 141 142 bool is64Bit() const { return TargetObjectWriter->is64Bit(); } 143 bool hasRelocationAddend() const { 144 return TargetObjectWriter->hasRelocationAddend(); 145 } 146 unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 147 bool IsPCRel, bool IsRelocWithSymbol, 148 int64_t Addend) const { 149 return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel, 150 IsRelocWithSymbol, Addend); 151 } 152 153 public: 154 ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 155 raw_ostream &_OS, bool IsLittleEndian) 156 : MCObjectWriter(_OS, IsLittleEndian), 157 TargetObjectWriter(MOTW), 158 NeedsGOT(false), NeedsSymtabShndx(false){ 159 } 160 161 virtual ~ELFObjectWriter(); 162 163 void WriteWord(uint64_t W) { 164 if (is64Bit()) 165 Write64(W); 166 else 167 Write32(W); 168 } 169 170 void StringLE16(char *buf, uint16_t Value) { 171 buf[0] = char(Value >> 0); 172 buf[1] = char(Value >> 8); 173 } 174 175 void StringLE32(char *buf, uint32_t Value) { 176 StringLE16(buf, uint16_t(Value >> 0)); 177 StringLE16(buf + 2, uint16_t(Value >> 16)); 178 } 179 180 void StringLE64(char *buf, uint64_t Value) { 181 StringLE32(buf, uint32_t(Value >> 0)); 182 StringLE32(buf + 4, uint32_t(Value >> 32)); 183 } 184 185 void StringBE16(char *buf ,uint16_t Value) { 186 buf[0] = char(Value >> 8); 187 buf[1] = char(Value >> 0); 188 } 189 190 void StringBE32(char *buf, uint32_t Value) { 191 StringBE16(buf, uint16_t(Value >> 16)); 192 StringBE16(buf + 2, uint16_t(Value >> 0)); 193 } 194 195 void StringBE64(char *buf, uint64_t Value) { 196 StringBE32(buf, uint32_t(Value >> 32)); 197 StringBE32(buf + 4, uint32_t(Value >> 0)); 198 } 199 200 void String8(MCDataFragment &F, uint8_t Value) { 201 char buf[1]; 202 buf[0] = Value; 203 F.getContents().append(&buf[0], &buf[1]); 204 } 205 206 void String16(MCDataFragment &F, uint16_t Value) { 207 char buf[2]; 208 if (isLittleEndian()) 209 StringLE16(buf, Value); 210 else 211 StringBE16(buf, Value); 212 F.getContents().append(&buf[0], &buf[2]); 213 } 214 215 void String32(MCDataFragment &F, uint32_t Value) { 216 char buf[4]; 217 if (isLittleEndian()) 218 StringLE32(buf, Value); 219 else 220 StringBE32(buf, Value); 221 F.getContents().append(&buf[0], &buf[4]); 222 } 223 224 void String64(MCDataFragment &F, uint64_t Value) { 225 char buf[8]; 226 if (isLittleEndian()) 227 StringLE64(buf, Value); 228 else 229 StringBE64(buf, Value); 230 F.getContents().append(&buf[0], &buf[8]); 231 } 232 233 void WriteHeader(const MCAssembler &Asm, 234 uint64_t SectionDataSize, 235 unsigned NumberOfSections); 236 237 void WriteSymbolEntry(MCDataFragment *SymtabF, 238 MCDataFragment *ShndxF, 239 uint64_t name, uint8_t info, 240 uint64_t value, uint64_t size, 241 uint8_t other, uint32_t shndx, 242 bool Reserved); 243 244 void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 245 ELFSymbolData &MSD, 246 const MCAsmLayout &Layout); 247 248 typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; 249 void WriteSymbolTable(MCDataFragment *SymtabF, 250 MCDataFragment *ShndxF, 251 const MCAssembler &Asm, 252 const MCAsmLayout &Layout, 253 const SectionIndexMapTy &SectionIndexMap); 254 255 virtual void RecordRelocation(const MCAssembler &Asm, 256 const MCAsmLayout &Layout, 257 const MCFragment *Fragment, 258 const MCFixup &Fixup, 259 MCValue Target, uint64_t &FixedValue); 260 261 uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, 262 const MCSymbol *S); 263 264 // Map from a group section to the signature symbol 265 typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; 266 // Map from a signature symbol to the group section 267 typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; 268 // Map from a section to the section with the relocations 269 typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy; 270 // Map from a section to its offset 271 typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy; 272 273 /// ComputeSymbolTable - Compute the symbol table data 274 /// 275 /// \param Asm - The assembler. 276 /// \param SectionIndexMap - Maps a section to its index. 277 /// \param RevGroupMap - Maps a signature symbol to the group section. 278 /// \param NumRegularSections - Number of non-relocation sections. 279 void ComputeSymbolTable(MCAssembler &Asm, 280 const SectionIndexMapTy &SectionIndexMap, 281 RevGroupMapTy RevGroupMap, 282 unsigned NumRegularSections); 283 284 void ComputeIndexMap(MCAssembler &Asm, 285 SectionIndexMapTy &SectionIndexMap, 286 const RelMapTy &RelMap); 287 288 void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, 289 RelMapTy &RelMap); 290 291 void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 292 const RelMapTy &RelMap); 293 294 void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, 295 SectionIndexMapTy &SectionIndexMap, 296 const RelMapTy &RelMap); 297 298 // Create the sections that show up in the symbol table. Currently 299 // those are the .note.GNU-stack section and the group sections. 300 void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, 301 GroupMapTy &GroupMap, 302 RevGroupMapTy &RevGroupMap, 303 SectionIndexMapTy &SectionIndexMap, 304 const RelMapTy &RelMap); 305 306 virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 307 const MCAsmLayout &Layout); 308 309 void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, 310 const MCAsmLayout &Layout, 311 const SectionIndexMapTy &SectionIndexMap, 312 const SectionOffsetMapTy &SectionOffsetMap); 313 314 void ComputeSectionOrder(MCAssembler &Asm, 315 std::vector<const MCSectionELF*> &Sections); 316 317 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 318 uint64_t Address, uint64_t Offset, 319 uint64_t Size, uint32_t Link, uint32_t Info, 320 uint64_t Alignment, uint64_t EntrySize); 321 322 void WriteRelocationsFragment(const MCAssembler &Asm, 323 MCDataFragment *F, 324 const MCSectionData *SD); 325 326 virtual bool 327 IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 328 const MCSymbolData &DataA, 329 const MCFragment &FB, 330 bool InSet, 331 bool IsPCRel) const; 332 333 virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 334 void WriteSection(MCAssembler &Asm, 335 const SectionIndexMapTy &SectionIndexMap, 336 uint32_t GroupSymbolIndex, 337 uint64_t Offset, uint64_t Size, uint64_t Alignment, 338 const MCSectionELF &Section); 339 }; 340 } 341 342 bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 343 const MCFixupKindInfo &FKI = 344 Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 345 346 return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 347 } 348 349 bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 350 switch (Variant) { 351 default: 352 return false; 353 case MCSymbolRefExpr::VK_GOT: 354 case MCSymbolRefExpr::VK_PLT: 355 case MCSymbolRefExpr::VK_GOTPCREL: 356 case MCSymbolRefExpr::VK_GOTOFF: 357 case MCSymbolRefExpr::VK_TPOFF: 358 case MCSymbolRefExpr::VK_TLSGD: 359 case MCSymbolRefExpr::VK_GOTTPOFF: 360 case MCSymbolRefExpr::VK_INDNTPOFF: 361 case MCSymbolRefExpr::VK_NTPOFF: 362 case MCSymbolRefExpr::VK_GOTNTPOFF: 363 case MCSymbolRefExpr::VK_TLSLDM: 364 case MCSymbolRefExpr::VK_DTPOFF: 365 case MCSymbolRefExpr::VK_TLSLD: 366 return true; 367 } 368 } 369 370 ELFObjectWriter::~ELFObjectWriter() 371 {} 372 373 // Emit the ELF header. 374 void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, 375 uint64_t SectionDataSize, 376 unsigned NumberOfSections) { 377 // ELF Header 378 // ---------- 379 // 380 // Note 381 // ---- 382 // emitWord method behaves differently for ELF32 and ELF64, writing 383 // 4 bytes in the former and 8 in the latter. 384 385 Write8(0x7f); // e_ident[EI_MAG0] 386 Write8('E'); // e_ident[EI_MAG1] 387 Write8('L'); // e_ident[EI_MAG2] 388 Write8('F'); // e_ident[EI_MAG3] 389 390 Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 391 392 // e_ident[EI_DATA] 393 Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 394 395 Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 396 // e_ident[EI_OSABI] 397 Write8(TargetObjectWriter->getOSABI()); 398 Write8(0); // e_ident[EI_ABIVERSION] 399 400 WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 401 402 Write16(ELF::ET_REL); // e_type 403 404 Write16(TargetObjectWriter->getEMachine()); // e_machine = target 405 406 Write32(ELF::EV_CURRENT); // e_version 407 WriteWord(0); // e_entry, no entry point in .o file 408 WriteWord(0); // e_phoff, no program header for .o 409 WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 410 sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 411 412 // e_flags = whatever the target wants 413 Write32(Asm.getELFHeaderEFlags()); 414 415 // e_ehsize = ELF header size 416 Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 417 418 Write16(0); // e_phentsize = prog header entry size 419 Write16(0); // e_phnum = # prog header entries = 0 420 421 // e_shentsize = Section header entry size 422 Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 423 424 // e_shnum = # of section header ents 425 if (NumberOfSections >= ELF::SHN_LORESERVE) 426 Write16(ELF::SHN_UNDEF); 427 else 428 Write16(NumberOfSections); 429 430 // e_shstrndx = Section # of '.shstrtab' 431 if (ShstrtabIndex >= ELF::SHN_LORESERVE) 432 Write16(ELF::SHN_XINDEX); 433 else 434 Write16(ShstrtabIndex); 435 } 436 437 void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 438 MCDataFragment *ShndxF, 439 uint64_t name, 440 uint8_t info, uint64_t value, 441 uint64_t size, uint8_t other, 442 uint32_t shndx, 443 bool Reserved) { 444 if (ShndxF) { 445 if (shndx >= ELF::SHN_LORESERVE && !Reserved) 446 String32(*ShndxF, shndx); 447 else 448 String32(*ShndxF, 0); 449 } 450 451 uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 452 uint16_t(ELF::SHN_XINDEX) : shndx; 453 454 if (is64Bit()) { 455 String32(*SymtabF, name); // st_name 456 String8(*SymtabF, info); // st_info 457 String8(*SymtabF, other); // st_other 458 String16(*SymtabF, Index); // st_shndx 459 String64(*SymtabF, value); // st_value 460 String64(*SymtabF, size); // st_size 461 } else { 462 String32(*SymtabF, name); // st_name 463 String32(*SymtabF, value); // st_value 464 String32(*SymtabF, size); // st_size 465 String8(*SymtabF, info); // st_info 466 String8(*SymtabF, other); // st_other 467 String16(*SymtabF, Index); // st_shndx 468 } 469 } 470 471 uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 472 const MCAsmLayout &Layout) { 473 if (Data.isCommon() && Data.isExternal()) 474 return Data.getCommonAlignment(); 475 476 const MCSymbol &Symbol = Data.getSymbol(); 477 478 if (Symbol.isAbsolute() && Symbol.isVariable()) { 479 if (const MCExpr *Value = Symbol.getVariableValue()) { 480 int64_t IntValue; 481 if (Value->EvaluateAsAbsolute(IntValue, Layout)) 482 return (uint64_t)IntValue; 483 } 484 } 485 486 if (!Symbol.isInSection()) 487 return 0; 488 489 490 if (Data.getFragment()) { 491 if (Data.getFlags() & ELF_Other_ThumbFunc) 492 return Layout.getSymbolOffset(&Data)+1; 493 else 494 return Layout.getSymbolOffset(&Data); 495 } 496 497 return 0; 498 } 499 500 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 501 const MCAsmLayout &Layout) { 502 // The presence of symbol versions causes undefined symbols and 503 // versions declared with @@@ to be renamed. 504 505 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 506 ie = Asm.symbol_end(); it != ie; ++it) { 507 const MCSymbol &Alias = it->getSymbol(); 508 const MCSymbol &Symbol = Alias.AliasedSymbol(); 509 MCSymbolData &SD = Asm.getSymbolData(Symbol); 510 511 // Not an alias. 512 if (&Symbol == &Alias) 513 continue; 514 515 StringRef AliasName = Alias.getName(); 516 size_t Pos = AliasName.find('@'); 517 if (Pos == StringRef::npos) 518 continue; 519 520 // Aliases defined with .symvar copy the binding from the symbol they alias. 521 // This is the first place we are able to copy this information. 522 it->setExternal(SD.isExternal()); 523 MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 524 525 StringRef Rest = AliasName.substr(Pos); 526 if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 527 continue; 528 529 // FIXME: produce a better error message. 530 if (Symbol.isUndefined() && Rest.startswith("@@") && 531 !Rest.startswith("@@@")) 532 report_fatal_error("A @@ version cannot be undefined"); 533 534 Renames.insert(std::make_pair(&Symbol, &Alias)); 535 } 536 } 537 538 void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 539 MCDataFragment *ShndxF, 540 ELFSymbolData &MSD, 541 const MCAsmLayout &Layout) { 542 MCSymbolData &OrigData = *MSD.SymbolData; 543 MCSymbolData &Data = 544 Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 545 546 bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 547 Data.getSymbol().isVariable(); 548 549 uint8_t Binding = MCELF::GetBinding(OrigData); 550 uint8_t Visibility = MCELF::GetVisibility(OrigData); 551 uint8_t Type = MCELF::GetType(Data); 552 553 uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 554 uint8_t Other = Visibility; 555 556 uint64_t Value = SymbolValue(Data, Layout); 557 uint64_t Size = 0; 558 559 assert(!(Data.isCommon() && !Data.isExternal())); 560 561 const MCExpr *ESize = Data.getSize(); 562 if (ESize) { 563 int64_t Res; 564 if (!ESize->EvaluateAsAbsolute(Res, Layout)) 565 report_fatal_error("Size expression must be absolute."); 566 Size = Res; 567 } 568 569 // Write out the symbol table entry 570 WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 571 Size, Other, MSD.SectionIndex, IsReserved); 572 } 573 574 void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 575 MCDataFragment *ShndxF, 576 const MCAssembler &Asm, 577 const MCAsmLayout &Layout, 578 const SectionIndexMapTy &SectionIndexMap) { 579 // The string table must be emitted first because we need the index 580 // into the string table for all the symbol names. 581 assert(StringTable.size() && "Missing string table"); 582 583 // FIXME: Make sure the start of the symbol table is aligned. 584 585 // The first entry is the undefined symbol entry. 586 WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 587 588 // Write the symbol table entries. 589 LastLocalSymbolIndex = LocalSymbolData.size() + 1; 590 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 591 ELFSymbolData &MSD = LocalSymbolData[i]; 592 WriteSymbol(SymtabF, ShndxF, MSD, Layout); 593 } 594 595 // Write out a symbol table entry for each regular section. 596 for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 597 ++i) { 598 const MCSectionELF &Section = 599 static_cast<const MCSectionELF&>(i->getSection()); 600 if (Section.getType() == ELF::SHT_RELA || 601 Section.getType() == ELF::SHT_REL || 602 Section.getType() == ELF::SHT_STRTAB || 603 Section.getType() == ELF::SHT_SYMTAB || 604 Section.getType() == ELF::SHT_SYMTAB_SHNDX) 605 continue; 606 WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 607 ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), 608 false); 609 LastLocalSymbolIndex++; 610 } 611 612 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 613 ELFSymbolData &MSD = ExternalSymbolData[i]; 614 MCSymbolData &Data = *MSD.SymbolData; 615 assert(((Data.getFlags() & ELF_STB_Global) || 616 (Data.getFlags() & ELF_STB_Weak)) && 617 "External symbol requires STB_GLOBAL or STB_WEAK flag"); 618 WriteSymbol(SymtabF, ShndxF, MSD, Layout); 619 if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 620 LastLocalSymbolIndex++; 621 } 622 623 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 624 ELFSymbolData &MSD = UndefinedSymbolData[i]; 625 MCSymbolData &Data = *MSD.SymbolData; 626 WriteSymbol(SymtabF, ShndxF, MSD, Layout); 627 if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 628 LastLocalSymbolIndex++; 629 } 630 } 631 632 const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 633 const MCValue &Target, 634 const MCFragment &F, 635 const MCFixup &Fixup, 636 bool IsPCRel) const { 637 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 638 const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 639 const MCSymbol *Renamed = Renames.lookup(&Symbol); 640 const MCSymbolData &SD = Asm.getSymbolData(Symbol); 641 642 if (ASymbol.isUndefined()) { 643 if (Renamed) 644 return Renamed; 645 return undefinedExplicitRelSym(Target, Fixup, IsPCRel); 646 } 647 648 if (SD.isExternal()) { 649 if (Renamed) 650 return Renamed; 651 return &Symbol; 652 } 653 654 const MCSectionELF &Section = 655 static_cast<const MCSectionELF&>(ASymbol.getSection()); 656 const SectionKind secKind = Section.getKind(); 657 658 if (secKind.isBSS()) 659 return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 660 661 if (secKind.isThreadLocal()) { 662 if (Renamed) 663 return Renamed; 664 return &Symbol; 665 } 666 667 MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 668 const MCSectionELF &Sec2 = 669 static_cast<const MCSectionELF&>(F.getParent()->getSection()); 670 671 if (&Sec2 != &Section && 672 (Kind == MCSymbolRefExpr::VK_PLT || 673 Kind == MCSymbolRefExpr::VK_GOTPCREL || 674 Kind == MCSymbolRefExpr::VK_GOTOFF)) { 675 if (Renamed) 676 return Renamed; 677 return &Symbol; 678 } 679 680 if (Section.getFlags() & ELF::SHF_MERGE) { 681 if (Target.getConstant() == 0) 682 return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 683 if (Renamed) 684 return Renamed; 685 return &Symbol; 686 } 687 688 return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 689 690 } 691 692 693 void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 694 const MCAsmLayout &Layout, 695 const MCFragment *Fragment, 696 const MCFixup &Fixup, 697 MCValue Target, 698 uint64_t &FixedValue) { 699 int64_t Addend = 0; 700 int Index = 0; 701 int64_t Value = Target.getConstant(); 702 const MCSymbol *RelocSymbol = NULL; 703 704 bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 705 if (!Target.isAbsolute()) { 706 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 707 const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 708 RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 709 710 if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 711 const MCSymbol &SymbolB = RefB->getSymbol(); 712 MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 713 IsPCRel = true; 714 715 // Offset of the symbol in the section 716 int64_t a = Layout.getSymbolOffset(&SDB); 717 718 // Offset of the relocation in the section 719 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 720 Value += b - a; 721 } 722 723 if (!RelocSymbol) { 724 MCSymbolData &SD = Asm.getSymbolData(ASymbol); 725 MCFragment *F = SD.getFragment(); 726 727 if (F) { 728 Index = F->getParent()->getOrdinal() + 1; 729 // Offset of the symbol in the section 730 Value += Layout.getSymbolOffset(&SD); 731 } else { 732 Index = 0; 733 } 734 } else { 735 if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 736 WeakrefUsedInReloc.insert(RelocSymbol); 737 else 738 UsedInReloc.insert(RelocSymbol); 739 Index = -1; 740 } 741 Addend = Value; 742 if (hasRelocationAddend()) 743 Value = 0; 744 } 745 746 FixedValue = Value; 747 unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 748 (RelocSymbol != 0), Addend); 749 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 750 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 751 if (RelocNeedsGOT(Modifier)) 752 NeedsGOT = true; 753 754 uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 755 Fixup.getOffset(); 756 757 // FIXME: no tests cover this. Is adjustFixupOffset dead code? 758 TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset); 759 760 if (!hasRelocationAddend()) 761 Addend = 0; 762 763 if (is64Bit()) 764 assert(isInt<64>(Addend)); 765 else 766 assert(isInt<32>(Addend)); 767 768 ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup); 769 Relocations[Fragment->getParent()].push_back(ERE); 770 } 771 772 773 uint64_t 774 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 775 const MCSymbol *S) { 776 MCSymbolData &SD = Asm.getSymbolData(*S); 777 return SD.getIndex(); 778 } 779 780 bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 781 const MCSymbolData &Data, 782 bool Used, bool Renamed) { 783 if (Data.getFlags() & ELF_Other_Weakref) 784 return false; 785 786 if (Used) 787 return true; 788 789 if (Renamed) 790 return false; 791 792 const MCSymbol &Symbol = Data.getSymbol(); 793 794 if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 795 return true; 796 797 const MCSymbol &A = Symbol.AliasedSymbol(); 798 if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 799 return false; 800 801 bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 802 if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 803 return false; 804 805 if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 806 return false; 807 808 if (Symbol.isTemporary()) 809 return false; 810 811 return true; 812 } 813 814 bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 815 bool isUsedInReloc) { 816 if (Data.isExternal()) 817 return false; 818 819 const MCSymbol &Symbol = Data.getSymbol(); 820 const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 821 822 if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 823 if (isSignature && !isUsedInReloc) 824 return true; 825 826 return false; 827 } 828 829 return true; 830 } 831 832 void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 833 SectionIndexMapTy &SectionIndexMap, 834 const RelMapTy &RelMap) { 835 unsigned Index = 1; 836 for (MCAssembler::iterator it = Asm.begin(), 837 ie = Asm.end(); it != ie; ++it) { 838 const MCSectionELF &Section = 839 static_cast<const MCSectionELF &>(it->getSection()); 840 if (Section.getType() != ELF::SHT_GROUP) 841 continue; 842 SectionIndexMap[&Section] = Index++; 843 } 844 845 for (MCAssembler::iterator it = Asm.begin(), 846 ie = Asm.end(); it != ie; ++it) { 847 const MCSectionELF &Section = 848 static_cast<const MCSectionELF &>(it->getSection()); 849 if (Section.getType() == ELF::SHT_GROUP || 850 Section.getType() == ELF::SHT_REL || 851 Section.getType() == ELF::SHT_RELA) 852 continue; 853 SectionIndexMap[&Section] = Index++; 854 const MCSectionELF *RelSection = RelMap.lookup(&Section); 855 if (RelSection) 856 SectionIndexMap[RelSection] = Index++; 857 } 858 } 859 860 void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 861 const SectionIndexMapTy &SectionIndexMap, 862 RevGroupMapTy RevGroupMap, 863 unsigned NumRegularSections) { 864 // FIXME: Is this the correct place to do this? 865 // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 866 if (NeedsGOT) { 867 StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 868 MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 869 MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 870 Data.setExternal(true); 871 MCELF::SetBinding(Data, ELF::STB_GLOBAL); 872 } 873 874 // Index 0 is always the empty string. 875 StringMap<uint64_t> StringIndexMap; 876 StringTable += '\x00'; 877 878 // FIXME: We could optimize suffixes in strtab in the same way we 879 // optimize them in shstrtab. 880 881 // Add the data for the symbols. 882 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 883 ie = Asm.symbol_end(); it != ie; ++it) { 884 const MCSymbol &Symbol = it->getSymbol(); 885 886 bool Used = UsedInReloc.count(&Symbol); 887 bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 888 bool isSignature = RevGroupMap.count(&Symbol); 889 890 if (!isInSymtab(Asm, *it, 891 Used || WeakrefUsed || isSignature, 892 Renames.count(&Symbol))) 893 continue; 894 895 ELFSymbolData MSD; 896 MSD.SymbolData = it; 897 const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 898 899 // Undefined symbols are global, but this is the first place we 900 // are able to set it. 901 bool Local = isLocal(*it, isSignature, Used); 902 if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 903 MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 904 MCELF::SetBinding(*it, ELF::STB_GLOBAL); 905 MCELF::SetBinding(SD, ELF::STB_GLOBAL); 906 } 907 908 if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 909 MCELF::SetBinding(*it, ELF::STB_WEAK); 910 911 if (it->isCommon()) { 912 assert(!Local); 913 MSD.SectionIndex = ELF::SHN_COMMON; 914 } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 915 MSD.SectionIndex = ELF::SHN_ABS; 916 } else if (RefSymbol.isUndefined()) { 917 if (isSignature && !Used) 918 MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 919 else 920 MSD.SectionIndex = ELF::SHN_UNDEF; 921 } else { 922 const MCSectionELF &Section = 923 static_cast<const MCSectionELF&>(RefSymbol.getSection()); 924 MSD.SectionIndex = SectionIndexMap.lookup(&Section); 925 if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 926 NeedsSymtabShndx = true; 927 assert(MSD.SectionIndex && "Invalid section index!"); 928 } 929 930 // The @@@ in symbol version is replaced with @ in undefined symbols and 931 // @@ in defined ones. 932 StringRef Name = Symbol.getName(); 933 SmallString<32> Buf; 934 935 size_t Pos = Name.find("@@@"); 936 if (Pos != StringRef::npos) { 937 Buf += Name.substr(0, Pos); 938 unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 939 Buf += Name.substr(Pos + Skip); 940 Name = Buf; 941 } 942 943 uint64_t &Entry = StringIndexMap[Name]; 944 if (!Entry) { 945 Entry = StringTable.size(); 946 StringTable += Name; 947 StringTable += '\x00'; 948 } 949 MSD.StringIndex = Entry; 950 if (MSD.SectionIndex == ELF::SHN_UNDEF) 951 UndefinedSymbolData.push_back(MSD); 952 else if (Local) 953 LocalSymbolData.push_back(MSD); 954 else 955 ExternalSymbolData.push_back(MSD); 956 } 957 958 // Symbols are required to be in lexicographic order. 959 array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 960 array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 961 array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 962 963 // Set the symbol indices. Local symbols must come before all other 964 // symbols with non-local bindings. 965 unsigned Index = 1; 966 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 967 LocalSymbolData[i].SymbolData->setIndex(Index++); 968 969 Index += NumRegularSections; 970 971 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 972 ExternalSymbolData[i].SymbolData->setIndex(Index++); 973 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 974 UndefinedSymbolData[i].SymbolData->setIndex(Index++); 975 976 if (NumRegularSections > ELF::SHN_LORESERVE) 977 NeedsSymtabShndx = true; 978 } 979 980 void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 981 MCAsmLayout &Layout, 982 RelMapTy &RelMap) { 983 for (MCAssembler::const_iterator it = Asm.begin(), 984 ie = Asm.end(); it != ie; ++it) { 985 const MCSectionData &SD = *it; 986 if (Relocations[&SD].empty()) 987 continue; 988 989 MCContext &Ctx = Asm.getContext(); 990 const MCSectionELF &Section = 991 static_cast<const MCSectionELF&>(SD.getSection()); 992 993 const StringRef SectionName = Section.getSectionName(); 994 std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 995 RelaSectionName += SectionName; 996 997 unsigned EntrySize; 998 if (hasRelocationAddend()) 999 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 1000 else 1001 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 1002 1003 const MCSectionELF *RelaSection = 1004 Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 1005 ELF::SHT_RELA : ELF::SHT_REL, 0, 1006 SectionKind::getReadOnly(), 1007 EntrySize, ""); 1008 RelMap[&Section] = RelaSection; 1009 Asm.getOrCreateSectionData(*RelaSection); 1010 } 1011 } 1012 1013 void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 1014 const RelMapTy &RelMap) { 1015 for (MCAssembler::const_iterator it = Asm.begin(), 1016 ie = Asm.end(); it != ie; ++it) { 1017 const MCSectionData &SD = *it; 1018 const MCSectionELF &Section = 1019 static_cast<const MCSectionELF&>(SD.getSection()); 1020 1021 const MCSectionELF *RelaSection = RelMap.lookup(&Section); 1022 if (!RelaSection) 1023 continue; 1024 MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 1025 RelaSD.setAlignment(is64Bit() ? 8 : 4); 1026 1027 MCDataFragment *F = new MCDataFragment(&RelaSD); 1028 WriteRelocationsFragment(Asm, F, &*it); 1029 } 1030 } 1031 1032 void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 1033 uint64_t Flags, uint64_t Address, 1034 uint64_t Offset, uint64_t Size, 1035 uint32_t Link, uint32_t Info, 1036 uint64_t Alignment, 1037 uint64_t EntrySize) { 1038 Write32(Name); // sh_name: index into string table 1039 Write32(Type); // sh_type 1040 WriteWord(Flags); // sh_flags 1041 WriteWord(Address); // sh_addr 1042 WriteWord(Offset); // sh_offset 1043 WriteWord(Size); // sh_size 1044 Write32(Link); // sh_link 1045 Write32(Info); // sh_info 1046 WriteWord(Alignment); // sh_addralign 1047 WriteWord(EntrySize); // sh_entsize 1048 } 1049 1050 void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 1051 MCDataFragment *F, 1052 const MCSectionData *SD) { 1053 std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 1054 1055 // Sort the relocation entries. Most targets just sort by r_offset, but some 1056 // (e.g., MIPS) have additional constraints. 1057 TargetObjectWriter->sortRelocs(Asm, Relocs); 1058 1059 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 1060 ELFRelocationEntry entry = Relocs[e - i - 1]; 1061 1062 if (!entry.Index) 1063 ; 1064 else if (entry.Index < 0) 1065 entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 1066 else 1067 entry.Index += LocalSymbolData.size(); 1068 if (is64Bit()) { 1069 String64(*F, entry.r_offset); 1070 if (TargetObjectWriter->isN64()) { 1071 String32(*F, entry.Index); 1072 1073 String8(*F, TargetObjectWriter->getRSsym(entry.Type)); 1074 String8(*F, TargetObjectWriter->getRType3(entry.Type)); 1075 String8(*F, TargetObjectWriter->getRType2(entry.Type)); 1076 String8(*F, TargetObjectWriter->getRType(entry.Type)); 1077 } 1078 else { 1079 struct ELF::Elf64_Rela ERE64; 1080 ERE64.setSymbolAndType(entry.Index, entry.Type); 1081 String64(*F, ERE64.r_info); 1082 } 1083 if (hasRelocationAddend()) 1084 String64(*F, entry.r_addend); 1085 } else { 1086 String32(*F, entry.r_offset); 1087 1088 struct ELF::Elf32_Rela ERE32; 1089 ERE32.setSymbolAndType(entry.Index, entry.Type); 1090 String32(*F, ERE32.r_info); 1091 1092 if (hasRelocationAddend()) 1093 String32(*F, entry.r_addend); 1094 } 1095 } 1096 } 1097 1098 static int compareBySuffix(const void *a, const void *b) { 1099 const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 1100 const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 1101 const StringRef &NameA = secA->getSectionName(); 1102 const StringRef &NameB = secB->getSectionName(); 1103 const unsigned sizeA = NameA.size(); 1104 const unsigned sizeB = NameB.size(); 1105 const unsigned len = std::min(sizeA, sizeB); 1106 for (unsigned int i = 0; i < len; ++i) { 1107 char ca = NameA[sizeA - i - 1]; 1108 char cb = NameB[sizeB - i - 1]; 1109 if (ca != cb) 1110 return cb - ca; 1111 } 1112 1113 return sizeB - sizeA; 1114 } 1115 1116 void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 1117 MCAsmLayout &Layout, 1118 SectionIndexMapTy &SectionIndexMap, 1119 const RelMapTy &RelMap) { 1120 MCContext &Ctx = Asm.getContext(); 1121 MCDataFragment *F; 1122 1123 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 1124 1125 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 1126 const MCSectionELF *ShstrtabSection = 1127 Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 1128 SectionKind::getReadOnly()); 1129 MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 1130 ShstrtabSD.setAlignment(1); 1131 1132 const MCSectionELF *SymtabSection = 1133 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 1134 SectionKind::getReadOnly(), 1135 EntrySize, ""); 1136 MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 1137 SymtabSD.setAlignment(is64Bit() ? 8 : 4); 1138 1139 MCSectionData *SymtabShndxSD = NULL; 1140 1141 if (NeedsSymtabShndx) { 1142 const MCSectionELF *SymtabShndxSection = 1143 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 1144 SectionKind::getReadOnly(), 4, ""); 1145 SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 1146 SymtabShndxSD->setAlignment(4); 1147 } 1148 1149 const MCSectionELF *StrtabSection; 1150 StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 1151 SectionKind::getReadOnly()); 1152 MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 1153 StrtabSD.setAlignment(1); 1154 1155 ComputeIndexMap(Asm, SectionIndexMap, RelMap); 1156 1157 ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 1158 SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 1159 StringTableIndex = SectionIndexMap.lookup(StrtabSection); 1160 1161 // Symbol table 1162 F = new MCDataFragment(&SymtabSD); 1163 MCDataFragment *ShndxF = NULL; 1164 if (NeedsSymtabShndx) { 1165 ShndxF = new MCDataFragment(SymtabShndxSD); 1166 } 1167 WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 1168 1169 F = new MCDataFragment(&StrtabSD); 1170 F->getContents().append(StringTable.begin(), StringTable.end()); 1171 1172 F = new MCDataFragment(&ShstrtabSD); 1173 1174 std::vector<const MCSectionELF*> Sections; 1175 for (MCAssembler::const_iterator it = Asm.begin(), 1176 ie = Asm.end(); it != ie; ++it) { 1177 const MCSectionELF &Section = 1178 static_cast<const MCSectionELF&>(it->getSection()); 1179 Sections.push_back(&Section); 1180 } 1181 array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 1182 1183 // Section header string table. 1184 // 1185 // The first entry of a string table holds a null character so skip 1186 // section 0. 1187 uint64_t Index = 1; 1188 F->getContents().push_back('\x00'); 1189 1190 for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 1191 const MCSectionELF &Section = *Sections[I]; 1192 1193 StringRef Name = Section.getSectionName(); 1194 if (I != 0) { 1195 StringRef PreviousName = Sections[I - 1]->getSectionName(); 1196 if (PreviousName.endswith(Name)) { 1197 SectionStringTableIndex[&Section] = Index - Name.size() - 1; 1198 continue; 1199 } 1200 } 1201 // Remember the index into the string table so we can write it 1202 // into the sh_name field of the section header table. 1203 SectionStringTableIndex[&Section] = Index; 1204 1205 Index += Name.size() + 1; 1206 F->getContents().append(Name.begin(), Name.end()); 1207 F->getContents().push_back('\x00'); 1208 } 1209 } 1210 1211 void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 1212 MCAsmLayout &Layout, 1213 GroupMapTy &GroupMap, 1214 RevGroupMapTy &RevGroupMap, 1215 SectionIndexMapTy &SectionIndexMap, 1216 const RelMapTy &RelMap) { 1217 // Create the .note.GNU-stack section if needed. 1218 MCContext &Ctx = Asm.getContext(); 1219 if (Asm.getNoExecStack()) { 1220 const MCSectionELF *GnuStackSection = 1221 Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 1222 SectionKind::getReadOnly()); 1223 Asm.getOrCreateSectionData(*GnuStackSection); 1224 } 1225 1226 // Build the groups 1227 for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 1228 it != ie; ++it) { 1229 const MCSectionELF &Section = 1230 static_cast<const MCSectionELF&>(it->getSection()); 1231 if (!(Section.getFlags() & ELF::SHF_GROUP)) 1232 continue; 1233 1234 const MCSymbol *SignatureSymbol = Section.getGroup(); 1235 Asm.getOrCreateSymbolData(*SignatureSymbol); 1236 const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 1237 if (!Group) { 1238 Group = Ctx.CreateELFGroupSection(); 1239 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 1240 Data.setAlignment(4); 1241 MCDataFragment *F = new MCDataFragment(&Data); 1242 String32(*F, ELF::GRP_COMDAT); 1243 } 1244 GroupMap[Group] = SignatureSymbol; 1245 } 1246 1247 ComputeIndexMap(Asm, SectionIndexMap, RelMap); 1248 1249 // Add sections to the groups 1250 for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 1251 it != ie; ++it) { 1252 const MCSectionELF &Section = 1253 static_cast<const MCSectionELF&>(it->getSection()); 1254 if (!(Section.getFlags() & ELF::SHF_GROUP)) 1255 continue; 1256 const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 1257 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 1258 // FIXME: we could use the previous fragment 1259 MCDataFragment *F = new MCDataFragment(&Data); 1260 unsigned Index = SectionIndexMap.lookup(&Section); 1261 String32(*F, Index); 1262 } 1263 } 1264 1265 void ELFObjectWriter::WriteSection(MCAssembler &Asm, 1266 const SectionIndexMapTy &SectionIndexMap, 1267 uint32_t GroupSymbolIndex, 1268 uint64_t Offset, uint64_t Size, 1269 uint64_t Alignment, 1270 const MCSectionELF &Section) { 1271 uint64_t sh_link = 0; 1272 uint64_t sh_info = 0; 1273 1274 switch(Section.getType()) { 1275 case ELF::SHT_DYNAMIC: 1276 sh_link = SectionStringTableIndex[&Section]; 1277 sh_info = 0; 1278 break; 1279 1280 case ELF::SHT_REL: 1281 case ELF::SHT_RELA: { 1282 const MCSectionELF *SymtabSection; 1283 const MCSectionELF *InfoSection; 1284 SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 1285 0, 1286 SectionKind::getReadOnly()); 1287 sh_link = SectionIndexMap.lookup(SymtabSection); 1288 assert(sh_link && ".symtab not found"); 1289 1290 // Remove ".rel" and ".rela" prefixes. 1291 unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 1292 StringRef SectionName = Section.getSectionName().substr(SecNameLen); 1293 1294 InfoSection = Asm.getContext().getELFSection(SectionName, 1295 ELF::SHT_PROGBITS, 0, 1296 SectionKind::getReadOnly()); 1297 sh_info = SectionIndexMap.lookup(InfoSection); 1298 break; 1299 } 1300 1301 case ELF::SHT_SYMTAB: 1302 case ELF::SHT_DYNSYM: 1303 sh_link = StringTableIndex; 1304 sh_info = LastLocalSymbolIndex; 1305 break; 1306 1307 case ELF::SHT_SYMTAB_SHNDX: 1308 sh_link = SymbolTableIndex; 1309 break; 1310 1311 case ELF::SHT_PROGBITS: 1312 case ELF::SHT_STRTAB: 1313 case ELF::SHT_NOBITS: 1314 case ELF::SHT_NOTE: 1315 case ELF::SHT_NULL: 1316 case ELF::SHT_ARM_ATTRIBUTES: 1317 case ELF::SHT_INIT_ARRAY: 1318 case ELF::SHT_FINI_ARRAY: 1319 case ELF::SHT_PREINIT_ARRAY: 1320 case ELF::SHT_X86_64_UNWIND: 1321 case ELF::SHT_MIPS_REGINFO: 1322 case ELF::SHT_MIPS_OPTIONS: 1323 // Nothing to do. 1324 break; 1325 1326 case ELF::SHT_GROUP: 1327 sh_link = SymbolTableIndex; 1328 sh_info = GroupSymbolIndex; 1329 break; 1330 1331 default: 1332 assert(0 && "FIXME: sh_type value not supported!"); 1333 break; 1334 } 1335 1336 if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && 1337 Section.getType() == ELF::SHT_ARM_EXIDX) { 1338 StringRef SecName(Section.getSectionName()); 1339 if (SecName == ".ARM.exidx") { 1340 sh_link = SectionIndexMap.lookup( 1341 Asm.getContext().getELFSection(".text", 1342 ELF::SHT_PROGBITS, 1343 ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, 1344 SectionKind::getText())); 1345 } else if (SecName.startswith(".ARM.exidx")) { 1346 sh_link = SectionIndexMap.lookup( 1347 Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1), 1348 ELF::SHT_PROGBITS, 1349 ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, 1350 SectionKind::getText())); 1351 } 1352 } 1353 1354 WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1355 Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1356 Alignment, Section.getEntrySize()); 1357 } 1358 1359 bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1360 return SD.getOrdinal() == ~UINT32_C(0) && 1361 !SD.getSection().isVirtualSection(); 1362 } 1363 1364 uint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 1365 uint64_t Ret = 0; 1366 for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 1367 ++i) { 1368 const MCFragment &F = *i; 1369 assert(F.getKind() == MCFragment::FT_Data); 1370 Ret += cast<MCDataFragment>(F).getContents().size(); 1371 } 1372 return Ret; 1373 } 1374 1375 uint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 1376 const MCSectionData &SD) { 1377 if (IsELFMetaDataSection(SD)) 1378 return DataSectionSize(SD); 1379 return Layout.getSectionFileSize(&SD); 1380 } 1381 1382 uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 1383 const MCSectionData &SD) { 1384 if (IsELFMetaDataSection(SD)) 1385 return DataSectionSize(SD); 1386 return Layout.getSectionAddressSize(&SD); 1387 } 1388 1389 void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 1390 const MCAsmLayout &Layout, 1391 const MCSectionELF &Section) { 1392 const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1393 1394 uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); 1395 WriteZeros(Padding); 1396 1397 if (IsELFMetaDataSection(SD)) { 1398 for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 1399 ++i) { 1400 const MCFragment &F = *i; 1401 assert(F.getKind() == MCFragment::FT_Data); 1402 WriteBytes(cast<MCDataFragment>(F).getContents()); 1403 } 1404 } else { 1405 Asm.writeSectionData(&SD, Layout); 1406 } 1407 } 1408 1409 void ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 1410 const GroupMapTy &GroupMap, 1411 const MCAsmLayout &Layout, 1412 const SectionIndexMapTy &SectionIndexMap, 1413 const SectionOffsetMapTy &SectionOffsetMap) { 1414 const unsigned NumSections = Asm.size() + 1; 1415 1416 std::vector<const MCSectionELF*> Sections; 1417 Sections.resize(NumSections - 1); 1418 1419 for (SectionIndexMapTy::const_iterator i= 1420 SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 1421 const std::pair<const MCSectionELF*, uint32_t> &p = *i; 1422 Sections[p.second - 1] = p.first; 1423 } 1424 1425 // Null section first. 1426 uint64_t FirstSectionSize = 1427 NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 1428 uint32_t FirstSectionLink = 1429 ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 1430 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 1431 1432 for (unsigned i = 0; i < NumSections - 1; ++i) { 1433 const MCSectionELF &Section = *Sections[i]; 1434 const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1435 uint32_t GroupSymbolIndex; 1436 if (Section.getType() != ELF::SHT_GROUP) 1437 GroupSymbolIndex = 0; 1438 else 1439 GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 1440 GroupMap.lookup(&Section)); 1441 1442 uint64_t Size = GetSectionAddressSize(Layout, SD); 1443 1444 WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 1445 SectionOffsetMap.lookup(&Section), Size, 1446 SD.getAlignment(), Section); 1447 } 1448 } 1449 1450 void ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 1451 std::vector<const MCSectionELF*> &Sections) { 1452 for (MCAssembler::iterator it = Asm.begin(), 1453 ie = Asm.end(); it != ie; ++it) { 1454 const MCSectionELF &Section = 1455 static_cast<const MCSectionELF &>(it->getSection()); 1456 if (Section.getType() == ELF::SHT_GROUP) 1457 Sections.push_back(&Section); 1458 } 1459 1460 for (MCAssembler::iterator it = Asm.begin(), 1461 ie = Asm.end(); it != ie; ++it) { 1462 const MCSectionELF &Section = 1463 static_cast<const MCSectionELF &>(it->getSection()); 1464 if (Section.getType() != ELF::SHT_GROUP && 1465 Section.getType() != ELF::SHT_REL && 1466 Section.getType() != ELF::SHT_RELA) 1467 Sections.push_back(&Section); 1468 } 1469 1470 for (MCAssembler::iterator it = Asm.begin(), 1471 ie = Asm.end(); it != ie; ++it) { 1472 const MCSectionELF &Section = 1473 static_cast<const MCSectionELF &>(it->getSection()); 1474 if (Section.getType() == ELF::SHT_REL || 1475 Section.getType() == ELF::SHT_RELA) 1476 Sections.push_back(&Section); 1477 } 1478 } 1479 1480 void ELFObjectWriter::WriteObject(MCAssembler &Asm, 1481 const MCAsmLayout &Layout) { 1482 GroupMapTy GroupMap; 1483 RevGroupMapTy RevGroupMap; 1484 SectionIndexMapTy SectionIndexMap; 1485 1486 unsigned NumUserSections = Asm.size(); 1487 1488 DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 1489 CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 1490 1491 const unsigned NumUserAndRelocSections = Asm.size(); 1492 CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 1493 RevGroupMap, SectionIndexMap, RelMap); 1494 const unsigned AllSections = Asm.size(); 1495 const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 1496 1497 unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1498 1499 // Compute symbol table information. 1500 ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 1501 1502 1503 WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 1504 1505 CreateMetadataSections(const_cast<MCAssembler&>(Asm), 1506 const_cast<MCAsmLayout&>(Layout), 1507 SectionIndexMap, 1508 RelMap); 1509 1510 uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1511 uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1512 sizeof(ELF::Elf32_Ehdr); 1513 uint64_t FileOff = HeaderSize; 1514 1515 std::vector<const MCSectionELF*> Sections; 1516 ComputeSectionOrder(Asm, Sections); 1517 unsigned NumSections = Sections.size(); 1518 SectionOffsetMapTy SectionOffsetMap; 1519 for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 1520 const MCSectionELF &Section = *Sections[i]; 1521 const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1522 1523 FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1524 1525 // Remember the offset into the file for this section. 1526 SectionOffsetMap[&Section] = FileOff; 1527 1528 // Get the size of the section in the output file (including padding). 1529 FileOff += GetSectionFileSize(Layout, SD); 1530 } 1531 1532 FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1533 1534 const unsigned SectionHeaderOffset = FileOff - HeaderSize; 1535 1536 uint64_t SectionHeaderEntrySize = is64Bit() ? 1537 sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 1538 FileOff += (NumSections + 1) * SectionHeaderEntrySize; 1539 1540 for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 1541 const MCSectionELF &Section = *Sections[i]; 1542 const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1543 1544 FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1545 1546 // Remember the offset into the file for this section. 1547 SectionOffsetMap[&Section] = FileOff; 1548 1549 // Get the size of the section in the output file (including padding). 1550 FileOff += GetSectionFileSize(Layout, SD); 1551 } 1552 1553 // Write out the ELF header ... 1554 WriteHeader(Asm, SectionHeaderOffset, NumSections + 1); 1555 1556 // ... then the regular sections ... 1557 // + because of .shstrtab 1558 for (unsigned i = 0; i < NumRegularSections + 1; ++i) 1559 WriteDataSectionData(Asm, Layout, *Sections[i]); 1560 1561 uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); 1562 WriteZeros(Padding); 1563 1564 // ... then the section header table ... 1565 WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 1566 SectionOffsetMap); 1567 1568 // ... and then the remaining sections ... 1569 for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 1570 WriteDataSectionData(Asm, Layout, *Sections[i]); 1571 } 1572 1573 bool 1574 ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 1575 const MCSymbolData &DataA, 1576 const MCFragment &FB, 1577 bool InSet, 1578 bool IsPCRel) const { 1579 if (DataA.getFlags() & ELF_STB_Weak) 1580 return false; 1581 return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 1582 Asm, DataA, FB,InSet, IsPCRel); 1583 } 1584 1585 MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1586 raw_ostream &OS, 1587 bool IsLittleEndian) { 1588 return new ELFObjectWriter(MOTW, OS, IsLittleEndian); 1589 } 1590