17394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky//===- 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
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCELFObjectWriter.h"
153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/OwningPtr.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallPtrSet.h"
183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallString.h"
193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h"
2078c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h"
223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCAssembler.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
246eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCELF.h"
253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCELFSymbolFlags.h"
263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
27f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h"
28f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h"
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h"
313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h"
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
353565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
37e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef  DEBUG_TYPE
38e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info"
39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
403963d617b3709c510003ac816fb42f28539fc62bRafael Espindolanamespace {
413963d617b3709c510003ac816fb42f28539fc62bRafael Espindolaclass ELFObjectWriter : public MCObjectWriter {
423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  protected:
433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant);
463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout);
473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                           bool Used, bool Renamed);
493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isLocal(const MCSymbolData &Data, bool isSignature,
503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                        bool isUsedInReloc);
513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool IsELFMetaDataSection(const MCSectionData &SD);
523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t DataSectionSize(const MCSectionData &SD);
533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                       const MCSectionData &SD);
553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                          const MCSectionData &SD);
573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteDataSectionData(MCAssembler &Asm,
593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                              const MCAsmLayout &Layout,
603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                              const MCSectionELF &Section);
613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /*static bool isFixupKindX86RIPRel(unsigned Kind) {
633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return Kind == X86::reloc_riprel_4byte ||
643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        Kind == X86::reloc_riprel_4byte_movq_load;
653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }*/
663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// ELFSymbolData - Helper struct for containing some precomputed
683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// information on symbols.
693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    struct ELFSymbolData {
703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      MCSymbolData *SymbolData;
713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      uint64_t StringIndex;
723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      uint32_t SectionIndex;
733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      // Support lexicographic sorting.
753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      bool operator<(const ELFSymbolData &RHS) const {
763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        if (MCELF::GetType(*SymbolData) == ELF::STT_FILE)
773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola          return true;
783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE)
793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola          return false;
803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        return SymbolData->getSymbol().getName() <
813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola               RHS.SymbolData->getSymbol().getName();
823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      }
833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    };
843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// The target specific ELF writer instance.
863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    DenseMap<const MCSymbol *, const MCSymbol *> Renames;
913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    llvm::DenseMap<const MCSectionData*,
933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                   std::vector<ELFRelocationEntry> > Relocations;
943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @}
973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @name Symbol Table Data
983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @{
993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    SmallString<256> StringTable;
1013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    std::vector<ELFSymbolData> LocalSymbolData;
1023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    std::vector<ELFSymbolData> ExternalSymbolData;
1033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    std::vector<ELFSymbolData> UndefinedSymbolData;
1043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @}
1063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool NeedsGOT;
1083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool NeedsSymtabShndx;
1103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the symbol table index of the last local symbol.
1123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned LastLocalSymbolIndex;
1133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the .strtab section index.
1143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned StringTableIndex;
1153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the .symtab section index.
1163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned SymbolTableIndex;
1173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned ShstrtabIndex;
1193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
1223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCValue &Target,
1233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFragment &F,
1243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFixup &Fixup,
1253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  bool IsPCRel) const;
1263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // TargetObjectWriter wrappers.
1283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
1293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   const MCValue &Target,
1303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   const MCFragment &F,
1313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   const MCFixup &Fixup,
1323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   bool IsPCRel) const {
1333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
1343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
135aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella    const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
136aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella                                            const MCFixup &Fixup,
137aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella                                            bool IsPCRel) const {
138dc08bfbd565ba6540be698bba551b2039661299dJack Carter      return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup,
139dc08bfbd565ba6540be698bba551b2039661299dJack Carter                                                         IsPCRel);
140aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella    }
1413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
1433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool hasRelocationAddend() const {
1443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->hasRelocationAddend();
1453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
1473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          bool IsPCRel, bool IsRelocWithSymbol,
1483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          int64_t Addend) const {
1493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel,
1503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                              IsRelocWithSymbol, Addend);
1513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  public:
1543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                    raw_ostream &_OS, bool IsLittleEndian)
1563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      : MCObjectWriter(_OS, IsLittleEndian),
1573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        TargetObjectWriter(MOTW),
1587394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky        NeedsGOT(false), NeedsSymtabShndx(false) {
1593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual ~ELFObjectWriter();
1623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteWord(uint64_t W) {
1643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (is64Bit())
1653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        Write64(W);
1663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
1673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        Write32(W);
1683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringLE16(char *buf, uint16_t Value) {
1713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[0] = char(Value >> 0);
1723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[1] = char(Value >> 8);
1733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringLE32(char *buf, uint32_t Value) {
1763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE16(buf, uint16_t(Value >> 0));
1773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE16(buf + 2, uint16_t(Value >> 16));
1783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringLE64(char *buf, uint64_t Value) {
1813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE32(buf, uint32_t(Value >> 0));
1823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE32(buf + 4, uint32_t(Value >> 32));
1833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringBE16(char *buf ,uint16_t Value) {
1863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[0] = char(Value >> 8);
1873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[1] = char(Value >> 0);
1883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringBE32(char *buf, uint32_t Value) {
1913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE16(buf, uint16_t(Value >> 16));
1923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE16(buf + 2, uint16_t(Value >> 0));
1933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringBE64(char *buf, uint64_t Value) {
1963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE32(buf, uint32_t(Value >> 32));
1973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE32(buf + 4, uint32_t(Value >> 0));
1983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String8(MCDataFragment &F, uint8_t Value) {
2013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[1];
2023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[0] = Value;
203550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky      F.getContents().append(&buf[0], &buf[1]);
2043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String16(MCDataFragment &F, uint16_t Value) {
2073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[2];
2083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (isLittleEndian())
2093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringLE16(buf, Value);
2103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
2113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringBE16(buf, Value);
212550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky      F.getContents().append(&buf[0], &buf[2]);
2133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String32(MCDataFragment &F, uint32_t Value) {
2163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[4];
2173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (isLittleEndian())
2183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringLE32(buf, Value);
2193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
2203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringBE32(buf, Value);
221550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky      F.getContents().append(&buf[0], &buf[4]);
2223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String64(MCDataFragment &F, uint64_t Value) {
2253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[8];
2263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (isLittleEndian())
2273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringLE64(buf, Value);
2283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
2293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringBE64(buf, Value);
230550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky      F.getContents().append(&buf[0], &buf[8]);
2313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2339a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter    void WriteHeader(const MCAssembler &Asm,
2349a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter                     uint64_t SectionDataSize,
2353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                     unsigned NumberOfSections);
2363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSymbolEntry(MCDataFragment *SymtabF,
2383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          MCDataFragment *ShndxF,
2393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t name, uint8_t info,
2403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t value, uint64_t size,
2413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint8_t other, uint32_t shndx,
2423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          bool Reserved);
2433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSymbol(MCDataFragment *SymtabF,  MCDataFragment *ShndxF,
2453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                     ELFSymbolData &MSD,
2463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                     const MCAsmLayout &Layout);
2473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
2493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSymbolTable(MCDataFragment *SymtabF,
2503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          MCDataFragment *ShndxF,
2513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const MCAssembler &Asm,
2523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const MCAsmLayout &Layout,
2533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const SectionIndexMapTy &SectionIndexMap);
2543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual void RecordRelocation(const MCAssembler &Asm,
2563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCAsmLayout &Layout,
2573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFragment *Fragment,
2583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFixup &Fixup,
2593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  MCValue Target, uint64_t &FixedValue);
2603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
2623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                         const MCSymbol *S);
2633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a group section to the signature symbol
2653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
2663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a signature symbol to the group section
2673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
2683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a section to the section with the relocations
2693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy;
2703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a section to its offset
2713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
2723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// ComputeSymbolTable - Compute the symbol table data
2743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    ///
275828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param Asm - The assembler.
276828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param SectionIndexMap - Maps a section to its index.
277828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param RevGroupMap - Maps a signature symbol to the group section.
278828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param NumRegularSections - Number of non-relocation sections.
2793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void ComputeSymbolTable(MCAssembler &Asm,
2803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
2813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            RevGroupMapTy RevGroupMap,
2823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            unsigned NumRegularSections);
2833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void ComputeIndexMap(MCAssembler &Asm,
2853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                         SectionIndexMapTy &SectionIndexMap,
2863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                         const RelMapTy &RelMap);
2873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout,
2893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  RelMapTy &RelMap);
2903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
2923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const RelMapTy &RelMap);
2933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
2953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                SectionIndexMapTy &SectionIndexMap,
2963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                const RelMapTy &RelMap);
2973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Create the sections that show up in the symbol table. Currently
2993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // those are the .note.GNU-stack section and the group sections.
3003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
3013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               GroupMapTy &GroupMap,
3023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               RevGroupMapTy &RevGroupMap,
3033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               SectionIndexMapTy &SectionIndexMap,
3043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               const RelMapTy &RelMap);
3053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
3073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                          const MCAsmLayout &Layout);
3083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
3103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const MCAsmLayout &Layout,
3113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
3123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionOffsetMapTy &SectionOffsetMap);
3133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void ComputeSectionOrder(MCAssembler &Asm,
3153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                             std::vector<const MCSectionELF*> &Sections);
3163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
3183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t Address, uint64_t Offset,
3193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t Size, uint32_t Link, uint32_t Info,
3203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t Alignment, uint64_t EntrySize);
3213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteRelocationsFragment(const MCAssembler &Asm,
3233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  MCDataFragment *F,
3243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCSectionData *SD);
3253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual bool
3273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
3283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           const MCSymbolData &DataA,
3293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           const MCFragment &FB,
3303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           bool InSet,
3313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           bool IsPCRel) const;
3323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
3343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSection(MCAssembler &Asm,
3353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      const SectionIndexMapTy &SectionIndexMap,
3363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      uint32_t GroupSymbolIndex,
3373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      uint64_t Offset, uint64_t Size, uint64_t Alignment,
3383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      const MCSectionELF &Section);
3393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  };
3403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola}
3413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
3432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  const MCFixupKindInfo &FKI =
3442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
3452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
3462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
3472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
3482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
3492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
3502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  switch (Variant) {
3512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  default:
3522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return false;
3532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOT:
3542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_PLT:
3552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTPCREL:
356378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola  case MCSymbolRefExpr::VK_GOTOFF:
3572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TPOFF:
3582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSGD:
3592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTTPOFF:
3602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_INDNTPOFF:
3612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_NTPOFF:
3622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTNTPOFF:
3632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLDM:
3642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_DTPOFF:
3652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLD:
3662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return true;
3672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  }
3682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
3692ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
370d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
371d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
372d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
3749a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Cartervoid ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
3759a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter                                  uint64_t SectionDataSize,
376115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  unsigned NumberOfSections) {
3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0x7f); // e_ident[EI_MAG0]
3863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('E');  // e_ident[EI_MAG1]
3873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('L');  // e_ident[EI_MAG2]
3883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('F');  // e_ident[EI_MAG3]
3893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
390bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
393115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
3943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
3965baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
397dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  Write8(TargetObjectWriter->getOSABI());
3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0);                  // e_ident[EI_ABIVERSION]
3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
4013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(ELF::ET_REL);             // e_type
4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
404bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
4053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(ELF::EV_CURRENT);         // e_version
4073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
409bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
410eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4122d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  // e_flags = whatever the target wants
4139a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter  Write32(Asm.getELFHeaderEFlags());
4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
416bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phentsize = prog header entry size
4193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phnum = # prog header entries = 0
4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
422bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
4233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
4257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
426aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky    Write16(ELF::SHN_UNDEF);
4277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
4287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(NumberOfSections);
4293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
431b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky  if (ShstrtabIndex >= ELF::SHN_LORESERVE)
4327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ELF::SHN_XINDEX);
4337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
4347be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ShstrtabIndex);
4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
437115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
438115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
439115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t name,
440115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint8_t info, uint64_t value,
441115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t size, uint8_t other,
442115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t shndx,
443115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       bool Reserved) {
4447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (ShndxF) {
4457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
446af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, shndx);
4477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    else
448af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, 0);
4497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
4507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
451af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
452af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    uint16_t(ELF::SHN_XINDEX) : shndx;
4533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
454bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
455af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
456af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
457af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
458af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
459af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, value); // st_value
460af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, size);  // st_size
4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
462af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
463af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, value); // st_value
464af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, size);  // st_size
465af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
466af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
467af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
4722ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                      const MCAsmLayout &Layout) {
4732c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (Data.isCommon() && Data.isExternal())
4742c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return Data.getCommonAlignment();
4752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
4762c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
477d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
478d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  if (Symbol.isAbsolute() && Symbol.isVariable()) {
479d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    if (const MCExpr *Value = Symbol.getVariableValue()) {
480d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      int64_t IntValue;
481d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      if (Value->EvaluateAsAbsolute(IntValue, Layout))
482f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach        return (uint64_t)IntValue;
483d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    }
484d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  }
485d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
4862c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (!Symbol.isInSection())
4872c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return 0;
4882c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
4896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (Data.getFragment()) {
4916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Data.getFlags() & ELF_Other_ThumbFunc)
4926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Layout.getSymbolOffset(&Data)+1;
4936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    else
4946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Layout.getSymbolOffset(&Data);
4956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
4962c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
4972c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  return 0;
4982c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
4992c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
50085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
50185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                               const MCAsmLayout &Layout) {
50288182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
50388182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
50488182132470527e27231f09b25a885893e528c66Rafael Espindola
50588182132470527e27231f09b25a885893e528c66Rafael Espindola  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
50688182132470527e27231f09b25a885893e528c66Rafael Espindola         ie = Asm.symbol_end(); it != ie; ++it) {
50788182132470527e27231f09b25a885893e528c66Rafael Espindola    const MCSymbol &Alias = it->getSymbol();
50894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &Symbol = Alias.AliasedSymbol();
509f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    MCSymbolData &SD = Asm.getSymbolData(Symbol);
510f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
511f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
512f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    if (&Symbol == &Alias)
513f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
514f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
51507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
51688182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
51788182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
51888182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
51988182132470527e27231f09b25a885893e528c66Rafael Espindola
520f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
521f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
522f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    it->setExternal(SD.isExternal());
5232ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(*it, MCELF::GetBinding(SD));
524f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
52507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
52688182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
52788182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
52888182132470527e27231f09b25a885893e528c66Rafael Espindola
52983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
53083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
53183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
53283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
53383ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
53407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
53588182132470527e27231f09b25a885893e528c66Rafael Espindola  }
53688182132470527e27231f09b25a885893e528c66Rafael Espindola}
53788182132470527e27231f09b25a885893e528c66Rafael Espindola
538115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
539115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  MCDataFragment *ShndxF,
540115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  ELFSymbolData &MSD,
541115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
542de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &OrigData = *MSD.SymbolData;
543de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &Data =
54494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
545152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
5467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
5477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Data.getSymbol().isVariable();
5487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
54977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  // Binding and Type share the same byte as upper and lower nibbles
5502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Binding = MCELF::GetBinding(OrigData);
5512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Type = MCELF::GetType(Data);
552152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
55377afbdce53aa740777486b0cc4e9df151ae65468Jack Carter
55477afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  // Other and Visibility share the same byte with Visability using the lower
55577afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  // 2 bits
55677afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  uint8_t Visibility = MCELF::GetVisibility(OrigData);
55777afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  uint8_t Other = MCELF::getOther(OrigData) <<
55877afbdce53aa740777486b0cc4e9df151ae65468Jack Carter    (ELF_Other_Shift - ELF_STV_Shift);
55977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  Other |= Visibility;
560152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
5612c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  uint64_t Value = SymbolValue(Data, Layout);
5623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
5633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
564f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(!(Data.isCommon() && !Data.isExternal()));
565f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
566f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  const MCExpr *ESize = Data.getSize();
567f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  if (ESize) {
568f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    int64_t Res;
569f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    if (!ESize->EvaluateAsAbsolute(Res, Layout))
570f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola      report_fatal_error("Size expression must be absolute.");
571f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    Size = Res;
5723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
5733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
5757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
5767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                   Size, Other, MSD.SectionIndex, IsReserved);
5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
579115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
580115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
581115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAssembler &Asm,
582115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAsmLayout &Layout,
583a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                                    const SectionIndexMapTy &SectionIndexMap) {
5843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The string table must be emitted first because we need the index
5853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // into the string table for all the symbol names.
5863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(StringTable.size() && "Missing string table");
5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make sure the start of the symbol table is aligned.
5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry is the undefined symbol entry.
5917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
5923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write the symbol table entries.
5943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
5953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
5963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = LocalSymbolData[i];
5977be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
5983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
5993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
60071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Write out a symbol table entry for each regular section.
6014beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
6024beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola       ++i) {
603a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    const MCSectionELF &Section =
6044beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola      static_cast<const MCSectionELF&>(i->getSection());
6054beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola    if (Section.getType() == ELF::SHT_RELA ||
6064beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_REL ||
6074beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_STRTAB ||
608d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky        Section.getType() == ELF::SHT_SYMTAB ||
609d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky        Section.getType() == ELF::SHT_SYMTAB_SHNDX)
610a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman      continue;
6117be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
612a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section),
613a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                     false);
614a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    LastLocalSymbolIndex++;
615a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman  }
6163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
6183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = ExternalSymbolData[i];
6193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
6203223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    assert(((Data.getFlags() & ELF_STB_Global) ||
6213223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola            (Data.getFlags() & ELF_STB_Weak)) &&
6223223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola           "External symbol requires STB_GLOBAL or STB_WEAK flag");
6237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
6242ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = UndefinedSymbolData[i];
6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
6317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
6322ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
6343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6371f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
6381f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCValue &Target,
6392684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach                                               const MCFragment &F,
640e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               const MCFixup &Fixup,
641e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               bool IsPCRel) const {
6421f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
64394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
64494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol *Renamed = Renames.lookup(&Symbol);
64594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
64694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola
64794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (ASymbol.isUndefined()) {
64894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
64994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
650aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella    return undefinedExplicitRelSym(Target, Fixup, IsPCRel);
6511f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
6521f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
65394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (SD.isExternal()) {
65494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
65594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
65694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
65794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
6587eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
6597eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola  const MCSectionELF &Section =
66094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    static_cast<const MCSectionELF&>(ASymbol.getSection());
66125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  const SectionKind secKind = Section.getKind();
6627eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
66325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isBSS())
664e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
6657eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
66625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isThreadLocal()) {
66725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    if (Renamed)
66825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola      return Renamed;
66925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    return &Symbol;
67025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
67125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
6728cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
6733729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola  const MCSectionELF &Sec2 =
6743729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola    static_cast<const MCSectionELF&>(F.getParent()->getSection());
6753729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
6768cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  if (&Sec2 != &Section &&
677c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola      (Kind == MCSymbolRefExpr::VK_PLT ||
678c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
67925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
68094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
68194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
68294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
68394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
6843729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
6851c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola  if (Section.getFlags() & ELF::SHF_MERGE) {
68694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Target.getConstant() == 0)
687e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
68894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
68994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
69094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
6911f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
692c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
693e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
694e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
69573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
69673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
6973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
69856a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
69956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCAsmLayout &Layout,
70056a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFragment *Fragment,
70156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFixup &Fixup,
70256a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       MCValue Target,
70356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       uint64_t &FixedValue) {
70456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Addend = 0;
70556a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int Index = 0;
70656a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Value = Target.getConstant();
70756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  const MCSymbol *RelocSymbol = NULL;
70856a399023aba6cf1348533df04732950c43eaca7Jason W Kim
709127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
71056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  if (!Target.isAbsolute()) {
71156a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
71256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
713e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);
71456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
71556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
71656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
71756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
71856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      IsPCRel = true;
71956a399023aba6cf1348533df04732950c43eaca7Jason W Kim
72056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
72156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t a = Layout.getSymbolOffset(&SDB);
72256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
723a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes      // Offset of the relocation in the section
72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
72556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += b - a;
72656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
72756a399023aba6cf1348533df04732950c43eaca7Jason W Kim
72856a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (!RelocSymbol) {
72956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
73056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCFragment *F = SD.getFragment();
73156a399023aba6cf1348533df04732950c43eaca7Jason W Kim
732aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella      if (F) {
733aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella        Index = F->getParent()->getOrdinal() + 1;
734aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella        // Offset of the symbol in the section
735aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella        Value += Layout.getSymbolOffset(&SD);
736aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella      } else {
737aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella        Index = 0;
738aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella      }
73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim    } else {
74056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      else
74356a399023aba6cf1348533df04732950c43eaca7Jason W Kim        UsedInReloc.insert(RelocSymbol);
74456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = -1;
74556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
74656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Addend = Value;
747b21d9aebba7e45ddcbce61dd501000049cefb335Michael Liao    if (hasRelocationAddend())
74856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value = 0;
74956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  }
75056a399023aba6cf1348533df04732950c43eaca7Jason W Kim
75156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  FixedValue = Value;
75256a399023aba6cf1348533df04732950c43eaca7Jason W Kim  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
75356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                               (RelocSymbol != 0), Addend);
754c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
755c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
756c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  if (RelocNeedsGOT(Modifier))
757c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola    NeedsGOT = true;
7582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
75956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
76056a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Fixup.getOffset();
7612a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky
762bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (!hasRelocationAddend())
763bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    Addend = 0;
764bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
765bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola  if (is64Bit())
766bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola    assert(isInt<64>(Addend));
767bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola  else
768bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola    assert(isInt<32>(Addend));
769bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
77000ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup);
77156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
77256a399023aba6cf1348533df04732950c43eaca7Jason W Kim}
77356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
77456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
7750b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t
776115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
777115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             const MCSymbol *S) {
7787b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer  MCSymbolData &SD = Asm.getSymbolData(*S);
779ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  return SD.getIndex();
7803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7822ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
7832ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 const MCSymbolData &Data,
7842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 bool Used, bool Renamed) {
785484291c27319668ad99cb87def000254357736fbRafael Espindola  if (Data.getFlags() & ELF_Other_Weakref)
786484291c27319668ad99cb87def000254357736fbRafael Espindola    return false;
787484291c27319668ad99cb87def000254357736fbRafael Espindola
788bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
789bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
790bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
79188182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
79288182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
79388182132470527e27231f09b25a885893e528c66Rafael Espindola
794737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
795a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
796d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
797d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola    return true;
798d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola
79994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &A = Symbol.AliasedSymbol();
80021451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (Symbol.isVariable() && !A.isVariable() && A.isUndefined())
80121451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola    return false;
80221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola
8032ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
80421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
805a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
806a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
807737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
808737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
809737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
810bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
811737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
812737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
813737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
814737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
815737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
8162ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
8172ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                              bool isUsedInReloc) {
818737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (Data.isExternal())
819737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
820737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
821737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
82294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
8231f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8241f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
8251f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (isSignature && !isUsedInReloc)
8261f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      return true;
8271f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
828737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
8291f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  }
830737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
831737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
832737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
833737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
834115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
8357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      SectionIndexMapTy &SectionIndexMap,
8367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const RelMapTy &RelMap) {
837bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  unsigned Index = 1;
838bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
839bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
840bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    const MCSectionELF &Section =
841bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
8432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionIndexMap[&Section] = Index++;
8452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
8462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
8472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
8482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         ie = Asm.end(); it != ie; ++it) {
8492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
8502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP ||
8527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_REL ||
8537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
8542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
855bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    SectionIndexMap[&Section] = Index++;
8567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelSection = RelMap.lookup(&Section);
8577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (RelSection)
8587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      SectionIndexMap[RelSection] = Index++;
859bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  }
860bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola}
861bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
862115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
8631f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
8647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         RevGroupMapTy RevGroupMap,
8657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         unsigned NumRegularSections) {
8665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  // FIXME: Is this the correct place to do this?
867378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola  // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
8685c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  if (NeedsGOT) {
86996f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko    StringRef Name = "_GLOBAL_OFFSET_TABLE_";
8705c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
8715c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
8725c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    Data.setExternal(true);
8732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(Data, ELF::STB_GLOBAL);
8745c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
8755c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
8763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Index 0 is always the empty string.
8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringMap<uint64_t> StringIndexMap;
8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTable += '\x00';
8793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
880d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  // FIXME: We could optimize suffixes in strtab in the same way we
881d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  // optimize them in shstrtab.
882d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
883a0949b50dcea35c08b50542091f97275f401529dRafael Espindola  // Add the data for the symbols.
8843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
8853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.symbol_end(); it != ie; ++it) {
8863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSymbol &Symbol = it->getSymbol();
8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
888484291c27319668ad99cb87def000254357736fbRafael Espindola    bool Used = UsedInReloc.count(&Symbol);
889484291c27319668ad99cb87def000254357736fbRafael Espindola    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
8901f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool isSignature = RevGroupMap.count(&Symbol);
8911f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!isInSymtab(Asm, *it,
8931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    Used || WeakrefUsed || isSignature,
89488182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
8953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
8963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
8983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MSD.SymbolData = it;
89994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
9003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Undefined symbols are global, but this is the first place we
9021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // are able to set it.
9031f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool Local = isLocal(*it, isSignature, Used);
9042ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
9051f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
9062ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_GLOBAL);
9072ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(SD, ELF::STB_GLOBAL);
9081f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    }
9091f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
910484291c27319668ad99cb87def000254357736fbRafael Espindola    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
9112ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_WEAK);
912484291c27319668ad99cb87def000254357736fbRafael Espindola
913f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    if (it->isCommon()) {
914a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
915f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
916bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
917a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      MSD.SectionIndex = ELF::SHN_ABS;
91888182132470527e27231f09b25a885893e528c66Rafael Espindola    } else if (RefSymbol.isUndefined()) {
9191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      if (isSignature && !Used)
9201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
9211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      else
9221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
9233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
924bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
925bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola        static_cast<const MCSectionELF&>(RefSymbol.getSection());
926bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
9277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
9287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola        NeedsSymtabShndx = true;
9293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
9305df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
9315df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
93288182132470527e27231f09b25a885893e528c66Rafael Espindola    // The @@@ in symbol version is replaced with @ in undefined symbols and
93388182132470527e27231f09b25a885893e528c66Rafael Espindola    // @@ in defined ones.
93488182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
9351261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    SmallString<32> Buf;
9361261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer
93788182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = Name.find("@@@");
93888182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos != StringRef::npos) {
9391261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(0, Pos);
9401261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
9411261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(Pos + Skip);
9421261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Name = Buf;
94388182132470527e27231f09b25a885893e528c66Rafael Espindola    }
94488182132470527e27231f09b25a885893e528c66Rafael Espindola
9451261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    uint64_t &Entry = StringIndexMap[Name];
946a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (!Entry) {
947a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      Entry = StringTable.size();
9481261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      StringTable += Name;
949a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      StringTable += '\x00';
9503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
951a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    MSD.StringIndex = Entry;
952a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (MSD.SectionIndex == ELF::SHN_UNDEF)
953a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      UndefinedSymbolData.push_back(MSD);
954a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else if (Local)
955a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
956a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
957a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
9583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
9593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
9613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
9623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
9633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
9643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
967ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  unsigned Index = 1;
9683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
9693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    LocalSymbolData[i].SymbolData->setIndex(Index++);
970ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
971ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  Index += NumRegularSections;
972ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
9743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ExternalSymbolData[i].SymbolData->setIndex(Index++);
9753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
9763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
9777aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky
9787394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky  if (Index >= ELF::SHN_LORESERVE)
9797aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky    NeedsSymtabShndx = true;
9803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
9813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
9837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               MCAsmLayout &Layout,
9847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               RelMapTy &RelMap) {
9857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
9867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
9877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
9887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Relocations[&SD].empty())
9897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
9907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
9913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCContext &Ctx = Asm.getContext();
9923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
9933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      static_cast<const MCSectionELF&>(SD.getSection());
9943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const StringRef SectionName = Section.getSectionName();
996bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
9973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    RelaSectionName += SectionName;
998299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer
999299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    unsigned EntrySize;
1000bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (hasRelocationAddend())
1001bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
1002299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    else
1003bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
10043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1005f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover    unsigned Flags = 0;
1006f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover    StringRef Group = "";
1007f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover    if (Section.getFlags() & ELF::SHF_GROUP) {
1008f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover        Flags = ELF::SHF_GROUP;
1009f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover        Group = Section.getGroup()->getName();
1010f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover    }
1011f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover
10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection =
10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
1014f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover                        ELF::SHT_RELA : ELF::SHT_REL, Flags,
10157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        SectionKind::getReadOnly(),
1016f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover                        EntrySize, Group);
10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    RelMap[&Section] = RelaSection;
10187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Asm.getOrCreateSectionData(*RelaSection);
10197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
10217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
10237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                       const RelMapTy &RelMap) {
10247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
10257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
10267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
10277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
10287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF&>(SD.getSection());
10293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection = RelMap.lookup(&Section);
10317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (!RelaSection)
10327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
1034bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    RelaSD.setAlignment(is64Bit() ? 8 : 4);
10353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCDataFragment *F = new MCDataFragment(&RelaSD);
10377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteRelocationsFragment(Asm, F, &*it);
10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1041115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
1042115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
1043115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
1044115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
1045115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
1046115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
10473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Name);        // sh_name: index into string table
10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Type);        // sh_type
10493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
10503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
10513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
10523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
10533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Link);        // sh_link
10543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Info);        // sh_info
10553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
10563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
10573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1059115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
1060115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               MCDataFragment *F,
1061115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               const MCSectionData *SD) {
10623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
106300ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka
106400ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  // Sort the relocation entries. Most targets just sort by r_offset, but some
106500ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  // (e.g., MIPS) have additional constraints.
106600ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  TargetObjectWriter->sortRelocs(Asm, Relocs);
10673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
10693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFRelocationEntry entry = Relocs[e - i - 1];
10703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
107112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    if (!entry.Index)
107212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      ;
107312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    else if (entry.Index < 0)
10748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
10758f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    else
107612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      entry.Index += LocalSymbolData.size();
1077bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit()) {
1078af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, entry.r_offset);
107993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      if (TargetObjectWriter->isN64()) {
108093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String32(*F, entry.Index);
10815e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
108293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRSsym(entry.Type));
108393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRType3(entry.Type));
108493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRType2(entry.Type));
108593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRType(entry.Type));
108693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      }
108793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      else {
108893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        struct ELF::Elf64_Rela ERE64;
108993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        ERE64.setSymbolAndType(entry.Index, entry.Type);
109093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String64(*F, ERE64.r_info);
109193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      }
1092bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
1093af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String64(*F, entry.r_addend);
10945e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
1095af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, entry.r_offset);
10965e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10978f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
10988f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE32.setSymbolAndType(entry.Index, entry.Type);
1099af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, ERE32.r_info);
11005e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1101bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
1102af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String32(*F, entry.r_addend);
11035e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
11043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
11053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
11063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1107d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) {
1108d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a);
1109d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b);
1110d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const StringRef &NameA = secA->getSectionName();
1111d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const StringRef &NameB = secB->getSectionName();
1112d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned sizeA = NameA.size();
1113d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned sizeB = NameB.size();
1114d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned len = std::min(sizeA, sizeB);
1115d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (unsigned int i = 0; i < len; ++i) {
1116d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    char ca = NameA[sizeA - i - 1];
1117d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    char cb = NameB[sizeB - i - 1];
1118d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    if (ca != cb)
1119d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      return cb - ca;
1120d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  }
1121d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
1122d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  return sizeB - sizeA;
1123d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola}
1124d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
1125115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
1126115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             MCAsmLayout &Layout,
11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             SectionIndexMapTy &SectionIndexMap,
11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             const RelMapTy &RelMap) {
11293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCContext &Ctx = Asm.getContext();
11303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F;
11313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1132bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
11333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
113438738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
11354283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *ShstrtabSection =
11367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
11373f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                      SectionKind::getReadOnly());
113871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
113971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabSD.setAlignment(1);
114071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
11414283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *SymtabSection =
11427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
11437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                      SectionKind::getReadOnly(),
11442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      EntrySize, "");
11453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
1146bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
11477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
11487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCSectionData *SymtabShndxSD = NULL;
11497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
11507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
11514283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *SymtabShndxSection =
11527be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
11532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                        SectionKind::getReadOnly(), 4, "");
11547be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
11557be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD->setAlignment(4);
11567be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
11573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionELF *StrtabSection;
11593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
11603f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                    SectionKind::getReadOnly());
11613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
11623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSD.setAlignment(1);
11633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection);
11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SymbolTableIndex = SectionIndexMap.lookup(SymtabSection);
11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  StringTableIndex = SectionIndexMap.lookup(StrtabSection);
116971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
117071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Symbol table
117171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  F = new MCDataFragment(&SymtabSD);
11727be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCDataFragment *ShndxF = NULL;
11737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
11747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShndxF = new MCDataFragment(SymtabShndxSD);
11757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
11764beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
117771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
11783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&StrtabSD);
11793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents().append(StringTable.begin(), StringTable.end());
11803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&ShstrtabSD);
11823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1183d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  std::vector<const MCSectionELF*> Sections;
1184d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
1185d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
1186d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    const MCSectionELF &Section =
1187d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
1188d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    Sections.push_back(&Section);
1189d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  }
1190d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
1191d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
11923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Section header string table.
11933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
11943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry of a string table holds a null character so skip
11953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // section 0.
11963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Index = 1;
1197550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky  F->getContents().push_back('\x00');
11983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1199d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
1200d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    const MCSectionELF &Section = *Sections[I];
12013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    StringRef Name = Section.getSectionName();
1203d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    if (I != 0) {
1204d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      StringRef PreviousName = Sections[I - 1]->getSectionName();
1205d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      if (PreviousName.endswith(Name)) {
1206d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola        SectionStringTableIndex[&Section] = Index - Name.size() - 1;
1207d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola        continue;
1208d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      }
12092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
12103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the index into the string table so we can write it
12113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // into the sh_name field of the section header table.
12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionStringTableIndex[&Section] = Index;
12133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Index += Name.size() + 1;
1215550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky    F->getContents().append(Name.begin(), Name.end());
1216550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky    F->getContents().push_back('\x00');
12173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
12187070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola}
12197070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
122096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
122196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            MCAsmLayout &Layout,
122296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            GroupMapTy &GroupMap,
12237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            RevGroupMapTy &RevGroupMap,
12247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            SectionIndexMapTy &SectionIndexMap,
12257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            const RelMapTy &RelMap) {
122696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  // Create the .note.GNU-stack section if needed.
122796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  MCContext &Ctx = Asm.getContext();
122896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  if (Asm.getNoExecStack()) {
122996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    const MCSectionELF *GnuStackSection =
123096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
123196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                        SectionKind::getReadOnly());
123296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    Asm.getOrCreateSectionData(*GnuStackSection);
123396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  }
123496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola
12352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Build the groups
12362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
12372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it) {
12382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
12392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
12401c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
12412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
12422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSymbol *SignatureSymbol = Section.getGroup();
12442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Asm.getOrCreateSymbolData(*SignatureSymbol);
12451f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
12462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!Group) {
124796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Group = Ctx.CreateELFGroupSection();
12482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Data.setAlignment(4);
12502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCDataFragment *F = new MCDataFragment(&Data);
12512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      String32(*F, ELF::GRP_COMDAT);
12522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
12532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupMap[Group] = SignatureSymbol;
12542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
12577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
12582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Add sections to the groups
12592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
12607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola       it != ie; ++it) {
12612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
12622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
12631c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
12642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
12651f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
12662ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12672ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    // FIXME: we could use the previous fragment
12682ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCDataFragment *F = new MCDataFragment(&Data);
12697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    unsigned Index = SectionIndexMap.lookup(&Section);
12707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    String32(*F, Index);
12712ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12722ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
12732ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1274115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
1275115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const SectionIndexMapTy &SectionIndexMap,
1276115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint32_t GroupSymbolIndex,
1277115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Offset, uint64_t Size,
1278115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Alignment,
1279115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const MCSectionELF &Section) {
1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
1281c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionStringTableIndex[&Section];
1286c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = 0;
1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
1290c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
1291c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *SymtabSection;
1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *InfoSection;
1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                   0,
12953f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                   SectionKind::getReadOnly());
1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionIndexMap.lookup(SymtabSection);
1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Remove ".rel" and ".rela" prefixes.
1300c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
1302c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1303c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    InfoSection = Asm.getContext().getELFSection(SectionName,
1304c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                 ELF::SHT_PROGBITS, 0,
13053f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                 SectionKind::getReadOnly());
1306c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
1307c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1308c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1309c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1310c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
1311c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
1312c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
1313c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
1314c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1315c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1316c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
1317c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
1318c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1319c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1320c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_PROGBITS:
1321c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_STRTAB:
1322c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NOBITS:
132398976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola  case ELF::SHT_NOTE:
1324c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NULL:
1325c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_ARM_ATTRIBUTES:
132686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_INIT_ARRAY:
132786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_FINI_ARRAY:
132886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_PREINIT_ARRAY:
13290cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola  case ELF::SHT_X86_64_UNWIND:
1330c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter  case ELF::SHT_MIPS_REGINFO:
1331c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter  case ELF::SHT_MIPS_OPTIONS:
1332c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Nothing to do.
1333c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1334c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
13354a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky  case ELF::SHT_GROUP:
13362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
13372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
13382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
13392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1340c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  default:
1341c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(0 && "FIXME: sh_type value not supported!");
1342c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1343c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1344c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1345b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien  if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
1346b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien      Section.getType() == ELF::SHT_ARM_EXIDX) {
1347b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien    StringRef SecName(Section.getSectionName());
1348b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien    if (SecName == ".ARM.exidx") {
1349b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien      sh_link = SectionIndexMap.lookup(
1350b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien        Asm.getContext().getELFSection(".text",
1351b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien                                       ELF::SHT_PROGBITS,
1352b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien                                       ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
1353b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien                                       SectionKind::getText()));
1354b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien    } else if (SecName.startswith(".ARM.exidx")) {
1355b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien      sh_link = SectionIndexMap.lookup(
1356b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien        Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1),
1357b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien                                       ELF::SHT_PROGBITS,
1358b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien                                       ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
1359b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien                                       SectionKind::getText()));
1360b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien    }
1361b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien  }
1362b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien
1363c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
1364c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
1365c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Alignment, Section.getEntrySize());
1366c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola}
1367c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
13682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) {
1369f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola  return SD.getOrdinal() == ~UINT32_C(0) &&
13706db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    !SD.getSection().isVirtualSection();
13716db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13726db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) {
13746db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  uint64_t Ret = 0;
13756db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
13766db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola       ++i) {
13776db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    const MCFragment &F = *i;
13786db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    assert(F.getKind() == MCFragment::FT_Data);
13796db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    Ret += cast<MCDataFragment>(F).getContents().size();
13806db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
13816db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Ret;
13826db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13836db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout,
13852ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                             const MCSectionData &SD) {
13866db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
13876db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
13886db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Layout.getSectionFileSize(&SD);
13896db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13912ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
13922ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                                const MCSectionData &SD) {
13936db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
13946db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
139585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  return Layout.getSectionAddressSize(&SD);
13966db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
13997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCAsmLayout &Layout,
14007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCSectionELF &Section) {
14017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
14027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
1403263109d822314305822796a2cc05e98304793051Benjamin Kramer  uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
14047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteZeros(Padding);
14057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  if (IsELFMetaDataSection(SD)) {
14077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
14087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ++i) {
14097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      const MCFragment &F = *i;
14107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      assert(F.getKind() == MCFragment::FT_Data);
1411550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky      WriteBytes(cast<MCDataFragment>(F).getContents());
14127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    }
14137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  } else {
1414f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach    Asm.writeSectionData(&SD, Layout);
14157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
14177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
14197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const GroupMapTy &GroupMap,
14207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const MCAsmLayout &Layout,
14217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
14227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                   const SectionOffsetMapTy &SectionOffsetMap) {
14237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumSections = Asm.size() + 1;
14247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  std::vector<const MCSectionELF*> Sections;
14267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  Sections.resize(NumSections - 1);
14277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (SectionIndexMapTy::const_iterator i=
14297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
14307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
14317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Sections[p.second - 1] = p.first;
14327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Null section first.
14357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FirstSectionSize =
14367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
14377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint32_t FirstSectionLink =
14387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
14397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
14407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumSections - 1; ++i) {
14427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section = *Sections[i];
14437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
14447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint32_t GroupSymbolIndex;
14457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
14467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = 0;
14477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    else
14487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm,
14497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                                     GroupMap.lookup(&Section));
14507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint64_t Size = GetSectionAddressSize(Layout, SD);
14527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
14547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SectionOffsetMap.lookup(&Section), Size,
14557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SD.getAlignment(), Section);
14567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
14587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm,
14607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                  std::vector<const MCSectionELF*> &Sections) {
14617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
14627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
14637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
14647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
14657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP)
14667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
14677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
14707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
14717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
14727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
14737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP &&
14747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_REL &&
14757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_RELA)
14767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
14777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
14807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
14817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
14827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
14837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_REL ||
14847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
14857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
14866db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
14876db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
14886db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
1489115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
1490115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
14912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  GroupMapTy GroupMap;
14921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
1493bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1494bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
14957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumUserSections = Asm.size();
14967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
14987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
14997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumUserAndRelocSections = Asm.size();
15017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
15027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        RevGroupMap, SectionIndexMap, RelMap);
15037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned AllSections = Asm.size();
15047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
15057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumRegularSections = NumUserSections + NumIndexedSections;
1507bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
15088f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola  // Compute symbol table information.
15097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
15107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
15138f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
15143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
15154beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         const_cast<MCAsmLayout&>(Layout),
15167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         SectionIndexMap,
15177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         RelMap);
15181d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
1519bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
1520bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
1521bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                    sizeof(ELF::Elf32_Ehdr);
1522a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t FileOff = HeaderSize;
15233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  std::vector<const MCSectionELF*> Sections;
15257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSectionOrder(Asm, Sections);
15267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumSections = Sections.size();
15277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SectionOffsetMapTy SectionOffsetMap;
15287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i) {
15292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
15302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
15313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1532a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1533a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Remember the offset into the file for this section.
15357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    SectionOffsetMap[&Section] = FileOff;
15367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Get the size of the section in the output file (including padding).
15386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
15393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
15403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1541a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
1542a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned SectionHeaderOffset = FileOff - HeaderSize;
15443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t SectionHeaderEntrySize = is64Bit() ?
15467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
15477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += (NumSections + 1) * SectionHeaderEntrySize;
15483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) {
15502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
15512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
1552a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1554a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
15562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionOffsetMap[&Section] = FileOff;
155744cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
15587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Get the size of the section in the output file (including padding).
15596db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
15603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
15613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Write out the ELF header ...
15639a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter  WriteHeader(Asm, SectionHeaderOffset, NumSections + 1);
15647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the regular sections ...
15667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // + because of .shstrtab
15677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i)
15687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
15697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
1570263109d822314305822796a2cc05e98304793051Benjamin Kramer  uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
1571a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteZeros(Padding);
1572a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the section header table ...
15747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
15757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                     SectionOffsetMap);
15763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1577aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky  // ... and then the remaining sections ...
15787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
15797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
15803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
15813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
158278c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool
158378c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
158478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCSymbolData &DataA,
158578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCFragment &FB,
158678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool InSet,
158778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool IsPCRel) const {
158878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  if (DataA.getFlags() & ELF_STB_Weak)
158978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman    return false;
159078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
159178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                 Asm, DataA, FB,InSet, IsPCRel);
159278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman}
159378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman
15946024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
15956024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola                                            raw_ostream &OS,
1596bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                            bool IsLittleEndian) {
15977bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola  return new ELFObjectWriter(MOTW, OS, IsLittleEndian);
1598edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola}
1599