13565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//                     The LLVM Compiler Infrastructure
43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source
63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details.
73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file implements ELF object file writer information.
113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "MCELF.h"
153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/OwningPtr.h"
163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallPtrSet.h"
173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallString.h"
183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/STLExtras.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"
243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCELFObjectWriter.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/ErrorHandling.h"
333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
38e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef  DEBUG_TYPE
39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info"
40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
413963d617b3709c510003ac816fb42f28539fc62bRafael Espindolanamespace {
423963d617b3709c510003ac816fb42f28539fc62bRafael Espindolaclass ELFObjectWriter : public MCObjectWriter {
433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  protected:
443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant);
473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout);
483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                           bool Used, bool Renamed);
503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isLocal(const MCSymbolData &Data, bool isSignature,
513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                        bool isUsedInReloc);
523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool IsELFMetaDataSection(const MCSectionData &SD);
533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t DataSectionSize(const MCSectionData &SD);
543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                       const MCSectionData &SD);
563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                          const MCSectionData &SD);
583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteDataSectionData(MCAssembler &Asm,
603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                              const MCAsmLayout &Layout,
613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                              const MCSectionELF &Section);
623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /*static bool isFixupKindX86RIPRel(unsigned Kind) {
643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return Kind == X86::reloc_riprel_4byte ||
653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        Kind == X86::reloc_riprel_4byte_movq_load;
663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }*/
673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// ELFSymbolData - Helper struct for containing some precomputed
693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// information on symbols.
703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    struct ELFSymbolData {
713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      MCSymbolData *SymbolData;
723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      uint64_t StringIndex;
733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      uint32_t SectionIndex;
743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      // Support lexicographic sorting.
763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      bool operator<(const ELFSymbolData &RHS) const {
773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        if (MCELF::GetType(*SymbolData) == ELF::STT_FILE)
783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola          return true;
793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE)
803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola          return false;
813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        return SymbolData->getSymbol().getName() <
823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola               RHS.SymbolData->getSymbol().getName();
833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      }
843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    };
853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// The target specific ELF writer instance.
873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    DenseMap<const MCSymbol *, const MCSymbol *> Renames;
923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    llvm::DenseMap<const MCSectionData*,
943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                   std::vector<ELFRelocationEntry> > Relocations;
953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @}
983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @name Symbol Table Data
993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @{
1003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    SmallString<256> StringTable;
1023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    std::vector<ELFSymbolData> LocalSymbolData;
1033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    std::vector<ELFSymbolData> ExternalSymbolData;
1043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    std::vector<ELFSymbolData> UndefinedSymbolData;
1053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @}
1073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool NeedsGOT;
1093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool NeedsSymtabShndx;
1113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the symbol table index of the last local symbol.
1133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned LastLocalSymbolIndex;
1143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the .strtab section index.
1153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned StringTableIndex;
1163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the .symtab section index.
1173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned SymbolTableIndex;
1183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned ShstrtabIndex;
1203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
1233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCValue &Target,
1243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFragment &F,
1253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFixup &Fixup,
1263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  bool IsPCRel) const;
1273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // TargetObjectWriter wrappers.
1293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
1303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   const MCValue &Target,
1313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   const MCFragment &F,
1323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   const MCFixup &Fixup,
1333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                   bool IsPCRel) const {
1343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
1353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
1383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool hasRelocationAddend() const {
1393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->hasRelocationAddend();
1403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned getEFlags() const {
1423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->getEFlags();
1433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
1453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          bool IsPCRel, bool IsRelocWithSymbol,
1463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          int64_t Addend) const {
1473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel,
1483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                              IsRelocWithSymbol, Addend);
1493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  public:
1533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                    raw_ostream &_OS, bool IsLittleEndian)
1553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      : MCObjectWriter(_OS, IsLittleEndian),
1563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        TargetObjectWriter(MOTW),
1573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        NeedsGOT(false), NeedsSymtabShndx(false){
1583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual ~ELFObjectWriter();
1613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteWord(uint64_t W) {
1633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (is64Bit())
1643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        Write64(W);
1653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
1663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        Write32(W);
1673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringLE16(char *buf, uint16_t Value) {
1703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[0] = char(Value >> 0);
1713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[1] = char(Value >> 8);
1723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringLE32(char *buf, uint32_t Value) {
1753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE16(buf, uint16_t(Value >> 0));
1763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE16(buf + 2, uint16_t(Value >> 16));
1773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringLE64(char *buf, uint64_t Value) {
1803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE32(buf, uint32_t(Value >> 0));
1813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringLE32(buf + 4, uint32_t(Value >> 32));
1823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringBE16(char *buf ,uint16_t Value) {
1853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[0] = char(Value >> 8);
1863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[1] = char(Value >> 0);
1873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringBE32(char *buf, uint32_t Value) {
1903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE16(buf, uint16_t(Value >> 16));
1913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE16(buf + 2, uint16_t(Value >> 0));
1923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void StringBE64(char *buf, uint64_t Value) {
1953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE32(buf, uint32_t(Value >> 32));
1963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      StringBE32(buf + 4, uint32_t(Value >> 0));
1973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String8(MCDataFragment &F, uint8_t Value) {
2003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[1];
2013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      buf[0] = Value;
2023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      F.getContents() += StringRef(buf, 1);
2033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String16(MCDataFragment &F, uint16_t Value) {
2063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[2];
2073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (isLittleEndian())
2083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringLE16(buf, Value);
2093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
2103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringBE16(buf, Value);
2113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      F.getContents() += StringRef(buf, 2);
2123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String32(MCDataFragment &F, uint32_t Value) {
2153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[4];
2163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (isLittleEndian())
2173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringLE32(buf, Value);
2183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
2193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringBE32(buf, Value);
2203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      F.getContents() += StringRef(buf, 4);
2213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void String64(MCDataFragment &F, uint64_t Value) {
2243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      char buf[8];
2253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (isLittleEndian())
2263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringLE64(buf, Value);
2273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
2283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola        StringBE64(buf, Value);
2293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      F.getContents() += StringRef(buf, 8);
2303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
2313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteHeader(uint64_t SectionDataSize,
2333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                     unsigned NumberOfSections);
2343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSymbolEntry(MCDataFragment *SymtabF,
2363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          MCDataFragment *ShndxF,
2373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t name, uint8_t info,
2383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t value, uint64_t size,
2393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint8_t other, uint32_t shndx,
2403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          bool Reserved);
2413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSymbol(MCDataFragment *SymtabF,  MCDataFragment *ShndxF,
2433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                     ELFSymbolData &MSD,
2443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                     const MCAsmLayout &Layout);
2453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
2473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSymbolTable(MCDataFragment *SymtabF,
2483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          MCDataFragment *ShndxF,
2493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const MCAssembler &Asm,
2503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const MCAsmLayout &Layout,
2513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const SectionIndexMapTy &SectionIndexMap);
2523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual void RecordRelocation(const MCAssembler &Asm,
2543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCAsmLayout &Layout,
2553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFragment *Fragment,
2563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCFixup &Fixup,
2573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  MCValue Target, uint64_t &FixedValue);
2583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
2603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                         const MCSymbol *S);
2613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a group section to the signature symbol
2633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
2643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a signature symbol to the group section
2653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
2663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a section to the section with the relocations
2673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy;
2683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Map from a section to its offset
2693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
2703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// ComputeSymbolTable - Compute the symbol table data
2723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    ///
273828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param Asm - The assembler.
274828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param SectionIndexMap - Maps a section to its index.
275828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param RevGroupMap - Maps a signature symbol to the group section.
276828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param NumRegularSections - Number of non-relocation sections.
2773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void ComputeSymbolTable(MCAssembler &Asm,
2783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
2793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            RevGroupMapTy RevGroupMap,
2803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            unsigned NumRegularSections);
2813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void ComputeIndexMap(MCAssembler &Asm,
2833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                         SectionIndexMapTy &SectionIndexMap,
2843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                         const RelMapTy &RelMap);
2853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout,
2873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  RelMapTy &RelMap);
2883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
2903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          const RelMapTy &RelMap);
2913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
2933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                SectionIndexMapTy &SectionIndexMap,
2943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                const RelMapTy &RelMap);
2953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // Create the sections that show up in the symbol table. Currently
2973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // those are the .note.GNU-stack section and the group sections.
2983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
2993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               GroupMapTy &GroupMap,
3003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               RevGroupMapTy &RevGroupMap,
3013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               SectionIndexMapTy &SectionIndexMap,
3023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                               const RelMapTy &RelMap);
3033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
3053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                          const MCAsmLayout &Layout);
3063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
3083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const MCAsmLayout &Layout,
3093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
3103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionOffsetMapTy &SectionOffsetMap);
3113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void ComputeSectionOrder(MCAssembler &Asm,
3133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                             std::vector<const MCSectionELF*> &Sections);
3143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
3163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t Address, uint64_t Offset,
3173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t Size, uint32_t Link, uint32_t Info,
3183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                          uint64_t Alignment, uint64_t EntrySize);
3193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteRelocationsFragment(const MCAssembler &Asm,
3213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  MCDataFragment *F,
3223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                  const MCSectionData *SD);
3233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual bool
3253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
3263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           const MCSymbolData &DataA,
3273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           const MCFragment &FB,
3283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           bool InSet,
3293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                                           bool IsPCRel) const;
3303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
3323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteSection(MCAssembler &Asm,
3333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      const SectionIndexMapTy &SectionIndexMap,
3343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      uint32_t GroupSymbolIndex,
3353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      uint64_t Offset, uint64_t Size, uint64_t Alignment,
3363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      const MCSectionELF &Section);
3373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  };
3383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola}
3393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
3402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
3412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  const MCFixupKindInfo &FKI =
3422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
3432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
3442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
3452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
3462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
3472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
3482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  switch (Variant) {
3492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  default:
3502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return false;
3512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOT:
3522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_PLT:
3532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTPCREL:
354378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola  case MCSymbolRefExpr::VK_GOTOFF:
3552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TPOFF:
3562ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSGD:
3572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTTPOFF:
3582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_INDNTPOFF:
3592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_NTPOFF:
3602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTNTPOFF:
3612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLDM:
3622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_DTPOFF:
3632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLD:
3642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return true;
3652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  }
3662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
3672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
368d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
369d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
370d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
3713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
372115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
373115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  unsigned NumberOfSections) {
3743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
3753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
3763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0x7f); // e_ident[EI_MAG0]
3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('E');  // e_ident[EI_MAG1]
3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('L');  // e_ident[EI_MAG2]
3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('F');  // e_ident[EI_MAG3]
3863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
387bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
3883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
390115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
3935baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
394dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  Write8(TargetObjectWriter->getOSABI());
3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0);                  // e_ident[EI_ABIVERSION]
3963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(ELF::ET_REL);             // e_type
4003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
401bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(ELF::EV_CURRENT);         // e_version
4043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
4053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
406bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
407eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4092d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  // e_flags = whatever the target wants
410e8526d030f2cf8cc79f2d923274944cb0fa9c4ebRafael Espindola  Write32(getEFlags());
4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
413bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phentsize = prog header entry size
4163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phnum = # prog header entries = 0
4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
419bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
4227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
423aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky    Write16(ELF::SHN_UNDEF);
4247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
4257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(NumberOfSections);
4263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
428b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky  if (ShstrtabIndex >= ELF::SHN_LORESERVE)
4297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ELF::SHN_XINDEX);
4307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
4317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ShstrtabIndex);
4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
434115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
435115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
436115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t name,
437115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint8_t info, uint64_t value,
438115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t size, uint8_t other,
439115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t shndx,
440115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       bool Reserved) {
4417be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (ShndxF) {
4427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
443af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, shndx);
4447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    else
445af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, 0);
4467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
4477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
448af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
449af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    uint16_t(ELF::SHN_XINDEX) : shndx;
4503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
451bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
452af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
453af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
454af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
455af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
456af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, value); // st_value
457af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, size);  // st_size
4583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
459af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
460af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, value); // st_value
461af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, size);  // st_size
462af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
463af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
464af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
4692ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                      const MCAsmLayout &Layout) {
4702c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (Data.isCommon() && Data.isExternal())
4712c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return Data.getCommonAlignment();
4722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
4732c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
474d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
475d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  if (Symbol.isAbsolute() && Symbol.isVariable()) {
476d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    if (const MCExpr *Value = Symbol.getVariableValue()) {
477d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      int64_t IntValue;
478d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      if (Value->EvaluateAsAbsolute(IntValue, Layout))
479f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach        return (uint64_t)IntValue;
480d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    }
481d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  }
482d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
4832c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (!Symbol.isInSection())
4842c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return 0;
4852c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
4866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (Data.getFragment()) {
4886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Data.getFlags() & ELF_Other_ThumbFunc)
4896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Layout.getSymbolOffset(&Data)+1;
4906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    else
4916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Layout.getSymbolOffset(&Data);
4926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
4932c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
4942c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  return 0;
4952c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
4962c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
49785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
49885f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                               const MCAsmLayout &Layout) {
49988182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
50088182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
50188182132470527e27231f09b25a885893e528c66Rafael Espindola
50288182132470527e27231f09b25a885893e528c66Rafael Espindola  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
50388182132470527e27231f09b25a885893e528c66Rafael Espindola         ie = Asm.symbol_end(); it != ie; ++it) {
50488182132470527e27231f09b25a885893e528c66Rafael Espindola    const MCSymbol &Alias = it->getSymbol();
50594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &Symbol = Alias.AliasedSymbol();
506f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    MCSymbolData &SD = Asm.getSymbolData(Symbol);
507f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
508f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
509f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    if (&Symbol == &Alias)
510f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
511f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
51207ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
51388182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
51488182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
51588182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
51688182132470527e27231f09b25a885893e528c66Rafael Espindola
517f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
518f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
519f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    it->setExternal(SD.isExternal());
5202ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(*it, MCELF::GetBinding(SD));
521f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
52207ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
52388182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
52488182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
52588182132470527e27231f09b25a885893e528c66Rafael Espindola
52683ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
52783ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
52883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
52983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
53083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
53107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
53288182132470527e27231f09b25a885893e528c66Rafael Espindola  }
53388182132470527e27231f09b25a885893e528c66Rafael Espindola}
53488182132470527e27231f09b25a885893e528c66Rafael Espindola
535115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
536115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  MCDataFragment *ShndxF,
537115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  ELFSymbolData &MSD,
538115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
539de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &OrigData = *MSD.SymbolData;
540de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &Data =
54194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
542152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
5437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
5447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Data.getSymbol().isVariable();
5457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
5462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Binding = MCELF::GetBinding(OrigData);
5472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Visibility = MCELF::GetVisibility(OrigData);
5482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Type = MCELF::GetType(Data);
549152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
550152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
551152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Other = Visibility;
552152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
5532c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  uint64_t Value = SymbolValue(Data, Layout);
5543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
5553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
556f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(!(Data.isCommon() && !Data.isExternal()));
557f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
558f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  const MCExpr *ESize = Data.getSize();
559f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  if (ESize) {
560f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    int64_t Res;
561f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    if (!ESize->EvaluateAsAbsolute(Res, Layout))
562f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola      report_fatal_error("Size expression must be absolute.");
563f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    Size = Res;
5643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
5653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
5677be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
5687be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                   Size, Other, MSD.SectionIndex, IsReserved);
5693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
571115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
572115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
573115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAssembler &Asm,
574115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAsmLayout &Layout,
575a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                                    const SectionIndexMapTy &SectionIndexMap) {
5763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The string table must be emitted first because we need the index
5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // into the string table for all the symbol names.
5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(StringTable.size() && "Missing string table");
5793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make sure the start of the symbol table is aligned.
5813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry is the undefined symbol entry.
5837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
5843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write the symbol table entries.
5863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
5883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = LocalSymbolData[i];
5897be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
5913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
59271859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Write out a symbol table entry for each regular section.
5934beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
5944beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola       ++i) {
595a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    const MCSectionELF &Section =
5964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola      static_cast<const MCSectionELF&>(i->getSection());
5974beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola    if (Section.getType() == ELF::SHT_RELA ||
5984beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_REL ||
5994beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_STRTAB ||
600d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky        Section.getType() == ELF::SHT_SYMTAB ||
601d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky        Section.getType() == ELF::SHT_SYMTAB_SHNDX)
602a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman      continue;
6037be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
604a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section),
605a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                     false);
606a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    LastLocalSymbolIndex++;
607a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman  }
6083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
6103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = ExternalSymbolData[i];
6113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
6123223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    assert(((Data.getFlags() & ELF_STB_Global) ||
6133223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola            (Data.getFlags() & ELF_STB_Weak)) &&
6143223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola           "External symbol requires STB_GLOBAL or STB_WEAK flag");
6157be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
6162ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
6183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
6213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = UndefinedSymbolData[i];
6223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
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
6291f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
6301f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCValue &Target,
6312684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach                                               const MCFragment &F,
632e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               const MCFixup &Fixup,
633e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               bool IsPCRel) const {
6341f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
63594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
63694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol *Renamed = Renames.lookup(&Symbol);
63794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
63894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola
63994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (ASymbol.isUndefined()) {
64094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
64194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
64294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &ASymbol;
6431f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
6441f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
64594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (SD.isExternal()) {
64694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
64794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
64894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
64994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
6507eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
6517eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola  const MCSectionELF &Section =
65294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    static_cast<const MCSectionELF&>(ASymbol.getSection());
65325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  const SectionKind secKind = Section.getKind();
6547eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
65525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isBSS())
656e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
6577eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
65825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isThreadLocal()) {
65925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    if (Renamed)
66025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola      return Renamed;
66125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    return &Symbol;
66225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
66325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
6648cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
6653729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola  const MCSectionELF &Sec2 =
6663729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola    static_cast<const MCSectionELF&>(F.getParent()->getSection());
6673729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
6688cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  if (&Sec2 != &Section &&
669c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola      (Kind == MCSymbolRefExpr::VK_PLT ||
670c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
67125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
67294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
67394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
67494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
67594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
6763729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
6771c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola  if (Section.getFlags() & ELF::SHF_MERGE) {
67894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Target.getConstant() == 0)
679e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
68094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
68194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
68294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
6831f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
684c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
685e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
686e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
68773ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
68873ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
69056a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
69156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCAsmLayout &Layout,
69256a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFragment *Fragment,
69356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFixup &Fixup,
69456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       MCValue Target,
69556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       uint64_t &FixedValue) {
69656a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Addend = 0;
69756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int Index = 0;
69856a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Value = Target.getConstant();
69956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  const MCSymbol *RelocSymbol = NULL;
70056a399023aba6cf1348533df04732950c43eaca7Jason W Kim
701127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
70256a399023aba6cf1348533df04732950c43eaca7Jason W Kim  if (!Target.isAbsolute()) {
70356a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
70456a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
705e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);
70656a399023aba6cf1348533df04732950c43eaca7Jason W Kim
70756a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
70856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
70956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
71056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      IsPCRel = true;
71156a399023aba6cf1348533df04732950c43eaca7Jason W Kim
71256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
71356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t a = Layout.getSymbolOffset(&SDB);
71456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
715a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes      // Offset of the relocation in the section
71656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
71756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += b - a;
71856a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
71956a399023aba6cf1348533df04732950c43eaca7Jason W Kim
72056a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (!RelocSymbol) {
72156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
72256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCFragment *F = SD.getFragment();
72356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = F->getParent()->getOrdinal() + 1;
72556a399023aba6cf1348533df04732950c43eaca7Jason W Kim
72656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
72756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += Layout.getSymbolOffset(&SD);
72856a399023aba6cf1348533df04732950c43eaca7Jason W Kim    } else {
72956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
73056a399023aba6cf1348533df04732950c43eaca7Jason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
73156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      else
73256a399023aba6cf1348533df04732950c43eaca7Jason W Kim        UsedInReloc.insert(RelocSymbol);
73356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = -1;
73456a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
73556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Addend = Value;
73656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    // Compensate for the addend on i386.
737bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit())
73856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value = 0;
73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  }
74056a399023aba6cf1348533df04732950c43eaca7Jason W Kim
74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  FixedValue = Value;
74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
74356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                               (RelocSymbol != 0), Addend);
744c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
745c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
746c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  if (RelocNeedsGOT(Modifier))
747c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola    NeedsGOT = true;
7482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
74956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
75056a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Fixup.getOffset();
7512a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky
752f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola  // FIXME: no tests cover this. Is adjustFixupOffset dead code?
753f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola  TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset);
75456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
755bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (!hasRelocationAddend())
756bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    Addend = 0;
757bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
758bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola  if (is64Bit())
759bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola    assert(isInt<64>(Addend));
760bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola  else
761bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola    assert(isInt<32>(Addend));
762bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
76300ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup);
76456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
76556a399023aba6cf1348533df04732950c43eaca7Jason W Kim}
76656a399023aba6cf1348533df04732950c43eaca7Jason W Kim
76756a399023aba6cf1348533df04732950c43eaca7Jason W Kim
7680b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t
769115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
770115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             const MCSymbol *S) {
7717b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer  MCSymbolData &SD = Asm.getSymbolData(*S);
772ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  return SD.getIndex();
7733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
7762ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 const MCSymbolData &Data,
7772ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 bool Used, bool Renamed) {
778484291c27319668ad99cb87def000254357736fbRafael Espindola  if (Data.getFlags() & ELF_Other_Weakref)
779484291c27319668ad99cb87def000254357736fbRafael Espindola    return false;
780484291c27319668ad99cb87def000254357736fbRafael Espindola
781bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
782bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
783bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
78488182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
78588182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
78688182132470527e27231f09b25a885893e528c66Rafael Espindola
787737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
788a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
789d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
790d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola    return true;
791d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola
79294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &A = Symbol.AliasedSymbol();
79321451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (Symbol.isVariable() && !A.isVariable() && A.isUndefined())
79421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola    return false;
79521451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola
7962ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
79721451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
798a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
799a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
800737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
801737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
802737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
803bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
804737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
805737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
806737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
807737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
808737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
8092ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
8102ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                              bool isUsedInReloc) {
811737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (Data.isExternal())
812737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
813737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
814737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
81594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
8161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
8181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (isSignature && !isUsedInReloc)
8191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      return true;
8201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
821737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
8221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  }
823737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
824737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
825737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
826737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
827115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
8287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      SectionIndexMapTy &SectionIndexMap,
8297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const RelMapTy &RelMap) {
830bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  unsigned Index = 1;
831bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
832bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
833bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    const MCSectionELF &Section =
834bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
8362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionIndexMap[&Section] = Index++;
8382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
8392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
8402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
8412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         ie = Asm.end(); it != ie; ++it) {
8422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
8432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP ||
8457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_REL ||
8467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
8472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
848bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    SectionIndexMap[&Section] = Index++;
8497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelSection = RelMap.lookup(&Section);
8507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (RelSection)
8517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      SectionIndexMap[RelSection] = Index++;
852bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  }
853bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola}
854bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
855115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
8561f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
8577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         RevGroupMapTy RevGroupMap,
8587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         unsigned NumRegularSections) {
8595c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  // FIXME: Is this the correct place to do this?
860378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola  // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
8615c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  if (NeedsGOT) {
8625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
8635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
8645c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
8655c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    Data.setExternal(true);
8662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(Data, ELF::STB_GLOBAL);
8675c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
8685c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Index 0 is always the empty string.
8703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringMap<uint64_t> StringIndexMap;
8713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTable += '\x00';
8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
873d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  // FIXME: We could optimize suffixes in strtab in the same way we
874d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  // optimize them in shstrtab.
875d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
876a0949b50dcea35c08b50542091f97275f401529dRafael Espindola  // Add the data for the symbols.
8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.symbol_end(); it != ie; ++it) {
8793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSymbol &Symbol = it->getSymbol();
8803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
881484291c27319668ad99cb87def000254357736fbRafael Espindola    bool Used = UsedInReloc.count(&Symbol);
882484291c27319668ad99cb87def000254357736fbRafael Espindola    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
8831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool isSignature = RevGroupMap.count(&Symbol);
8841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!isInSymtab(Asm, *it,
8861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    Used || WeakrefUsed || isSignature,
88788182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
8893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
8913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MSD.SymbolData = it;
89294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
8933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Undefined symbols are global, but this is the first place we
8951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // are able to set it.
8961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool Local = isLocal(*it, isSignature, Used);
8972ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
8981f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
8992ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_GLOBAL);
9002ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(SD, ELF::STB_GLOBAL);
9011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    }
9021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
903484291c27319668ad99cb87def000254357736fbRafael Espindola    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
9042ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_WEAK);
905484291c27319668ad99cb87def000254357736fbRafael Espindola
906f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    if (it->isCommon()) {
907a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
908f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
909bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
910a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      MSD.SectionIndex = ELF::SHN_ABS;
91188182132470527e27231f09b25a885893e528c66Rafael Espindola    } else if (RefSymbol.isUndefined()) {
9121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      if (isSignature && !Used)
9131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
9141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      else
9151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
9163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
917bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
918bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola        static_cast<const MCSectionELF&>(RefSymbol.getSection());
919bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
9207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
9217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola        NeedsSymtabShndx = true;
9223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
9235df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
9245df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
92588182132470527e27231f09b25a885893e528c66Rafael Espindola    // The @@@ in symbol version is replaced with @ in undefined symbols and
92688182132470527e27231f09b25a885893e528c66Rafael Espindola    // @@ in defined ones.
92788182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
9281261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    SmallString<32> Buf;
9291261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer
93088182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = Name.find("@@@");
93188182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos != StringRef::npos) {
9321261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(0, Pos);
9331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
9341261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(Pos + Skip);
9351261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Name = Buf;
93688182132470527e27231f09b25a885893e528c66Rafael Espindola    }
93788182132470527e27231f09b25a885893e528c66Rafael Espindola
9381261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    uint64_t &Entry = StringIndexMap[Name];
939a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (!Entry) {
940a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      Entry = StringTable.size();
9411261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      StringTable += Name;
942a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      StringTable += '\x00';
9433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
944a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    MSD.StringIndex = Entry;
945a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (MSD.SectionIndex == ELF::SHN_UNDEF)
946a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      UndefinedSymbolData.push_back(MSD);
947a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else if (Local)
948a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
949a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
950a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
9513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
9523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
9543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
9553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
9563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
9573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
9593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
960ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  unsigned Index = 1;
9613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
9623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    LocalSymbolData[i].SymbolData->setIndex(Index++);
963ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
964ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  Index += NumRegularSections;
965ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
9673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ExternalSymbolData[i].SymbolData->setIndex(Index++);
9683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
9693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
9707aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky
9717aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky  if (NumRegularSections > ELF::SHN_LORESERVE)
9727aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky    NeedsSymtabShndx = true;
9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
9743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
9767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               MCAsmLayout &Layout,
9777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               RelMapTy &RelMap) {
9787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
9797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
9807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
9817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Relocations[&SD].empty())
9827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
9837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
9843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCContext &Ctx = Asm.getContext();
9853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
9863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      static_cast<const MCSectionELF&>(SD.getSection());
9873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const StringRef SectionName = Section.getSectionName();
989bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
9903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    RelaSectionName += SectionName;
991299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer
992299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    unsigned EntrySize;
993bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (hasRelocationAddend())
994bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
995299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    else
996bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
9973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection =
9997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
10007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        ELF::SHT_RELA : ELF::SHT_REL, 0,
10017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        SectionKind::getReadOnly(),
10027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        EntrySize, "");
10037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    RelMap[&Section] = RelaSection;
10047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Asm.getOrCreateSectionData(*RelaSection);
10057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
10077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
10097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                       const RelMapTy &RelMap) {
10107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
10117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
10147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF&>(SD.getSection());
10153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection = RelMap.lookup(&Section);
10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (!RelaSection)
10187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
10193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
1020bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    RelaSD.setAlignment(is64Bit() ? 8 : 4);
10213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCDataFragment *F = new MCDataFragment(&RelaSD);
10237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteRelocationsFragment(Asm, F, &*it);
10243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1027115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
1028115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
1029115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
1030115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
1031115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
1032115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Name);        // sh_name: index into string table
10343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Type);        // sh_type
10353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
10363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
10373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Link);        // sh_link
10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Info);        // sh_info
10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
10433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1045115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
1046115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               MCDataFragment *F,
1047115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               const MCSectionData *SD) {
10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
104900ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka
105000ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  // Sort the relocation entries. Most targets just sort by r_offset, but some
105100ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  // (e.g., MIPS) have additional constraints.
105200ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka  TargetObjectWriter->sortRelocs(Asm, Relocs);
10533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
10553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFRelocationEntry entry = Relocs[e - i - 1];
10563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
105712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    if (!entry.Index)
105812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      ;
105912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    else if (entry.Index < 0)
10608f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
10618f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    else
106212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      entry.Index += LocalSymbolData.size();
1063bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit()) {
1064af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, entry.r_offset);
106593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      if (TargetObjectWriter->isN64()) {
106693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String32(*F, entry.Index);
10675e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
106893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRSsym(entry.Type));
106993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRType3(entry.Type));
107093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRType2(entry.Type));
107193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String8(*F, TargetObjectWriter->getRType(entry.Type));
107293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      }
107393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      else {
107493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        struct ELF::Elf64_Rela ERE64;
107593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        ERE64.setSymbolAndType(entry.Index, entry.Type);
107693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        String64(*F, ERE64.r_info);
107793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      }
1078bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
1079af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String64(*F, entry.r_addend);
10805e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
1081af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, entry.r_offset);
10825e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10838f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
10848f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE32.setSymbolAndType(entry.Index, entry.Type);
1085af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, ERE32.r_info);
10865e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1087bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
1088af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String32(*F, entry.r_addend);
10895e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
10903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1093d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) {
1094d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a);
1095d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b);
1096d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const StringRef &NameA = secA->getSectionName();
1097d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const StringRef &NameB = secB->getSectionName();
1098d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned sizeA = NameA.size();
1099d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned sizeB = NameB.size();
1100d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned len = std::min(sizeA, sizeB);
1101d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (unsigned int i = 0; i < len; ++i) {
1102d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    char ca = NameA[sizeA - i - 1];
1103d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    char cb = NameB[sizeB - i - 1];
1104d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    if (ca != cb)
1105d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      return cb - ca;
1106d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  }
1107d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
1108d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  return sizeB - sizeA;
1109d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola}
1110d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
1111115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
1112115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             MCAsmLayout &Layout,
11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             SectionIndexMapTy &SectionIndexMap,
11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             const RelMapTy &RelMap) {
11153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCContext &Ctx = Asm.getContext();
11163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F;
11173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1118bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
11193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
112038738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
11214283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *ShstrtabSection =
11227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
11233f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                      SectionKind::getReadOnly());
112471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
112571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabSD.setAlignment(1);
112671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
11274283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *SymtabSection =
11287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
11297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                      SectionKind::getReadOnly(),
11302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      EntrySize, "");
11313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
1132bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
11337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
11347be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCSectionData *SymtabShndxSD = NULL;
11357be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
11367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
11374283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *SymtabShndxSection =
11387be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
11392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                        SectionKind::getReadOnly(), 4, "");
11407be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
11417be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD->setAlignment(4);
11427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
11433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionELF *StrtabSection;
11453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
11463f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                    SectionKind::getReadOnly());
11473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
11483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSD.setAlignment(1);
11493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
11517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection);
11537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SymbolTableIndex = SectionIndexMap.lookup(SymtabSection);
11547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  StringTableIndex = SectionIndexMap.lookup(StrtabSection);
115571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
115671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Symbol table
115771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  F = new MCDataFragment(&SymtabSD);
11587be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCDataFragment *ShndxF = NULL;
11597be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
11607be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShndxF = new MCDataFragment(SymtabShndxSD);
11617be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
11624beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
116371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
11643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&StrtabSD);
11653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents().append(StringTable.begin(), StringTable.end());
11663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&ShstrtabSD);
11683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1169d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  std::vector<const MCSectionELF*> Sections;
1170d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
1171d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
1172d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    const MCSectionELF &Section =
1173d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
1174d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    Sections.push_back(&Section);
1175d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  }
1176d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
1177d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
11783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Section header string table.
11793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
11803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry of a string table holds a null character so skip
11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // section 0.
11823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Index = 1;
11833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents() += '\x00';
11843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1185d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
1186d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    const MCSectionELF &Section = *Sections[I];
11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    StringRef Name = Section.getSectionName();
1189d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    if (I != 0) {
1190d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      StringRef PreviousName = Sections[I - 1]->getSectionName();
1191d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      if (PreviousName.endswith(Name)) {
1192d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola        SectionStringTableIndex[&Section] = Index - Name.size() - 1;
1193d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola        continue;
1194d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      }
11952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
11963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the index into the string table so we can write it
11973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // into the sh_name field of the section header table.
11982ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionStringTableIndex[&Section] = Index;
11993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Index += Name.size() + 1;
12012ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    F->getContents() += Name;
12023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    F->getContents() += '\x00';
12033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
12047070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola}
12057070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
120696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
120796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            MCAsmLayout &Layout,
120896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            GroupMapTy &GroupMap,
12097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            RevGroupMapTy &RevGroupMap,
12107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            SectionIndexMapTy &SectionIndexMap,
12117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            const RelMapTy &RelMap) {
121296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  // Create the .note.GNU-stack section if needed.
121396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  MCContext &Ctx = Asm.getContext();
121496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  if (Asm.getNoExecStack()) {
121596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    const MCSectionELF *GnuStackSection =
121696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
121796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                        SectionKind::getReadOnly());
121896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    Asm.getOrCreateSectionData(*GnuStackSection);
121996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  }
122096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola
12212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Build the groups
12222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
12232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it) {
12242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
12252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
12261c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
12272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
12282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSymbol *SignatureSymbol = Section.getGroup();
12302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Asm.getOrCreateSymbolData(*SignatureSymbol);
12311f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
12322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!Group) {
123396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Group = Ctx.CreateELFGroupSection();
12342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Data.setAlignment(4);
12362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCDataFragment *F = new MCDataFragment(&Data);
12372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      String32(*F, ELF::GRP_COMDAT);
12382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
12392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupMap[Group] = SignatureSymbol;
12402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
12437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
12442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Add sections to the groups
12452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
12467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola       it != ie; ++it) {
12472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
12482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
12491c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
12502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
12511f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
12522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    // FIXME: we could use the previous fragment
12542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCDataFragment *F = new MCDataFragment(&Data);
12557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    unsigned Index = SectionIndexMap.lookup(&Section);
12567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    String32(*F, Index);
12572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
12592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1260115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
1261115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const SectionIndexMapTy &SectionIndexMap,
1262115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint32_t GroupSymbolIndex,
1263115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Offset, uint64_t Size,
1264115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Alignment,
1265115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const MCSectionELF &Section) {
1266c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
1267c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
1268c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1269c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
1270c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
1271c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionStringTableIndex[&Section];
1272c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = 0;
1273c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1274c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1275c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
1276c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
1277c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *SymtabSection;
1278c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *InfoSection;
1279c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                   0,
12813f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                   SectionKind::getReadOnly());
1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionIndexMap.lookup(SymtabSection);
1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Remove ".rel" and ".rela" prefixes.
1286c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    InfoSection = Asm.getContext().getELFSection(SectionName,
1290c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                 ELF::SHT_PROGBITS, 0,
12913f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                 SectionKind::getReadOnly());
1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1295c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
1300c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1302c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
1303c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
1304c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1305c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1306c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_PROGBITS:
1307c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_STRTAB:
1308c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NOBITS:
130998976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola  case ELF::SHT_NOTE:
1310c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NULL:
1311c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_ARM_ATTRIBUTES:
131286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_INIT_ARRAY:
131386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_FINI_ARRAY:
131486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_PREINIT_ARRAY:
13150cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola  case ELF::SHT_X86_64_UNWIND:
1316c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Nothing to do.
1317c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1318c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
13194a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky  case ELF::SHT_GROUP:
13202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
13212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
13222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
13232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1324c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  default:
1325c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(0 && "FIXME: sh_type value not supported!");
1326c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1327c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1328c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1329c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
1330c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
1331c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Alignment, Section.getEntrySize());
1332c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola}
1333c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
13342ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) {
1335f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola  return SD.getOrdinal() == ~UINT32_C(0) &&
13366db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    !SD.getSection().isVirtualSection();
13376db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) {
13406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  uint64_t Ret = 0;
13416db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
13426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola       ++i) {
13436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    const MCFragment &F = *i;
13446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    assert(F.getKind() == MCFragment::FT_Data);
13456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    Ret += cast<MCDataFragment>(F).getContents().size();
13466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
13476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Ret;
13486db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13496db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout,
13512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                             const MCSectionData &SD) {
13526db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
13536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
13546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Layout.getSectionFileSize(&SD);
13556db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13566db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
13582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                                const MCSectionData &SD) {
13596db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
13606db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
136185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  return Layout.getSectionAddressSize(&SD);
13626db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
13636db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
13647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
13657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCAsmLayout &Layout,
13667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCSectionELF &Section) {
13677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
13687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
1369263109d822314305822796a2cc05e98304793051Benjamin Kramer  uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
13707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteZeros(Padding);
13717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
13727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  if (IsELFMetaDataSection(SD)) {
13737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
13747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ++i) {
13757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      const MCFragment &F = *i;
13767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      assert(F.getKind() == MCFragment::FT_Data);
13777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      WriteBytes(cast<MCDataFragment>(F).getContents().str());
13787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    }
13797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  } else {
1380f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach    Asm.writeSectionData(&SD, Layout);
13817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
13827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
13837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
13847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
13857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const GroupMapTy &GroupMap,
13867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const MCAsmLayout &Layout,
13877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
13887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                   const SectionOffsetMapTy &SectionOffsetMap) {
13897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumSections = Asm.size() + 1;
13907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
13917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  std::vector<const MCSectionELF*> Sections;
13927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  Sections.resize(NumSections - 1);
13937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
13947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (SectionIndexMapTy::const_iterator i=
13957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
13967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
13977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Sections[p.second - 1] = p.first;
13987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
13997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Null section first.
14017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FirstSectionSize =
14027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
14037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint32_t FirstSectionLink =
14047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
14057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
14067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumSections - 1; ++i) {
14087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section = *Sections[i];
14097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
14107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint32_t GroupSymbolIndex;
14117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
14127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = 0;
14137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    else
14147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm,
14157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                                     GroupMap.lookup(&Section));
14167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint64_t Size = GetSectionAddressSize(Layout, SD);
14187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
14207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SectionOffsetMap.lookup(&Section), Size,
14217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SD.getAlignment(), Section);
14227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
14247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm,
14267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                  std::vector<const MCSectionELF*> &Sections) {
14277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
14287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
14297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
14307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
14317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP)
14327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
14337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
14367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
14377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
14387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
14397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP &&
14407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_REL &&
14417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_RELA)
14427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
14437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
14447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
14467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
14477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
14487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
14497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_REL ||
14507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
14517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
14526db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
14536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
14546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
1455115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
1456115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
14572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  GroupMapTy GroupMap;
14581f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
1459bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1460bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
14617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumUserSections = Asm.size();
14627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
14647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
14657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumUserAndRelocSections = Asm.size();
14677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
14687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        RevGroupMap, SectionIndexMap, RelMap);
14697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned AllSections = Asm.size();
14707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
14717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumRegularSections = NumUserSections + NumIndexedSections;
1473bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
14748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola  // Compute symbol table information.
14757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
14767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
14787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
14798f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
14803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
14814beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         const_cast<MCAsmLayout&>(Layout),
14827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         SectionIndexMap,
14837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         RelMap);
14841d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
1485bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
1486bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
1487bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                    sizeof(ELF::Elf32_Ehdr);
1488a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t FileOff = HeaderSize;
14893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
14902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  std::vector<const MCSectionELF*> Sections;
14917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSectionOrder(Asm, Sections);
14927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumSections = Sections.size();
14937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SectionOffsetMapTy SectionOffsetMap;
14947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i) {
14952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
14962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
14973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1498a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1499a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Remember the offset into the file for this section.
15017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    SectionOffsetMap[&Section] = FileOff;
15027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Get the size of the section in the output file (including padding).
15046db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
15053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
15063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1507a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
1508a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned SectionHeaderOffset = FileOff - HeaderSize;
15103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t SectionHeaderEntrySize = is64Bit() ?
15127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
15137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += (NumSections + 1) * SectionHeaderEntrySize;
15143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) {
15162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
15172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
1518a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1520a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
15222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionOffsetMap[&Section] = FileOff;
152344cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
15247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Get the size of the section in the output file (including padding).
15256db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
15263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
15273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
15287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Write out the ELF header ...
15297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteHeader(SectionHeaderOffset, NumSections + 1);
15307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
15317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the regular sections ...
15327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // + because of .shstrtab
15337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i)
15347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
15357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
1536263109d822314305822796a2cc05e98304793051Benjamin Kramer  uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
1537a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteZeros(Padding);
1538a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
15397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the section header table ...
15407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
15417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                     SectionOffsetMap);
15423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1543aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky  // ... and then the remaining sections ...
15447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
15457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
15463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
15473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
154878c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool
154978c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
155078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCSymbolData &DataA,
155178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCFragment &FB,
155278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool InSet,
155378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool IsPCRel) const {
155478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  if (DataA.getFlags() & ELF_STB_Weak)
155578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman    return false;
155678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
155778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                 Asm, DataA, FB,InSet, IsPCRel);
155878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman}
155978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman
15606024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
15616024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola                                            raw_ostream &OS,
1562bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                            bool IsLittleEndian) {
15637bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola  return new ELFObjectWriter(MOTW, OS, IsLittleEndian);
1564edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola}
1565