ELFObjectWriter.cpp revision 7a54997d670d92f7f0ece87911800aa68fcb8c6d
13565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//                     The LLVM Compiler Infrastructure
43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source
63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details.
73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file implements ELF object file writer information.
113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1431f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola#include "llvm/ADT/OwningPtr.h"
158f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola#include "llvm/ADT/SmallPtrSet.h"
163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/STLExtras.h"
173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h"
183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/Twine.h"
193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAssembler.h"
203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCELFSymbolFlags.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
24285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#include "llvm/MC/MCELFObjectWriter.h"
253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCObjectWriter.h"
263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSymbol.h"
283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h"
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h"
313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h"
333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "../Target/X86/X86FixupKinds.h"
354a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim#include "../Target/ARM/ARMFixupKinds.h"
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
383565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
40ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindolastatic unsigned GetType(const MCSymbolData &SD) {
41ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola  uint32_t Type = (SD.getFlags() & (0xf << ELF_STT_Shift)) >> ELF_STT_Shift;
42ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola  assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
43ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola         Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
44ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola         Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
45ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola         Type == ELF::STT_TLS);
46ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola  return Type;
47ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola}
48ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola
49e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindolastatic unsigned GetBinding(const MCSymbolData &SD) {
50e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift;
51e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
52e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola         Binding == ELF::STB_WEAK);
53e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  return Binding;
54e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola}
55e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola
56e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindolastatic void SetBinding(MCSymbolData &SD, unsigned Binding) {
57e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
58e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola         Binding == ELF::STB_WEAK);
59e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift);
60e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift));
61e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola}
62e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola
63152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindolastatic unsigned GetVisibility(MCSymbolData &SD) {
64152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  unsigned Visibility =
65152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola    (SD.getFlags() & (0xf << ELF_STV_Shift)) >> ELF_STV_Shift;
66152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
67152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
68152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  return Visibility;
69152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola}
70152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
714b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
72a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindolastatic bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
73a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  switch (Variant) {
745c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  default:
755c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    return false;
76a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOT:
77a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_PLT:
78a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOTPCREL:
79a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_TPOFF:
80a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_TLSGD:
81a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOTTPOFF:
82a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_INDNTPOFF:
83a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_NTPOFF:
84a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOTNTPOFF:
85a264f72d3fb9dec1427480fcf17ef3c746ea723aRafael Espindola  case MCSymbolRefExpr::VK_TLSLDM:
860cf15d61b7e3bf53f5a99f58ada37b93bc039559Rafael Espindola  case MCSymbolRefExpr::VK_DTPOFF:
87b4d1721eff7b43577e5f2e53f885973fb6c43683Rafael Espindola  case MCSymbolRefExpr::VK_TLSLD:
885c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    return true;
895c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
905c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola}
915c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
92127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindolastatic bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
93127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  const MCFixupKindInfo &FKI =
94127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
95127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola
96127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
97127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola}
98127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola
993565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingnamespace {
100115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  class ELFObjectWriter : public MCObjectWriter {
101d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  protected:
102b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner    /*static bool isFixupKindX86RIPRel(unsigned Kind) {
1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      return Kind == X86::reloc_riprel_4byte ||
1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming        Kind == X86::reloc_riprel_4byte_movq_load;
105b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner    }*/
1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// ELFSymbolData - Helper struct for containing some precomputed information
1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// on symbols.
1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    struct ELFSymbolData {
1113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      MCSymbolData *SymbolData;
1123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint64_t StringIndex;
1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint32_t SectionIndex;
1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      // Support lexicographic sorting.
1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      bool operator<(const ELFSymbolData &RHS) const {
117ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola        if (GetType(*SymbolData) == ELF::STT_FILE)
118ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola          return true;
119ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola        if (GetType(*RHS.SymbolData) == ELF::STT_FILE)
120ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola          return false;
12136c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer        return SymbolData->getSymbol().getName() <
12236c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer               RHS.SymbolData->getSymbol().getName();
1233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
1243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    };
1253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @name Relocation Data
1273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @{
1283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    struct ELFRelocationEntry {
1303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      // Make these big enough for both 32-bit and 64-bit
1313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint64_t r_offset;
1328f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      int Index;
1338f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      unsigned Type;
1348f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      const MCSymbol *Symbol;
1353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint64_t r_addend;
136858e7506e1fabe563eb4222c80ad0fad01641becJason W Kim
1374a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      ELFRelocationEntry()
1384a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
1394a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim
14010907426893019c6b7e59c886e41815d4fe50b19Jason W Kim      ELFRelocationEntry(uint64_t RelocOffset, int Idx,
14110907426893019c6b7e59c886e41815d4fe50b19Jason W Kim                         unsigned RelType, const MCSymbol *Sym,
1424a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim                         uint64_t Addend)
14310907426893019c6b7e59c886e41815d4fe50b19Jason W Kim        : r_offset(RelocOffset), Index(Idx), Type(RelType),
14410907426893019c6b7e59c886e41815d4fe50b19Jason W Kim          Symbol(Sym), r_addend(Addend) {}
1453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      // Support lexicographic sorting.
1473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      bool operator<(const ELFRelocationEntry &RE) const {
1483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming        return RE.r_offset < r_offset;
1493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
1503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    };
1513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15231f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola    /// The target specific ELF writer instance.
15331f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola    llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
15431f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola
1558f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
156484291c27319668ad99cb87def000254357736fbRafael Espindola    SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
15788182132470527e27231f09b25a885893e528c66Rafael Espindola    DenseMap<const MCSymbol *, const MCSymbol *> Renames;
1588f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
1593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    llvm::DenseMap<const MCSectionData*,
1603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                   std::vector<ELFRelocationEntry> > Relocations;
1613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
1623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @}
1643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @name Symbol Table Data
1653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @{
1663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    SmallString<256> StringTable;
1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    std::vector<ELFSymbolData> LocalSymbolData;
1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    std::vector<ELFSymbolData> ExternalSymbolData;
1703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    std::vector<ELFSymbolData> UndefinedSymbolData;
1713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @}
1733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1745c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    bool NeedsGOT;
1755c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
1767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    bool NeedsSymtabShndx;
1777be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
1783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // This holds the symbol table index of the last local symbol.
1793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned LastLocalSymbolIndex;
1803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // This holds the .strtab section index.
1813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned StringTableIndex;
1827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    // This holds the .symtab section index.
1837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    unsigned SymbolTableIndex;
1843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned ShstrtabIndex;
1863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1871f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
1881f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola    const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
1891f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                  const MCValue &Target,
1901f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                  const MCFragment &F) const;
1911f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
192bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
193bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    bool hasRelocationAddend() const {
194bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return TargetObjectWriter->hasRelocationAddend();
195bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    }
196bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola
1973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  public:
19831f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola    ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
199bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                    raw_ostream &_OS, bool IsLittleEndian)
200115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      : MCObjectWriter(_OS, IsLittleEndian),
20131f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola        TargetObjectWriter(MOTW),
202bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola        NeedsGOT(false), NeedsSymtabShndx(false){
2033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
204d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
205d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual ~ELFObjectWriter();
206d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
2073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void WriteWord(uint64_t W) {
208bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (is64Bit())
209115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar        Write64(W);
210b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner      else
211115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar        Write32(W);
2123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringLE16(char *buf, uint16_t Value) {
2153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[0] = char(Value >> 0);
2163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[1] = char(Value >> 8);
2173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringLE32(char *buf, uint32_t Value) {
22036c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringLE16(buf, uint16_t(Value >> 0));
221c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringLE16(buf + 2, uint16_t(Value >> 16));
2223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringLE64(char *buf, uint64_t Value) {
22536c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringLE32(buf, uint32_t(Value >> 0));
226c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringLE32(buf + 4, uint32_t(Value >> 32));
2273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringBE16(char *buf ,uint16_t Value) {
2303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[0] = char(Value >> 8);
2313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[1] = char(Value >> 0);
2323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringBE32(char *buf, uint32_t Value) {
23536c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringBE16(buf, uint16_t(Value >> 16));
236c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringBE16(buf + 2, uint16_t(Value >> 0));
2373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringBE64(char *buf, uint64_t Value) {
24036c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringBE32(buf, uint32_t(Value >> 32));
241c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringBE32(buf + 4, uint32_t(Value >> 0));
2423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
244af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String8(MCDataFragment &F, uint8_t Value) {
245af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[1];
246af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      buf[0] = Value;
247af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 1);
248af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    }
249af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola
250af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String16(MCDataFragment &F, uint16_t Value) {
251af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[2];
252115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      if (isLittleEndian())
253f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringLE16(buf, Value);
2543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      else
255f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringBE16(buf, Value);
256af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 2);
2573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
259af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String32(MCDataFragment &F, uint32_t Value) {
260af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[4];
261115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      if (isLittleEndian())
262f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringLE32(buf, Value);
2633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      else
264f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringBE32(buf, Value);
265af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 4);
2663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
268af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String64(MCDataFragment &F, uint64_t Value) {
269af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[8];
270115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      if (isLittleEndian())
271f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringLE64(buf, Value);
2723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      else
273f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringBE64(buf, Value);
274af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 8);
2753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
277d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections);
2783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
279d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
2807be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          uint64_t name, uint8_t info,
2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t value, uint64_t size,
2827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          uint8_t other, uint32_t shndx,
2837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          bool Reserved);
2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
285d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSymbol(MCDataFragment *SymtabF,  MCDataFragment *ShndxF,
2867be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                     ELFSymbolData &MSD,
2873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                     const MCAsmLayout &Layout);
2883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
289bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
290d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
2917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          const MCAssembler &Asm,
29271859c640f6a36251aca223fd503c58dc314e296Rafael Espindola                          const MCAsmLayout &Layout,
2934beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                          const SectionIndexMapTy &SectionIndexMap);
2943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
295d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
29656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  const MCFragment *Fragment, const MCFixup &Fixup,
29756a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  MCValue Target, uint64_t &FixedValue);
2983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
299d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
3000b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Kramer                                         const MCSymbol *S);
3013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Map from a group section to the signature symbol
3031f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
3041f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Map from a signature symbol to the group section
3051f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
3061f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
3073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// ComputeSymbolTable - Compute the symbol table data
3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ///
3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// \param StringTable [out] - The string table data.
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// \param StringIndexMap [out] - Map from symbol names to offsets in the
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// string table.
312d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void ComputeSymbolTable(MCAssembler &Asm,
3131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
3141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                            RevGroupMapTy RevGroupMap);
315bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
316d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void ComputeIndexMap(MCAssembler &Asm,
317bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola                         SectionIndexMapTy &SectionIndexMap);
3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
319d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                         const MCSectionData &SD);
3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
322d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) {
3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      for (MCAssembler::const_iterator it = Asm.begin(),
3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming             ie = Asm.end(); it != ie; ++it) {
3253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming        WriteRelocation(Asm, Layout, *it);
3263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
329d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
3304beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                const SectionIndexMapTy &SectionIndexMap);
3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
332d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout,
3331f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                             GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap);
3342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
33585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola    virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
33685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                          const MCAsmLayout &Layout);
3373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
338d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
3393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t Address, uint64_t Offset,
3403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t Size, uint32_t Link, uint32_t Info,
3413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t Alignment, uint64_t EntrySize);
3423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3431f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar    virtual void WriteRelocationsFragment(const MCAssembler &Asm,
3441f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar                                          MCDataFragment *F,
3451f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar                                          const MCSectionData *SD);
3461f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar
347fea753b397823c340608925eb7f3256a64a30017Rafael Espindola    virtual bool
348fea753b397823c340608925eb7f3256a64a30017Rafael Espindola    IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
349fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                           const MCSymbolData &DataA,
350fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                           const MCFragment &FB,
351fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                           bool InSet,
352fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                           bool IsPCRel) const;
3537070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
354d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
355d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSection(MCAssembler &Asm,
356c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                      const SectionIndexMapTy &SectionIndexMap,
3572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      uint32_t GroupSymbolIndex,
358c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                      uint64_t Offset, uint64_t Size, uint64_t Alignment,
359c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                      const MCSectionELF &Section);
36056a399023aba6cf1348533df04732950c43eaca7Jason W Kim
36156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  protected:
36256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
36356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  bool IsPCRel, bool IsRelocWithSymbol,
36456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  int64_t Addend) = 0;
3653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  };
3663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
367d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  //===- X86ELFObjectWriter -------------------------------------------===//
368d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
369d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  class X86ELFObjectWriter : public ELFObjectWriter {
370d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  public:
37131f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola    X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
372bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                       raw_ostream &_OS,
373bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                       bool IsLittleEndian);
3744b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
375d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual ~X86ELFObjectWriter();
37656a399023aba6cf1348533df04732950c43eaca7Jason W Kim  protected:
37756a399023aba6cf1348533df04732950c43eaca7Jason W Kim    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
37856a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  bool IsPCRel, bool IsRelocWithSymbol,
37956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  int64_t Addend);
380d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  };
381d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
382d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
383d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  //===- ARMELFObjectWriter -------------------------------------------===//
384d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
385d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  class ARMELFObjectWriter : public ELFObjectWriter {
386d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  public:
38731f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola    ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
388bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                       raw_ostream &_OS,
389bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                       bool IsLittleEndian);
3904b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
391d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual ~ARMELFObjectWriter();
39285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  protected:
39356a399023aba6cf1348533df04732950c43eaca7Jason W Kim    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
39456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  bool IsPCRel, bool IsRelocWithSymbol,
39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  int64_t Addend);
396d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  };
3974b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
3984b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  //===- MBlazeELFObjectWriter -------------------------------------------===//
3994b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
4004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  class MBlazeELFObjectWriter : public ELFObjectWriter {
4014b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  public:
40231f3578b00a2ea85fb730b690f0478529103c748Rafael Espindola    MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
403bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                          raw_ostream &_OS,
404bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                          bool IsLittleEndian);
4054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
4064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    virtual ~MBlazeELFObjectWriter();
40756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  protected:
40856a399023aba6cf1348533df04732950c43eaca7Jason W Kim    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
40956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  bool IsPCRel, bool IsRelocWithSymbol,
41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                  int64_t Addend);
4114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  };
4123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
414d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
415d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
416d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
418115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
419115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  unsigned NumberOfSections) {
4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
4223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
4233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
4243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
4253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
4263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0x7f); // e_ident[EI_MAG0]
4293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('E');  // e_ident[EI_MAG1]
4303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('L');  // e_ident[EI_MAG2]
4313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('F');  // e_ident[EI_MAG3]
4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
433bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
4343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
436115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
4373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
4395baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
440bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  switch (TargetObjectWriter->getOSType()) {
4415baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    case Triple::FreeBSD:  Write8(ELF::ELFOSABI_FREEBSD); break;
4425baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    case Triple::Linux:    Write8(ELF::ELFOSABI_LINUX); break;
4435baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    default:               Write8(ELF::ELFOSABI_NONE); break;
4445baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  }
4453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0);                  // e_ident[EI_ABIVERSION]
4463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
4483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(ELF::ET_REL);             // e_type
4503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
451bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
4523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(ELF::EV_CURRENT);         // e_version
4543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
4553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
456bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
457eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
4583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make this configurable.
4603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(0);   // e_flags = whatever the target wants
4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
463bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
4643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phentsize = prog header entry size
4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phnum = # prog header entries = 0
4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
469bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
4703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
4727be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
4737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(0);
4747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
4757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(NumberOfSections);
4763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
4787be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
4797be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ELF::SHN_XINDEX);
4807be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
4817be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ShstrtabIndex);
4823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
484115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
485115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
486115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t name,
487115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint8_t info, uint64_t value,
488115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t size, uint8_t other,
489115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t shndx,
490115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       bool Reserved) {
4917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (ShndxF) {
4927be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
493af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, shndx);
4947be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    else
495af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, 0);
4967be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
4977be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
498af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
499af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    uint16_t(ELF::SHN_XINDEX) : shndx;
5003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
501bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
502af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
503af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
504af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
505af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
506af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, value); // st_value
507af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, size);  // st_size
5083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
509af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
510af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, value); // st_value
511af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, size);  // st_size
512af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
513af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
514af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
5153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
5163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5182c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindolastatic uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) {
5192c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (Data.isCommon() && Data.isExternal())
5202c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return Data.getCommonAlignment();
5212c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
5222c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
523d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
524d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  if (Symbol.isAbsolute() && Symbol.isVariable()) {
525d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    if (const MCExpr *Value = Symbol.getVariableValue()) {
526d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      int64_t IntValue;
527d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      if (Value->EvaluateAsAbsolute(IntValue, Layout))
528d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky	return (uint64_t)IntValue;
529d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    }
530d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  }
531d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
5322c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (!Symbol.isInSection())
5332c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return 0;
5342c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
535ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola  if (Data.getFragment())
536ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola    return Layout.getSymbolOffset(&Data);
5372c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
5382c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  return 0;
5392c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
5402c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
54185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
54285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                               const MCAsmLayout &Layout) {
54388182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
54488182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
54588182132470527e27231f09b25a885893e528c66Rafael Espindola
54688182132470527e27231f09b25a885893e528c66Rafael Espindola  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
54788182132470527e27231f09b25a885893e528c66Rafael Espindola         ie = Asm.symbol_end(); it != ie; ++it) {
54888182132470527e27231f09b25a885893e528c66Rafael Espindola    const MCSymbol &Alias = it->getSymbol();
54994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &Symbol = Alias.AliasedSymbol();
550f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    MCSymbolData &SD = Asm.getSymbolData(Symbol);
551f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
552f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
553f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    if (&Symbol == &Alias)
554f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
555f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
55607ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
55788182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
55888182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
55988182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
56088182132470527e27231f09b25a885893e528c66Rafael Espindola
561f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
562f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
563f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    it->setExternal(SD.isExternal());
564f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    SetBinding(*it, GetBinding(SD));
565f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
56607ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
56788182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
56888182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
56988182132470527e27231f09b25a885893e528c66Rafael Espindola
57083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
57183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
57283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
57383ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
57483ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
57507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
57688182132470527e27231f09b25a885893e528c66Rafael Espindola  }
57788182132470527e27231f09b25a885893e528c66Rafael Espindola}
57888182132470527e27231f09b25a885893e528c66Rafael Espindola
579115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
580115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  MCDataFragment *ShndxF,
581115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  ELFSymbolData &MSD,
582115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
583de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &OrigData = *MSD.SymbolData;
584de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &Data =
58594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
586152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
5877be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
5887be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Data.getSymbol().isVariable();
5897be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
590152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Binding = GetBinding(OrigData);
591152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Visibility = GetVisibility(OrigData);
592152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Type = GetType(Data);
593152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
594152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
595152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Other = Visibility;
596152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
5972c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  uint64_t Value = SymbolValue(Data, Layout);
5983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
5993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
600f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(!(Data.isCommon() && !Data.isExternal()));
601f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
602f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  const MCExpr *ESize = Data.getSize();
603f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  if (ESize) {
604f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    int64_t Res;
605f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    if (!ESize->EvaluateAsAbsolute(Res, Layout))
606f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola      report_fatal_error("Size expression must be absolute.");
607f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    Size = Res;
6083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
6117be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
6127be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                   Size, Other, MSD.SectionIndex, IsReserved);
6133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
615115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
616115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
617115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAssembler &Asm,
618115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAsmLayout &Layout,
6194beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                     const SectionIndexMapTy &SectionIndexMap) {
6203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The string table must be emitted first because we need the index
6213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // into the string table for all the symbol names.
6223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(StringTable.size() && "Missing string table");
6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make sure the start of the symbol table is aligned.
6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry is the undefined symbol entry.
6277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write the symbol table entries.
6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
6313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
6323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = LocalSymbolData[i];
6337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
6343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
63671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Write out a symbol table entry for each regular section.
6374beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
6384beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola       ++i) {
639a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    const MCSectionELF &Section =
6404beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola      static_cast<const MCSectionELF&>(i->getSection());
6414beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola    if (Section.getType() == ELF::SHT_RELA ||
6424beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_REL ||
6434beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_STRTAB ||
6444beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_SYMTAB)
645a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman      continue;
6467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
6474beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false);
648a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    LastLocalSymbolIndex++;
649a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman  }
6503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = ExternalSymbolData[i];
6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
6543223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    assert(((Data.getFlags() & ELF_STB_Global) ||
6553223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola            (Data.getFlags() & ELF_STB_Weak)) &&
6563223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola           "External symbol requires STB_GLOBAL or STB_WEAK flag");
6577be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
658e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola    if (GetBinding(Data) == ELF::STB_LOCAL)
6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
6633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = UndefinedSymbolData[i];
6643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
6657be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
666e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola    if (GetBinding(Data) == ELF::STB_LOCAL)
6673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6711f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
6721f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCValue &Target,
6731f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCFragment &F) const {
6741f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
67594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
67694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol *Renamed = Renames.lookup(&Symbol);
67794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
67894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola
67994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (ASymbol.isUndefined()) {
68094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
68194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
68294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &ASymbol;
6831f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
6841f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
68594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (SD.isExternal()) {
68694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
68794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
68894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
68994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
6907eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
6917eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola  const MCSectionELF &Section =
69294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    static_cast<const MCSectionELF&>(ASymbol.getSection());
69325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  const SectionKind secKind = Section.getKind();
6947eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
69525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isBSS())
6961f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola    return NULL;
6977eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
69825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isThreadLocal()) {
69925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    if (Renamed)
70025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola      return Renamed;
70125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    return &Symbol;
70225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
70325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
7048cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
7053729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola  const MCSectionELF &Sec2 =
7063729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola    static_cast<const MCSectionELF&>(F.getParent()->getSection());
7073729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
7088cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  if (&Sec2 != &Section &&
709c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola      (Kind == MCSymbolRefExpr::VK_PLT ||
710c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
71125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
71294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
71394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
71494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
71594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
7163729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
7171f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  if (Section.getFlags() & MCSectionELF::SHF_MERGE) {
71894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Target.getConstant() == 0)
71994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return NULL;
72094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
72194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
72294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
7231f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
724c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
7251f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  return NULL;
72673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
72773ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
7283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
72956a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
73056a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCAsmLayout &Layout,
73156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFragment *Fragment,
73256a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFixup &Fixup,
73356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       MCValue Target,
73456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       uint64_t &FixedValue) {
73556a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Addend = 0;
73656a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int Index = 0;
73756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Value = Target.getConstant();
73856a399023aba6cf1348533df04732950c43eaca7Jason W Kim  const MCSymbol *RelocSymbol = NULL;
73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim
740127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  if (!Target.isAbsolute()) {
74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
74356a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
74456a399023aba6cf1348533df04732950c43eaca7Jason W Kim    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
74556a399023aba6cf1348533df04732950c43eaca7Jason W Kim
74656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
74756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
74856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
74956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      IsPCRel = true;
75056a399023aba6cf1348533df04732950c43eaca7Jason W Kim
75156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
75256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t a = Layout.getSymbolOffset(&SDB);
75356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
75456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Ofeset of the relocation in the section
75556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
75656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += b - a;
75756a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
75856a399023aba6cf1348533df04732950c43eaca7Jason W Kim
75956a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (!RelocSymbol) {
76056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
76156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCFragment *F = SD.getFragment();
76256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
76356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = F->getParent()->getOrdinal() + 1;
76456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
76556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
76656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += Layout.getSymbolOffset(&SD);
76756a399023aba6cf1348533df04732950c43eaca7Jason W Kim    } else {
76856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
76956a399023aba6cf1348533df04732950c43eaca7Jason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
77056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      else
77156a399023aba6cf1348533df04732950c43eaca7Jason W Kim        UsedInReloc.insert(RelocSymbol);
77256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = -1;
77356a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
77456a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Addend = Value;
77556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    // Compensate for the addend on i386.
776bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit())
77756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value = 0;
77856a399023aba6cf1348533df04732950c43eaca7Jason W Kim  }
77956a399023aba6cf1348533df04732950c43eaca7Jason W Kim
78056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  FixedValue = Value;
78156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
78256a399023aba6cf1348533df04732950c43eaca7Jason W Kim                               (RelocSymbol != 0), Addend);
78356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
78456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
78556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Fixup.getOffset();
78656a399023aba6cf1348533df04732950c43eaca7Jason W Kim
787bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (!hasRelocationAddend())
788bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    Addend = 0;
78956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
79056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
79156a399023aba6cf1348533df04732950c43eaca7Jason W Kim}
79256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
79356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
7940b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t
795115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
796115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             const MCSymbol *S) {
7977b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer  MCSymbolData &SD = Asm.getSymbolData(*S);
798ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  return SD.getIndex();
7993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
8003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
801737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindolastatic bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
80288182132470527e27231f09b25a885893e528c66Rafael Espindola                       bool Used, bool Renamed) {
803484291c27319668ad99cb87def000254357736fbRafael Espindola  if (Data.getFlags() & ELF_Other_Weakref)
804484291c27319668ad99cb87def000254357736fbRafael Espindola    return false;
805484291c27319668ad99cb87def000254357736fbRafael Espindola
806bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
807bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
808bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
80988182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
81088182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
81188182132470527e27231f09b25a885893e528c66Rafael Espindola
812737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
813a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
814d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
815d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola    return true;
816d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola
81794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &A = Symbol.AliasedSymbol();
818d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (!A.isVariable() && A.isUndefined() && !Data.isCommon())
819a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
820a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
821737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
822737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
823737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
824bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
825737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
826737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
827737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
828737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
829737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
8301f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindolastatic bool isLocal(const MCSymbolData &Data, bool isSignature,
8311f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    bool isUsedInReloc) {
832737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (Data.isExternal())
833737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
834737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
835737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
83694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
8371f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8381f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
8391f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (isSignature && !isUsedInReloc)
8401f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      return true;
8411f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
842737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
8431f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  }
844737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
845737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
846737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
847737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
848115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
849115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                      SectionIndexMapTy &SectionIndexMap) {
850bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  unsigned Index = 1;
851bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
852bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
853bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    const MCSectionELF &Section =
854bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
8562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionIndexMap[&Section] = Index++;
8582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
8592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
8602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
8612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         ie = Asm.end(); it != ie; ++it) {
8622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
8632ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() == ELF::SHT_GROUP)
8652ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
866bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    SectionIndexMap[&Section] = Index++;
867bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  }
868bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola}
869bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
870115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
8711f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
8721f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      RevGroupMapTy RevGroupMap) {
8735c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  // FIXME: Is this the correct place to do this?
8745c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  if (NeedsGOT) {
8755c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
8765c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
8775c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
8785c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    Data.setExternal(true);
879f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    SetBinding(Data, ELF::STB_GLOBAL);
8805c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
8815c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
8823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Build section lookup table.
883ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  int NumRegularSections = Asm.size();
8843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Index 0 is always the empty string.
8863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringMap<uint64_t> StringIndexMap;
8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTable += '\x00';
8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
889a0949b50dcea35c08b50542091f97275f401529dRafael Espindola  // Add the data for the symbols.
8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
8913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.symbol_end(); it != ie; ++it) {
8923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSymbol &Symbol = it->getSymbol();
8933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
894484291c27319668ad99cb87def000254357736fbRafael Espindola    bool Used = UsedInReloc.count(&Symbol);
895484291c27319668ad99cb87def000254357736fbRafael Espindola    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
8961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool isSignature = RevGroupMap.count(&Symbol);
8971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8981f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!isInSymtab(Asm, *it,
8991f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    Used || WeakrefUsed || isSignature,
90088182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
9013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
9023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
9043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MSD.SymbolData = it;
90594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
9063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9071f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Undefined symbols are global, but this is the first place we
9081f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // are able to set it.
9091f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool Local = isLocal(*it, isSignature, Used);
9101f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!Local && GetBinding(*it) == ELF::STB_LOCAL) {
9111f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
9121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      SetBinding(*it, ELF::STB_GLOBAL);
9131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      SetBinding(SD, ELF::STB_GLOBAL);
9141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    }
9151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
916484291c27319668ad99cb87def000254357736fbRafael Espindola    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
917484291c27319668ad99cb87def000254357736fbRafael Espindola      SetBinding(*it, ELF::STB_WEAK);
918484291c27319668ad99cb87def000254357736fbRafael Espindola
919f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    if (it->isCommon()) {
920a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
921f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
922bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
923a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      MSD.SectionIndex = ELF::SHN_ABS;
92488182132470527e27231f09b25a885893e528c66Rafael Espindola    } else if (RefSymbol.isUndefined()) {
9251f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      if (isSignature && !Used)
9261f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
9271f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      else
9281f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
9293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
930bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
931bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola        static_cast<const MCSectionELF&>(RefSymbol.getSection());
932bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
9337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
9347be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola        NeedsSymtabShndx = true;
9353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
9365df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
9375df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
93888182132470527e27231f09b25a885893e528c66Rafael Espindola    // The @@@ in symbol version is replaced with @ in undefined symbols and
93988182132470527e27231f09b25a885893e528c66Rafael Espindola    // @@ in defined ones.
94088182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
9411261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    SmallString<32> Buf;
9421261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer
94388182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = Name.find("@@@");
94488182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos != StringRef::npos) {
9451261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(0, Pos);
9461261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
9471261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(Pos + Skip);
9481261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Name = Buf;
94988182132470527e27231f09b25a885893e528c66Rafael Espindola    }
95088182132470527e27231f09b25a885893e528c66Rafael Espindola
9511261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    uint64_t &Entry = StringIndexMap[Name];
952a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (!Entry) {
953a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      Entry = StringTable.size();
9541261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      StringTable += Name;
955a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      StringTable += '\x00';
9563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
957a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    MSD.StringIndex = Entry;
958a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (MSD.SectionIndex == ELF::SHN_UNDEF)
959a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      UndefinedSymbolData.push_back(MSD);
960a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else if (Local)
961a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
962a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
963a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
9643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
9653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
9673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
9683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
9693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
9703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
9723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
973ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  unsigned Index = 1;
9743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
9753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    LocalSymbolData[i].SymbolData->setIndex(Index++);
976ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
977ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  Index += NumRegularSections;
978ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
9793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
9803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ExternalSymbolData[i].SymbolData->setIndex(Index++);
9813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
9823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
9833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
9843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
985115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
986115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                      const MCSectionData &SD) {
9873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (!Relocations[&SD].empty()) {
9883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCContext &Ctx = Asm.getContext();
9894283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *RelaSection;
9903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
9913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      static_cast<const MCSectionELF&>(SD.getSection());
9923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const StringRef SectionName = Section.getSectionName();
994bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
9953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    RelaSectionName += SectionName;
996299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer
997299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    unsigned EntrySize;
998bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (hasRelocationAddend())
999bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
1000299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    else
1001bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
10023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1003bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    RelaSection = Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
1004377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer                                    ELF::SHT_RELA : ELF::SHT_REL, 0,
10053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                    SectionKind::getReadOnly(),
10062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                                    EntrySize, "");
10073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
1009bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    RelaSD.setAlignment(is64Bit() ? 8 : 4);
10103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCDataFragment *F = new MCDataFragment(&RelaSD);
10123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    WriteRelocationsFragment(Asm, F, &SD);
10143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1017115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
1018115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
1019115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
1020115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
1021115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
1022115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
10233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Name);        // sh_name: index into string table
10243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Type);        // sh_type
10253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
10263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
10273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
10283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
10293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Link);        // sh_link
10303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Info);        // sh_info
10313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
10323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1035115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
1036115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               MCDataFragment *F,
1037115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               const MCSectionData *SD) {
10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // sort by the r_offset just like gnu as does
10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(Relocs.begin(), Relocs.end());
10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
10433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFRelocationEntry entry = Relocs[e - i - 1];
10443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
104512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    if (!entry.Index)
104612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      ;
104712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    else if (entry.Index < 0)
10488f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
10498f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    else
105012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      entry.Index += LocalSymbolData.size();
1051bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit()) {
1052af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, entry.r_offset);
10535e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10548f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf64_Rela ERE64;
10558f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE64.setSymbolAndType(entry.Index, entry.Type);
1056af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, ERE64.r_info);
10575e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1058bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
1059af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String64(*F, entry.r_addend);
10605e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
1061af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, entry.r_offset);
10625e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10638f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
10648f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE32.setSymbolAndType(entry.Index, entry.Type);
1065af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, ERE32.r_info);
10665e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1067bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
1068af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String32(*F, entry.r_addend);
10695e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
10703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1073115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
1074115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             MCAsmLayout &Layout,
10754beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                    const SectionIndexMapTy &SectionIndexMap) {
10763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCContext &Ctx = Asm.getContext();
10773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F;
10783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1079bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
10803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
108138738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
10824283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *ShstrtabSection =
10837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
10843f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                      SectionKind::getReadOnly());
108571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
108671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabSD.setAlignment(1);
108771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabIndex = Asm.size();
108871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
10894283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *SymtabSection =
10907be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
10917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                      SectionKind::getReadOnly(),
10922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      EntrySize, "");
10933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
1094bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
10957be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  SymbolTableIndex = Asm.size();
10967be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
10977be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCSectionData *SymtabShndxSD = NULL;
10987be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
10997be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
11004283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *SymtabShndxSection =
11017be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
11022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                        SectionKind::getReadOnly(), 4, "");
11037be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
11047be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD->setAlignment(4);
11057be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
11063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  const MCSection *StrtabSection;
11083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
11093f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                    SectionKind::getReadOnly());
11103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
11113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSD.setAlignment(1);
11123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTableIndex = Asm.size();
11133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1114c3c413f63117896f186fc4385bdaac0578d3613fRafael Espindola  WriteRelocations(Asm, Layout);
111571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
111671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Symbol table
111771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  F = new MCDataFragment(&SymtabSD);
11187be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCDataFragment *ShndxF = NULL;
11197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
11207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShndxF = new MCDataFragment(SymtabShndxSD);
11217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
11224beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
112371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
11243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&StrtabSD);
11253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents().append(StringTable.begin(), StringTable.end());
11263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&ShstrtabSD);
11283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Section header string table.
11303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
11313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry of a string table holds a null character so skip
11323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // section 0.
11333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Index = 1;
11343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents() += '\x00';
11353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  StringMap<uint64_t> SecStringMap;
11373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::const_iterator it = Asm.begin(),
11383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.end(); it != ie; ++it) {
11393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
1140368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer      static_cast<const MCSectionELF&>(it->getSection());
114151efe7a253190b672519e8388ce5d45f1dcf1a24Rafael Espindola    // FIXME: We could merge suffixes like in .text and .rela.text.
11423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    StringRef Name = Section.getSectionName();
11442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (SecStringMap.count(Name)) {
11452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      SectionStringTableIndex[&Section] =  SecStringMap[Name];
11462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
11472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
11483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the index into the string table so we can write it
11493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // into the sh_name field of the section header table.
11502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionStringTableIndex[&Section] = Index;
11512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SecStringMap[Name] = Index;
11523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Index += Name.size() + 1;
11542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    F->getContents() += Name;
11553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    F->getContents() += '\x00';
11563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
11577070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola}
11587070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
1159fea753b397823c340608925eb7f3256a64a30017Rafael Espindolabool
1160fea753b397823c340608925eb7f3256a64a30017Rafael EspindolaELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
1161fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                                      const MCSymbolData &DataA,
1162fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                                      const MCFragment &FB,
1163fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                                      bool InSet,
1164fea753b397823c340608925eb7f3256a64a30017Rafael Espindola                                                      bool IsPCRel) const {
11652c920850343810535c0cd8720a81eddf7997663aRafael Espindola  // FIXME: This is in here just to match gnu as output. If the two ends
11662c920850343810535c0cd8720a81eddf7997663aRafael Espindola  // are in the same section, there is nothing that the linker can do to
11672c920850343810535c0cd8720a81eddf7997663aRafael Espindola  // break it.
11687070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  if (DataA.isExternal())
11697070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola    return false;
11707070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
1171fea753b397823c340608925eb7f3256a64a30017Rafael Espindola  const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection();
1172fea753b397823c340608925eb7f3256a64a30017Rafael Espindola  const MCSection &SecB = FB.getParent()->getSection();
1173fea753b397823c340608925eb7f3256a64a30017Rafael Espindola  // On ELF A - B is absolute if A and B are in the same section.
1174fea753b397823c340608925eb7f3256a64a30017Rafael Espindola  return &SecA == &SecB;
11753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
11763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1177115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
1178115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                          MCAsmLayout &Layout,
11791f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                          GroupMapTy &GroupMap,
11801f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                          RevGroupMapTy &RevGroupMap) {
11812ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Build the groups
11822ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
11832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it) {
11842ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
11852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
11862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!(Section.getFlags() & MCSectionELF::SHF_GROUP))
11872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
11882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
11892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSymbol *SignatureSymbol = Section.getGroup();
11902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Asm.getOrCreateSymbolData(*SignatureSymbol);
11911f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
11922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!Group) {
11932ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Group = Asm.getContext().CreateELFGroupSection();
11942ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
11952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Data.setAlignment(4);
11962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCDataFragment *F = new MCDataFragment(&Data);
11972ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      String32(*F, ELF::GRP_COMDAT);
11982ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
11992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupMap[Group] = SignatureSymbol;
12002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12012ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Add sections to the groups
12032ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  unsigned Index = 1;
12041f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  unsigned NumGroups = RevGroupMap.size();
12052ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
12062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it, ++Index) {
12072ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
12082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
12092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!(Section.getFlags() & MCSectionELF::SHF_GROUP))
12102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
12111f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    // FIXME: we could use the previous fragment
12142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCDataFragment *F = new MCDataFragment(&Data);
12152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    String32(*F, NumGroups + Index);
12162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
12182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1219115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
1220115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const SectionIndexMapTy &SectionIndexMap,
1221115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint32_t GroupSymbolIndex,
1222115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Offset, uint64_t Size,
1223115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Alignment,
1224115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const MCSectionELF &Section) {
1225c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
1226c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
1227c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1228c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
1229c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
1230c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionStringTableIndex[&Section];
1231c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = 0;
1232c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1233c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1234c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
1235c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
1236c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *SymtabSection;
1237c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *InfoSection;
1238c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
1239c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                   0,
12403f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                   SectionKind::getReadOnly());
1241c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionIndexMap.lookup(SymtabSection);
1242c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
1243c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1244c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Remove ".rel" and ".rela" prefixes.
1245c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
1246c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
1247c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1248c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    InfoSection = Asm.getContext().getELFSection(SectionName,
1249c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                 ELF::SHT_PROGBITS, 0,
12503f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                 SectionKind::getReadOnly());
1251c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
1252c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1253c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1254c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1255c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
1256c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
1257c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
1258c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
1259c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1260c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1261c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
1262c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
1263c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1264c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1265c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_PROGBITS:
1266c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_STRTAB:
1267c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NOBITS:
126898976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola  case ELF::SHT_NOTE:
1269c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NULL:
1270c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_ARM_ATTRIBUTES:
1271c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Nothing to do.
1272c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1273c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
12742ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  case ELF::SHT_GROUP: {
12752ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
12762ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
12772ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
12782ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12792ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  default:
1281c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(0 && "FIXME: sh_type value not supported!");
1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
1286c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Alignment, Section.getEntrySize());
1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola}
1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
12906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic bool IsELFMetaDataSection(const MCSectionData &SD) {
1291f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola  return SD.getOrdinal() == ~UINT32_C(0) &&
12926db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    !SD.getSection().isVirtualSection();
12936db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
12946db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
12956db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic uint64_t DataSectionSize(const MCSectionData &SD) {
12966db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  uint64_t Ret = 0;
12976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
12986db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola       ++i) {
12996db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    const MCFragment &F = *i;
13006db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    assert(F.getKind() == MCFragment::FT_Data);
13016db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    Ret += cast<MCDataFragment>(F).getContents().size();
13026db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
13036db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Ret;
13046db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13056db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13066db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
13076db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola                                   const MCSectionData &SD) {
13086db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
13096db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
13106db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Layout.getSectionFileSize(&SD);
13116db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13126db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
131385f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolastatic uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
131485f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                      const MCSectionData &SD) {
13156db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
13166db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
131785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  return Layout.getSectionAddressSize(&SD);
13186db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13196db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13206db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic void WriteDataSectionData(ELFObjectWriter *W, const MCSectionData &SD) {
13216db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
13226db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola       ++i) {
13236db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    const MCFragment &F = *i;
13246db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    assert(F.getKind() == MCFragment::FT_Data);
13256db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    W->WriteBytes(cast<MCDataFragment>(F).getContents().str());
13266db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
13276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13286db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
1329115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
1330115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
13312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  GroupMapTy GroupMap;
13321f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
13331f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
13341f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                      RevGroupMap);
13352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1336bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1337bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
1338bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap);
1339bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
13408f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola  // Compute symbol table information.
13411f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap);
13428f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
13433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
13444beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         const_cast<MCAsmLayout&>(Layout),
13454beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         SectionIndexMap);
13463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13471d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola  // Update to include the metadata sections.
13481d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap);
13491d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
13503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Add 1 for the null section.
13513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  unsigned NumSections = Asm.size() + 1;
1352bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
1353bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
1354bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                    sizeof(ELF::Elf32_Ehdr);
1355a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t FileOff = HeaderSize;
13563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  std::vector<const MCSectionELF*> Sections;
13582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  Sections.resize(NumSections);
13592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
13602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (SectionIndexMapTy::const_iterator i=
13612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
13622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
13632ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Sections[p.second] = p.first;
13642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
13652ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
13662ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (unsigned i = 1; i < NumSections; ++i) {
13672ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
13682ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
13693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1370a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1371a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Get the size of the section in the output file (including padding).
13736db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
13743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
13753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1376a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
1377a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the ELF header ...
1379a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteHeader(FileOff - HeaderSize, NumSections);
1380a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
1381a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = HeaderSize;
13823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ... then all of the sections ...
13843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  DenseMap<const MCSection*, uint64_t> SectionOffsetMap;
13853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (unsigned i = 1; i < NumSections; ++i) {
13872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
13882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
1389a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
1390a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
1391a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    WriteZeros(Padding);
1392a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff += Padding;
1393a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
13952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionOffsetMap[&Section] = FileOff;
139644cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
13976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
13983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13996db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    if (IsELFMetaDataSection(SD))
14006db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola      WriteDataSectionData(this, SD);
14016db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    else
14025d2477cecf53bef911f57423a5cecb743d4286faDaniel Dunbar      Asm.WriteSectionData(&SD, Layout);
14033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
14043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1405a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
1406a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteZeros(Padding);
1407a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff += Padding;
1408a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
14093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ... and then the section header table.
14103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Should we align the section header table?
14113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
14123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Null section first.
14137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  uint64_t FirstSectionSize =
14147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
14157be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  uint32_t FirstSectionLink =
14167be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
14177be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
14183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
14192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (unsigned i = 1; i < NumSections; ++i) {
14202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
14212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
14222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    uint32_t GroupSymbolIndex;
14232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
14242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      GroupSymbolIndex = 0;
14252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    else
14262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]);
14273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
142885f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola    uint64_t Size = GetSectionAddressSize(Layout, SD);
14296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
14302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
14316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola                 SectionOffsetMap[&Section], Size,
1432c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                 SD.getAlignment(), Section);
14333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
14343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
14353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
14366024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
14376024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola                                            raw_ostream &OS,
1438bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                            bool IsLittleEndian) {
1439bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  switch (MOTW->getEMachine()) {
1440d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_386:
1441d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_X86_64:
1442bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break;
1443d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_ARM:
1444bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
14454b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case ELF::EM_MBLAZE:
1446bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
14473285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer    default: llvm_unreachable("Unsupported architecture"); break;
1448d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1449d3443e99e43945fdb0742177da06a32fa225740dJason W Kim}
1450d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1451d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1452d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter
1453d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===//
1454d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
145531f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1456bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       raw_ostream &_OS,
1457bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       bool IsLittleEndian)
1458bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
1459d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1460d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1461d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter()
1462d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1463d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
146485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
146585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim                                          const MCFixup &Fixup,
146656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsPCRel,
146756a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsRelocWithSymbol,
146856a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          int64_t Addend) {
146985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
147085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
147185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
1472a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim  unsigned Type = 0;
147385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (IsPCRel) {
147485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
147585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: assert(0 && "Unimplemented");
14763fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim    case FK_Data_4:
14773fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      switch (Modifier) {
14783fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default: llvm_unreachable("Unsupported Modifier");
14793fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_None:
14803fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_BASE_PREL; break;
14813fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_TLSGD:
14823fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        assert(0 && "unimplemented"); break;
14833fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
14843fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_TLS_IE32;
14853fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      } break;
14863fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim    case ARM::fixup_arm_branch:
14873fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      switch (Modifier) {
14883fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_PLT:
14893fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_PLT32; break;
14903fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default:
14913fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_CALL; break;
14923fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      } break;
149385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
149485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  } else {
149585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
149685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: llvm_unreachable("invalid fixup kind!");
1497a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim    case FK_Data_4:
1498a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      switch (Modifier) {
14993fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default: llvm_unreachable("Unsupported Modifier"); break;
15003fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOT:
15013fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_GOT_BREL; break;
15023fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_TLSGD:
15033fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_TLS_GD32; break;
1504f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      case MCSymbolRefExpr::VK_ARM_TPOFF:
1505f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim        Type = ELF::R_ARM_TLS_LE32; break;
1506a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
15073fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_TLS_IE32; break;
1508f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      case MCSymbolRefExpr::VK_None:
1509f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim        Type = ELF::R_ARM_ABS32; break;
15103fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOTOFF:
15113fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_GOTOFF32; break;
1512a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      } break;
1513dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_ldst_pcrel_12:
15149d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    case ARM::fixup_arm_pcrel_10:
1515dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_adr_pcrel_12:
1516662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach    case ARM::fixup_arm_thumb_bl:
1517b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach    case ARM::fixup_arm_thumb_cb:
1518b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling    case ARM::fixup_arm_thumb_cp:
1519e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach    case ARM::fixup_arm_thumb_br:
152085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      assert(0 && "Unimplemented"); break;
152185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_branch:
1522f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      // FIXME: Differentiate between R_ARM_CALL and
1523f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      // R_ARM_JUMP24 (latter used for conditional jumps)
1524a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      Type = ELF::R_ARM_CALL; break;
152585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_movt_hi16:
1526a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      Type = ELF::R_ARM_MOVT_ABS; break;
152785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_movw_lo16:
1528a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      Type = ELF::R_ARM_MOVW_ABS_NC; break;
152985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
153085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  }
153185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
153285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (RelocNeedsGOT(Modifier))
153385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    NeedsGOT = true;
1534a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim
1535a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim  return Type;
153685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim}
153785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
15384b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===//
1539d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
154031f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1541bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                             raw_ostream &_OS,
1542bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                             bool IsLittleEndian)
1543bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
15444b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
15454b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15464b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
15474b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
15484b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
154956a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
15504b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             const MCFixup &Fixup,
155156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             bool IsPCRel,
155256a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             bool IsRelocWithSymbol,
155356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             int64_t Addend) {
15544b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  // determine the type of the relocation
15554b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  unsigned Type;
15564b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  if (IsPCRel) {
15574b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
15584b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default:
15594b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      llvm_unreachable("Unimplemented");
1560e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_4:
15614b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_64_PCREL;
15624b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
1563e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_2:
15644b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32_PCREL;
15654b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
15664b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
15674b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  } else {
15684b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
15694b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default: llvm_unreachable("invalid fixup kind!");
15704b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_4:
157156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Type = ((IsRelocWithSymbol || Addend !=0)
157256a399023aba6cf1348533df04732950c43eaca7Jason W Kim              ? ELF::R_MICROBLAZE_32
157356a399023aba6cf1348533df04732950c43eaca7Jason W Kim              : ELF::R_MICROBLAZE_64);
15744b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
15754b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_2:
15764b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32;
15774b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
15784b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
15794b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  }
158056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  return Type;
15814b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
1582d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1583d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===//
1584d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1585d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
158631f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1587bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       raw_ostream &_OS,
1588bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       bool IsLittleEndian)
1589bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
1590d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1591d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1592d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter()
1593d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1594d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
159556a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
159656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          const MCFixup &Fixup,
159756a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsPCRel,
159856a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsRelocWithSymbol,
159956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          int64_t Addend) {
1600d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  // determine the type of the relocation
1601d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
160212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
160312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
1604d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  unsigned Type;
1605bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
1606d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
16073a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
16083a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
16093a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_8:
16103a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
16113a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        Type = ELF::R_X86_64_PC64;
1612d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
16137a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola      case X86::reloc_signed_4byte:
1614c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola      case X86::reloc_riprel_4byte_movq_load:
16153a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_Data_4: // FIXME?
16163a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case X86::reloc_riprel_4byte:
16173a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_4:
16183a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        switch (Modifier) {
16193a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        default:
16203a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          llvm_unreachable("Unimplemented");
16213a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_None:
16223a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_PC32;
16233a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16243a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_PLT:
16253a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_PLT32;
16263a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16273a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_GOTPCREL:
16283a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_GOTPCREL;
16293a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16303a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_GOTTPOFF:
16313a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_GOTTPOFF;
1632d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
16333a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_TLSGD:
16343a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_TLSGD;
16353a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16363a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_TLSLD:
16373a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_TLSLD;
16383a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16393a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        }
1640d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
16413a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_2:
16423a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
16433a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        Type = ELF::R_X86_64_PC16;
1644d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1645d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1646d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1647d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1648d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1649d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_8: Type = ELF::R_X86_64_64; break;
1650d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1651d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        assert(isInt<32>(Target.getConstant()));
1652d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1653d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1654d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1655d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1656d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_32S;
1657d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1658d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1659d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOT32;
1660d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1661d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTPCREL:
1662d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOTPCREL;
1663d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1664d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1665d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_TPOFF32;
1666d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1667d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1668d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_DTPOFF32;
1669d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1670d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1671d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1672d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1673d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_32;
1674d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1675d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_X86_64_16; break;
1676e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1677d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_X86_64_8; break;
1678d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1679d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1680d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  } else {
1681d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
1682d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch (Modifier) {
1683d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default:
1684d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        llvm_unreachable("Unimplemented");
1685d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_None:
1686d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_PC32;
1687d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1688d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_PLT:
1689d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_PLT32;
1690d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1691d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1692d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1693d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1694d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1695d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1696d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_global_offset_table:
1697d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_GOTPC;
1698d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1699d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1700d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1701d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // instead?
1702d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1703e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
1704d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1705d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1706d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1707d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1708d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_32;
1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOT32;
1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTOFF:
1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOTOFF;
1716d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1717d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSGD:
1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GD;
1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE_32;
1722d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_INDNTPOFF:
1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_IE;
1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_NTPOFF:
1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE;
1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTNTPOFF:
1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GOTIE;
1731d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSLDM:
1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDM;
1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1735d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDO_32;
1737d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1738d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1739d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1740d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_386_16; break;
1741e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_386_8; break;
1743d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1744d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1745d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1746d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1747d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  if (RelocNeedsGOT(Modifier))
1748d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    NeedsGOT = true;
1749d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
175056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  return Type;
17513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1752