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