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