17394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//                     The LLVM Compiler Infrastructure
43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source
63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details.
73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file implements ELF object file writer information.
113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCELFObjectWriter.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallPtrSet.h"
173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallString.h"
183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h"
1978c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h"
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCAsmInfo.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h"
223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCAssembler.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
25f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h"
26f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h"
273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSymbolELF.h"
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h"
30c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/StringTableBuilder.h"
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/Compression.h"
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Endian.h"
35d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h"
36cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Support/StringSaver.h"
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
383565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef  DEBUG_TYPE
41e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info"
42e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
433963d617b3709c510003ac816fb42f28539fc62bRafael Espindolanamespace {
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestypedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy;
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass ELFObjectWriter;
486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass SymbolTableWriter {
506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ELFObjectWriter &EWriter;
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool Is64Bit;
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // indexes we are going to write to .symtab_shndx.
546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::vector<uint32_t> ShndxIndexes;
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The numbel of symbols written so far.
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned NumWritten;
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void createSymtabShndx();
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  template <typename T> void write(T Value);
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit);
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   uint8_t other, uint32_t shndx, bool Reserved);
686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
723963d617b3709c510003ac816fb42f28539fc62bRafael Espindolaclass ELFObjectWriter : public MCObjectWriter {
733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                           bool Used, bool Renamed);
773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    /// Helper struct for containing some precomputed information on symbols.
793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    struct ELFSymbolData {
806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      const MCSymbolELF *Symbol;
813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      uint32_t SectionIndex;
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      StringRef Name;
833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      // Support lexicographic sorting.
853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      bool operator<(const ELFSymbolData &RHS) const {
866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        unsigned LHSType = Symbol->getType();
876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        unsigned RHSType = RHS.Symbol->getType();
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return false;
9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return true;
9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return SectionIndex < RHS.SectionIndex;
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return Name < RHS.Name;
953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      }
963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    };
973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// The target specific ELF writer instance.
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
1003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
1023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Relocations;
1053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @}
1073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @name Symbol Table Data
1083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @{
1093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
110cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    BumpPtrAllocator Alloc;
111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    StringSaver VersionSymSaver{Alloc};
112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
1133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    /// @}
1153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the symbol table index of the last local symbol.
1173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned LastLocalSymbolIndex;
1183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the .strtab section index.
1193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned StringTableIndex;
1203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // This holds the .symtab section index.
1213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned SymbolTableIndex;
1223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Sections in the order they are to be output in the section table.
1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    std::vector<const MCSectionELF *> SectionTable;
1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    unsigned addToSectionTable(const MCSectionELF *Sec);
1263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    // TargetObjectWriter wrappers.
1283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
1293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    bool hasRelocationAddend() const {
1303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      return TargetObjectWriter->hasRelocationAddend();
1313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          bool IsPCRel) const {
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel);
1353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void align(unsigned Alignment);
1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  public:
1400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    bool IsLittleEndian)
1426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
1433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    void reset() override {
1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      Renames.clear();
1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      Relocations.clear();
1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      StrTabBuilder.clear();
1486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SectionTable.clear();
1494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      MCObjectWriter::reset();
1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    ~ELFObjectWriter() override;
1533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    void WriteWord(uint64_t W) {
1553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      if (is64Bit())
1566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write64(W);
1573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola      else
1586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write32(W);
1593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    template <typename T> void write(T Val) {
1626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (IsLittleEndian)
163cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        support::endian::Writer<support::little>(getStream()).write(Val);
1646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      else
165cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        support::endian::Writer<support::big>(getStream()).write(Val);
1663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    }
1673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeHeader(const MCAssembler &Asm);
1693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
1716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     ELFSymbolData &MSD, const MCAsmLayout &Layout);
1723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Start and end offset of each section
1746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
1756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        SectionOffsetsTy;
1763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool shouldRelocateWithSymbol(const MCAssembler &Asm,
178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  const MCSymbolRefExpr *RefA,
1796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                  const MCSymbol *Sym, uint64_t C,
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  unsigned Type) const;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCFragment *Fragment, const MCFixup &Fixup,
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          MCValue Target, bool &IsPCRel,
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          uint64_t &FixedValue) override;
1863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
1876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Map from a signature symbol to the group section index
1886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy;
1893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// Compute the symbol table data
1913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola    ///
192828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param Asm - The assembler.
193828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param SectionIndexMap - Maps a section to its index.
194828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola    /// \param RevGroupMap - Maps a signature symbol to the group section.
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
1963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
1976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                            const RevGroupMapTy &RevGroupMap,
1986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                            SectionOffsetsTy &SectionOffsets);
1996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSectionELF *createRelocationSection(MCContext &Ctx,
2016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                          const MCSectionELF &Sec);
2023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCSectionELF *createStringTable(MCContext &Ctx);
2043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void executePostLayoutBinding(MCAssembler &Asm,
2066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                  const MCAsmLayout &Layout) override;
2073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeSectionHeader(const MCAsmLayout &Layout,
2096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                            const SectionIndexMapTy &SectionIndexMap,
2106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                            const SectionOffsetsTy &SectionOffsets);
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
2136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                          const MCAsmLayout &Layout);
2143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
2166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                          uint64_t Address, uint64_t Offset, uint64_t Size,
2176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                          uint32_t Link, uint32_t Info, uint64_t Alignment,
2186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                          uint64_t EntrySize);
2193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
2213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
2236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                const MCSymbol &SymA,
2246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                const MCFragment &FB,
2256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                bool InSet,
2266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                bool IsPCRel) const override;
2273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool isWeak(const MCSymbol &Sym) const override;
2293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
2316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    void writeSection(const SectionIndexMapTy &SectionIndexMap,
2326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                      uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
2333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola                      const MCSectionELF &Section);
2343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola  };
2353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola}
2363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola
2376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::align(unsigned Alignment) {
238cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment);
2396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  WriteZeros(Padding);
2406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarunsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) {
2436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SectionTable.push_back(Sec);
2446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  StrTabBuilder.add(Sec->getSectionName());
2456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return SectionTable.size();
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid SymbolTableWriter::createSymtabShndx() {
2496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!ShndxIndexes.empty())
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ShndxIndexes.resize(NumWritten);
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainartemplate <typename T> void SymbolTableWriter::write(T Value) {
2566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  EWriter.write(Value);
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSymbolTableWriter::SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit)
2606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    uint64_t size, uint8_t other,
26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    uint32_t shndx, bool Reserved) {
26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LargeIndex)
26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    createSymtabShndx();
26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!ShndxIndexes.empty()) {
27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (LargeIndex)
2726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ShndxIndexes.push_back(shndx);
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
2746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ShndxIndexes.push_back(0);
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Is64Bit) {
2806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(name);  // st_name
2816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(info);  // st_info
2826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(other); // st_other
2836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(Index); // st_shndx
2846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(value); // st_value
2856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(size);  // st_size
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
2876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(name);            // st_name
2886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(uint32_t(value)); // st_value
2896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(uint32_t(size));  // st_size
2906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(info);            // st_info
2916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(other);           // st_other
2926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(Index);           // st_shndx
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ++NumWritten;
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
2992ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  const MCFixupKindInfo &FKI =
3002ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
3012ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
3022ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
3032ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
3042ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
305d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
306d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
307d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
3096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
3143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
3153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
3173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  writeBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3]
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
3236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
3265baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
3276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write8(TargetObjectWriter->getOSABI());
3286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write8(0);                  // e_ident[EI_ABIVERSION]
3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(ELF::ET_REL);             // e_type
3333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(TargetObjectWriter->getEMachine()); // e_machine = target
3353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write32(ELF::EV_CURRENT);         // e_version
3373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
3383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
3390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  WriteWord(0);                     // e_shoff = sec hdr table off in bytes
3403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3412d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  // e_flags = whatever the target wants
3426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write32(Asm.getELFHeaderEFlags());
3433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
3456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
3463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(0);                  // e_phentsize = prog header entry size
3486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(0);                  // e_phnum = # prog header entries = 0
3493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
3516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
3523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
3546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(0);
3553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
3576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(StringTableIndex < ELF::SHN_LORESERVE);
3586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write16(StringTableIndex);
3593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainaruint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const MCAsmLayout &Layout) {
3636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Sym.isCommon() && Sym.isExternal())
3646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return Sym.getCommonAlignment();
3653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t Res;
3676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!Layout.getSymbolOffset(Sym, Res))
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
369d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
3706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Layout.getAssembler().isThumbFunc(&Sym))
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Res |= 1;
3722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Res;
3742c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
3752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
3766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
37785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                               const MCAsmLayout &Layout) {
37888182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
37988182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
38088182132470527e27231f09b25a885893e528c66Rafael Espindola
3816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const MCSymbol &A : Asm.symbols()) {
3826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const auto &Alias = cast<MCSymbolELF>(A);
383f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Alias.isVariable())
385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Ref)
388f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
3896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol());
390f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
39107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
39288182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
39388182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
39488182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
39588182132470527e27231f09b25a885893e528c66Rafael Espindola
396f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
397f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
3986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Alias.setExternal(Symbol.isExternal());
3996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Alias.setBinding(Symbol.getBinding());
400f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
40107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
40288182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
40388182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
40488182132470527e27231f09b25a885893e528c66Rafael Espindola
40583ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
40683ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
40783ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
40883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
40983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
41007ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
41188182132470527e27231f09b25a885893e528c66Rafael Espindola  }
41288182132470527e27231f09b25a885893e528c66Rafael Espindola}
41388182132470527e27231f09b25a885893e528c66Rafael Espindola
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t Type = newType;
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Propagation rules:
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // IFUNC > FUNC > OBJECT > NOTYPE
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // TLS_OBJECT > OBJECT > NOTYPE
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // dont let the new type degrade the old type
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (origType) {
42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STT_GNU_IFUNC:
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Type = ELF::STT_GNU_IFUNC;
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STT_FUNC:
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Type == ELF::STT_TLS)
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Type = ELF::STT_FUNC;
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STT_OBJECT:
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Type == ELF::STT_NOTYPE)
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Type = ELF::STT_OBJECT;
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STT_TLS:
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Type = ELF::STT_TLS;
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Type;
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer,
4506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                  uint32_t StringIndex, ELFSymbolData &MSD,
451115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
4526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
4536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSymbolELF *Base =
4546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
455152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // This has to be in sync with when computeSymbolTable uses SHN_ABS or
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // SHN_COMMON.
4586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool IsReserved = !Base || Symbol.isCommon();
4597be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
46077afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  // Binding and Type share the same byte as upper and lower nibbles
4616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint8_t Binding = Symbol.getBinding();
4626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint8_t Type = Symbol.getType();
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Base) {
4646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Type = mergeTypeForSet(Type, Base->getType());
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
4666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint8_t Info = (Binding << 4) | Type;
46777afbdce53aa740777486b0cc4e9df151ae65468Jack Carter
46872580780a98cb8b0019b7ec4ed88e3f3328b9969Joerg Sonnenberger  // Other and Visibility share the same byte with Visibility using the lower
46977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter  // 2 bits
4706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint8_t Visibility = Symbol.getVisibility();
4716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint8_t Other = Symbol.getOther() | Visibility;
472152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
4736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCExpr *ESize = MSD.Symbol->getSize();
47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!ESize && Base)
4786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    ESize = Base->getSize();
479f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
480f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  if (ESize) {
481f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    int64_t Res;
4820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (!ESize->evaluateKnownAbsolute(Res, Layout))
483f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola      report_fatal_error("Size expression must be absolute.");
484f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    Size = Res;
4853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
4863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
4886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
4896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     IsReserved);
4903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// It is always valid to create a relocation with a symbol. It is preferable
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// to use a relocation with a section if that is possible. Using the section
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// allows us to omit some local symbols from the symbol table.
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               const MCSymbolRefExpr *RefA,
4976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                               const MCSymbol *S, uint64_t C,
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                               unsigned Type) const {
4996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const auto *Sym = cast_or_null<MCSymbolELF>(S);
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // A PCRel relocation to an absolute value has no symbol (or section). We
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // represent that with a relocation to a null section.
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!RefA)
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
5047eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Kind) {
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The .odp creation emits a relocation against the symbol ".TOC." which
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // create a R_PPC64_TOC relocation. However the relocation symbol name
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // in final object creation should be NULL, since the symbol does not
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // really exist, it is just the reference to TOC base for the current
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // object file. Since the symbol is undefined, returning false results
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // in a relocation with a null section which is the desired result.
51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_PPC_TOCBASE:
51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
5177eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // These VariantKind cause the relocation to refer to something other than
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the symbol itself, like a linker generated table. Since the address of
52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // symbol is not relevant, we cannot replace the symbol with the
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // section and patch the difference in the addend.
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_GOT:
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_PLT:
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_GOTPCREL:
52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_Mips_GOT:
52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_PPC_GOT_LO:
52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_PPC_GOT_HI:
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCSymbolRefExpr::VK_PPC_GOT_HA:
52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
53025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
53125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // An undefined symbol is not in any section, so the relocation has to point
53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // to the symbol itself.
5346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(Sym && "Expected a symbol");
5356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Sym->isUndefined())
53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
5373729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
5386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Binding = Sym->getBinding();
53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch(Binding) {
54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Invalid Binding");
54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STB_LOCAL:
54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STB_WEAK:
54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // If the symbol is weak, it might be overridden by a symbol in another
54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // file. The relocation has to point to the symbol so that the linker
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // can update it.
54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::STB_GLOBAL:
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Global ELF symbols can be preempted by the dynamic linker. The relocation
55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // has to point to the symbol for a reason analogous to the STB_WEAK case.
55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
55394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
5543729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If a relocation points to a mergeable section, we have to be careful.
55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If the offset is zero, a relocation with the section will encode the
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // same information. With a non-zero offset, the situation is different.
55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // For example, a relocation can point 42 bytes past the end of a string.
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If we change such a relocation to use the section, the linker would think
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // that it pointed to another string and subtracting 42 at runtime will
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // produce the wrong value.
5626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  auto &Sec = cast<MCSectionELF>(Sym->getSection());
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Flags = Sec.getFlags();
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Flags & ELF::SHF_MERGE) {
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (C != 0)
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // It looks like gold has a bug (http://sourceware.org/PR16794) and can
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // only handle section relocations to mergeable sections if using RELA.
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!hasRelocationAddend())
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
5721f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
573c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Most TLS relocations use a got, so they need the symbol. Even those that
57537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // are just an offset (@tpoff), require a symbol in gold versions before
57637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
57737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // http://sourceware.org/PR16773.
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Flags & ELF::SHF_TLS)
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
580e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If the symbol is a thumb function the final relocation must set the lowest
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // bit. With a symbol that is done by just having the symbol have that bit
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // set, so we would lose the bit if we relocated with the section.
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: We could use the section but add the bit to the relocation value.
5856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Asm.isThumbFunc(Sym))
586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
59173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
59273ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
5936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// True if the assembler knows nothing about the final value of the symbol.
5946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This doesn't cover the comdat issues, since in those cases the assembler
5956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// can at least know that all symbols in the section will move together.
5966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic bool isWeak(const MCSymbolELF &Sym) {
5976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Sym.getType() == ELF::STT_GNU_IFUNC)
5986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return true;
599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
6006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  switch (Sym.getBinding()) {
6016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  default:
6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    llvm_unreachable("Unknown binding");
6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::STB_LOCAL:
6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return false;
6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::STB_GLOBAL:
6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return false;
6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::STB_WEAK:
6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::STB_GNU_UNIQUE:
6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return true;
6106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
6114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
6124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
6136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::recordRelocation(MCAssembler &Asm,
61456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCAsmLayout &Layout,
61556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFragment *Fragment,
616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       const MCFixup &Fixup, MCValue Target,
617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       bool &IsPCRel, uint64_t &FixedValue) {
6186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t C = Target.getConstant();
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           "Should not have constructed this");
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Let A, B and C being the components of Target and R be the location of
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // If it is pcrel, we want to compute (A - B + C - R).
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // In general, ELF has no relocations for -B. It can only represent (A + C)
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // or (A + C - R). If B = R + K and the relocation is not pcrel, we can
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // replace B to implement it: (A - R - K + C)
633cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (IsPCRel) {
634cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Asm.getContext().reportError(
63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Fixup.getLoc(),
63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          "No relocation available to represent this relative expression");
637cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return;
638cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
642cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (SymB.isUndefined()) {
643cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Asm.getContext().reportError(
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Fixup.getLoc(),
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Twine("symbol '") + SymB.getName() +
64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines              "' can not be undefined in a subtraction expression");
647cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return;
648cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(!SymB.isAbsolute() && "Should have been folded");
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSection &SecB = SymB.getSection();
652cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (&SecB != &FixupSection) {
653cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Asm.getContext().reportError(
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Fixup.getLoc(), "Cannot represent a difference across sections");
655cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return;
656cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
658cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (::isWeak(SymB)) {
659cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Asm.getContext().reportError(
6604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
661cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return;
662cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
6634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
6646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t K = SymBOffset - FixupOffset;
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsPCRel = true;
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    C -= K;
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
66956a399023aba6cf1348533df04732950c43eaca7Jason W Kim
67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We either rejected the fixup or folded B into C at this point.
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCSymbolRefExpr *RefA = Target.getSymA();
6726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
6736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool ViaWeakRef = false;
6756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (SymA && SymA->isVariable()) {
6766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCExpr *Expr = SymA->getVariableValue();
6776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
6786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
6796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        SymA = cast<MCSymbolELF>(&Inner->getSymbol());
6806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        ViaWeakRef = true;
6816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
6826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
6836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
68456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
6866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
6886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    C += Layout.getSymbolOffset(*SymA);
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Addend = 0;
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (hasRelocationAddend()) {
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addend = C;
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    C = 0;
69456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  }
69556a399023aba6cf1348533df04732950c43eaca7Jason W Kim
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FixedValue = C;
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!RelocateWithSymbol) {
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSection *SecA =
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
70137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *ELFSec = cast_or_null<MCSectionELF>(SecA);
7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const auto *SectionSymbol =
7036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        ELFSec ? cast<MCSymbolELF>(ELFSec->getBeginSymbol()) : nullptr;
7046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (SectionSymbol)
7056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SectionSymbol->setUsedInReloc();
70637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend);
7076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Relocations[&FixupSection].push_back(Rec);
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7102a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SymA) {
7126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (const MCSymbolELF *R = Renames.lookup(SymA))
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SymA = R;
714bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
7156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (ViaWeakRef)
7166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SymA->setIsWeakrefUsedInReloc();
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
7186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SymA->setUsedInReloc();
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend);
7216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Relocations[&FixupSection].push_back(Rec);
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return;
72356a399023aba6cf1348533df04732950c43eaca7Jason W Kim}
72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout,
7266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                 const MCSymbolELF &Symbol, bool Used,
727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 bool Renamed) {
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Symbol.isVariable()) {
72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Expr = Symbol.getVariableValue();
73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
735484291c27319668ad99cb87def000254357736fbRafael Espindola
736bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
737bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
738bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
73988182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
74088182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
74188182132470527e27231f09b25a885893e528c66Rafael Espindola
7426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Symbol.isVariable() && Symbol.isUndefined()) {
7436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // FIXME: this is here just to diagnose the case of a var = commmon_sym.
7446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Layout.getBaseSymbol(Symbol);
7456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return false;
746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
74721451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola
7486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Symbol.isUndefined() && !Symbol.isBindingSet())
749a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
750a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
751bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
752737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
753737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
7546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Symbol.getType() == ELF::STT_SECTION)
755737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
756737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
757737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
758737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
759737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
7600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarvoid ELFObjectWriter::computeSymbolTable(
7610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    MCAssembler &Asm, const MCAsmLayout &Layout,
7626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
7636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SectionOffsetsTy &SectionOffsets) {
7646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCContext &Ctx = Asm.getContext();
7656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SymbolTableWriter Writer(*this, is64Bit());
7665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
7676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Symbol table
7686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
7696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSectionELF *SymtabSection =
7706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
7716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SymtabSection->setAlignment(is64Bit() ? 8 : 4);
7726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SymbolTableIndex = addToSectionTable(SymtabSection);
7736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
7746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  align(SymtabSection->getAlignment());
775cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  uint64_t SecStart = getStream().tell();
7763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // The first entry is the undefined symbol entry.
7786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
7791f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
7806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::vector<ELFSymbolData> LocalSymbolData;
7816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::vector<ELFSymbolData> ExternalSymbolData;
7826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
7836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Add the data for the symbols.
7846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool HasLargeSectionIndex = false;
7856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const MCSymbol &S : Asm.symbols()) {
7866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const auto &Symbol = cast<MCSymbolELF>(S);
7876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool Used = Symbol.isUsedInReloc();
7886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
7896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool isSignature = Symbol.isSignature();
7906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
7916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
79288182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
7933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
7943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
795cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (Symbol.isTemporary() && Symbol.isUndefined()) {
796cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Ctx.reportError(SMLoc(), "Undefined temporary symbol");
797cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      continue;
798cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
799cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
8003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
8016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MSD.Symbol = cast<MCSymbolELF>(&Symbol);
8021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
804cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(Local || !Symbol.isTemporary());
805cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
8066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Symbol.isAbsolute()) {
80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MSD.SectionIndex = ELF::SHN_ABS;
8086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    } else if (Symbol.isCommon()) {
809a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
810f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
8116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    } else if (Symbol.isUndefined()) {
8126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (isSignature && !Used) {
8136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
8146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
8156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          HasLargeSectionIndex = true;
8166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      } else {
8171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
8186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
8193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
820bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
8216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          static_cast<const MCSectionELF &>(Symbol.getSection());
822bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
8233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
8246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
8256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        HasLargeSectionIndex = true;
8265df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
8275df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
828ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // The @@@ in symbol version is replaced with @ in undefined symbols and @@
829ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // in defined ones.
830ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    //
831ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // FIXME: All name handling should be done before we get to the writer,
832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // including dealing with GNU-style version suffixes.  Fixing this isn't
833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // trivial.
834ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    //
835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // We thus have to be careful to not perform the symbol version replacement
836ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // blindly:
837ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    //
838ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // The ELF format is used on Windows by the MCJIT engine.  Thus, on
839ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
840ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC
841ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // C++ name mangling can legally have "@@@" as a sub-string. In that case,
842ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // the EFLObjectWriter should not interpret the "@@@" sub-string as
843ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // specifying GNU-style symbol versioning. The ELFObjectWriter therefore
844ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // checks for the MSVC C++ name mangling prefix which is either "?", "@?",
845ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // "__imp_?" or "__imp_@?".
846ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    //
847ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // It would have been interesting to perform the MS mangling prefix check
848ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // only when the target triple is of the form *-pc-windows-elf. But, it
849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // seems that this information is not easily accessible from the
850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // ELFObjectWriter.
85188182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
852cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    SmallString<32> Buf;
853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!Name.startswith("?") && !Name.startswith("@?") &&
854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // This symbol isn't following the MSVC C++ name mangling convention. We
856ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // can thus safely interpret the @@@ in symbol names as specifying symbol
857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // versioning.
858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      size_t Pos = Name.find("@@@");
859ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (Pos != StringRef::npos) {
860ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Buf += Name.substr(0, Pos);
861ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
862ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Buf += Name.substr(Pos + Skip);
863cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        Name = VersionSymSaver.save(Buf.c_str());
864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
86588182132470527e27231f09b25a885893e528c66Rafael Espindola    }
86637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
86737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Sections have their own string table
868cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (Symbol.getType() != ELF::STT_SECTION) {
869cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      MSD.Name = Name;
870cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      StrTabBuilder.add(Name);
871cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
87288182132470527e27231f09b25a885893e528c66Rafael Espindola
8736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Local)
874a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
875a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
876a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
879cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // This holds the .symtab_shndx section index.
880cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  unsigned SymtabShndxSectionIndex = 0;
881cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
8826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (HasLargeSectionIndex) {
8836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSectionELF *SymtabShndxSection =
8846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
8856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
8866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SymtabShndxSection->setAlignment(4);
8876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
8896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ArrayRef<std::string> FileNames = Asm.getFileNames();
8906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const std::string &Name : FileNames)
8916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    StrTabBuilder.add(Name);
892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
893cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  StrTabBuilder.finalize();
894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
8956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const std::string &Name : FileNames)
8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Writer.writeSymbol(StrTabBuilder.getOffset(Name),
8976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                       ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
8986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                       ELF::SHN_ABS, true);
899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
9003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
9013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
9023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
9033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
9053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Index = FileNames.size() + 1;
9076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
9086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (ELFSymbolData &MSD : LocalSymbolData) {
9096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
9106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                               ? 0
9116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                               : StrTabBuilder.getOffset(MSD.Name);
9126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MSD.Symbol->setIndex(Index++);
9136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeSymbol(Writer, StringIndex, MSD, Layout);
9146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
9156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
9166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Write the symbol table entries.
9176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LastLocalSymbolIndex = Index;
9186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
9196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (ELFSymbolData &MSD : ExternalSymbolData) {
9206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
9216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MSD.Symbol->setIndex(Index++);
9226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeSymbol(Writer, StringIndex, MSD, Layout);
9236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
9246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
9256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
926cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  uint64_t SecEnd = getStream().tell();
9276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
9286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
9296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
9306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (ShndxIndexes.empty()) {
9316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(SymtabShndxSectionIndex == 0);
9326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return;
9336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
9346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(SymtabShndxSectionIndex != 0);
9356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
936cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SecStart = getStream().tell();
9376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSectionELF *SymtabShndxSection =
9386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SectionTable[SymtabShndxSectionIndex - 1];
9396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (uint32_t Index : ShndxIndexes)
9406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(Index);
941cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SecEnd = getStream().tell();
9426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
9433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
9443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMCSectionELF *
9466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarELFObjectWriter::createRelocationSection(MCContext &Ctx,
9476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         const MCSectionELF &Sec) {
9486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Relocations[&Sec].empty())
949ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return nullptr;
9503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const StringRef SectionName = Sec.getSectionName();
952ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
953ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  RelaSectionName += SectionName;
9543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
955ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned EntrySize;
956ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (hasRelocationAddend())
957ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
958ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
959ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
960f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover
961ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned Flags = 0;
9626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Sec.getFlags() & ELF::SHF_GROUP)
963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Flags = ELF::SHF_GROUP;
964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
9656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSectionELF *RelaSection = Ctx.createELFRelSection(
966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
9676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Flags, EntrySize, Sec.getGroup(), &Sec);
9686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  RelaSection->setAlignment(is64Bit() ? 8 : 4);
9696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return RelaSection;
9707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
9717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Include the debug info compression header:
973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// useful for consumers to preallocate a buffer to decompress into.
975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool
976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesprependCompressionHeader(uint64_t Size,
977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         SmallVectorImpl<char> &CompressedContents) {
9784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  const StringRef Magic = "ZLIB";
979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (sys::IsLittleEndianHost)
982c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    sys::swapByteOrder(Size);
983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  CompressedContents.insert(CompressedContents.begin(),
984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            Magic.size() + sizeof(Size), 0);
985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::copy(Magic.begin(), Magic.end(), CompressedContents.begin());
986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::copy(reinterpret_cast<char *>(&Size),
987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            reinterpret_cast<char *>(&Size + 1),
988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            CompressedContents.begin() + Magic.size());
989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
9926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
9936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                       const MCAsmLayout &Layout) {
9946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
9956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  StringRef SectionName = Section.getSectionName();
996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
9976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Compressing debug_frame requires handling alignment fragments which is
9986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
9996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // for writing to arbitrary buffers) for little benefit.
10006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!Asm.getContext().getAsmInfo()->compressDebugSections() ||
10016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      !SectionName.startswith(".debug_") || SectionName == ".debug_frame") {
10026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Asm.writeSectionData(&Section, Layout);
10036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return;
10046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
10056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1006cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SmallVector<char, 128> UncompressedData;
1007cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  raw_svector_ostream VecOS(UncompressedData);
1008cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  raw_pwrite_stream &OldStream = getStream();
1009cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  setStream(VecOS);
1010cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Asm.writeSectionData(&Section, Layout);
1011cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  setStream(OldStream);
1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
10136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SmallVector<char, 128> CompressedContents;
1014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  zlib::Status Success = zlib::compress(
1015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      StringRef(UncompressedData.data(), UncompressedData.size()),
1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CompressedContents);
10176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Success != zlib::StatusOK) {
1018cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    getStream() << UncompressedData;
10196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return;
1020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
10226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) {
1023cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    getStream() << UncompressedData;
1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
10256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Asm.getContext().renameELFSection(&Section,
1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    (".z" + SectionName.drop_front(1)).str());
1028cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  getStream() << CompressedContents;
10293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1031115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
1032115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
1033115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
1034115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
1035115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
1036115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
10376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write32(Name);        // sh_name: index into string table
10386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write32(Type);        // sh_type
10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
10436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write32(Link);        // sh_link
10446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  write32(Info);        // sh_info
10453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
10463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
10473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
10506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                       const MCSectionELF &Sec) {
10516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec];
105200ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka
1053cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // We record relocations by pushing to the end of a vector. Reverse the vector
1054cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // to get the relocations in the order they were created.
1055cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // In most cases that is not important, but it can be for special sections
1056cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
1057cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::reverse(Relocs.begin(), Relocs.end());
1058cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
1059cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Sort the relocation entries. MIPS needs this.
10600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  TargetObjectWriter->sortRelocs(Asm, Relocs);
10613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const ELFRelocationEntry &Entry = Relocs[e - i - 1];
10646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
10653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1066bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit()) {
10676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      write(Entry.Offset);
106893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      if (TargetObjectWriter->isN64()) {
10696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(uint32_t(Index));
10705e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(TargetObjectWriter->getRSsym(Entry.Type));
10726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(TargetObjectWriter->getRType3(Entry.Type));
10736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(TargetObjectWriter->getRType2(Entry.Type));
10746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(TargetObjectWriter->getRType(Entry.Type));
107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else {
107693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter        struct ELF::Elf64_Rela ERE64;
107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ERE64.setSymbolAndType(Index, Entry.Type);
10786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(ERE64.r_info);
107993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter      }
1080bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
10816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(Entry.Addend);
10825e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
10836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      write(uint32_t(Entry.Offset));
10845e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10858f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
108636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ERE32.setSymbolAndType(Index, Entry.Type);
10876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      write(ERE32.r_info);
10885e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1089bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
10906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        write(uint32_t(Entry.Addend));
10915e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
10923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarconst MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
10966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
1097cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  getStream() << StrTabBuilder.data();
10986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return StrtabSection;
10992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
11002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
11016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
11026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                   uint32_t GroupSymbolIndex, uint64_t Offset,
11036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                   uint64_t Size, const MCSectionELF &Section) {
1104c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
1105c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
1106c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1107c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
11080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  default:
11090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    // Nothing to do.
11100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    break;
11110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1112c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
11136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1114c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1115c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
1116c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
1117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    sh_link = SymbolTableIndex;
1118c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
11190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const MCSectionELF *InfoSection = Section.getAssociatedSection();
1120c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
1121c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1122c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1123c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1124c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
1125c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
1126c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
1127c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
1128c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1129c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1130c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
1131c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
1132c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1133c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
11344a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky  case ELF::SHT_GROUP:
11352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
11362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
11372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
1138c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1139c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1140b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien  if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
11410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      Section.getType() == ELF::SHT_ARM_EXIDX)
11420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
1143b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien
11446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
11456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                   Section.getType(), Section.getFlags(), 0, Offset, Size,
11466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                   sh_link, sh_info, Section.getAlignment(),
11476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                   Section.getEntrySize());
11487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
11497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
1150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ELFObjectWriter::writeSectionHeader(
11516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
11526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const SectionOffsetsTy &SectionOffsets) {
11536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const unsigned NumSections = SectionTable.size();
11547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Null section first.
11567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FirstSectionSize =
11570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
11586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const MCSectionELF *Section : SectionTable) {
11617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint32_t GroupSymbolIndex;
11626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    unsigned Type = Section->getType();
11636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Type != ELF::SHT_GROUP)
11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = 0;
11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    else
11666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      GroupSymbolIndex = Section->getGroup()->getIndex();
11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const std::pair<uint64_t, uint64_t> &Offsets =
11696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        SectionOffsets.find(Section)->second;
11706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint64_t Size;
11716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Type == ELF::SHT_NOBITS)
11726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Size = Layout.getSectionAddressSize(Section);
11736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else
11746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Size = Offsets.second - Offsets.first;
11757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
11776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                 *Section);
11786db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
11796db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
11806db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
11816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeObject(MCAssembler &Asm,
1182115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
11836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCContext &Ctx = Asm.getContext();
11846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSectionELF *StrtabSection =
11856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
11866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  StringTableIndex = addToSectionTable(StrtabSection);
11876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
11881f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
1189bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1190bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
11916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1192bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
11936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Write out the ELF header ...
11946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  writeHeader(Asm);
11956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
11966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // ... then the sections ...
11976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SectionOffsetsTy SectionOffsets;
11986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::vector<MCSectionELF *> Groups;
11996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::vector<MCSectionELF *> Relocations;
12006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (MCSection &Sec : Asm) {
12016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
12027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
12036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    align(Section.getAlignment());
12048f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
12056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Remember the offset into the file for this section.
1206cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecStart = getStream().tell();
12071d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
12086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCSymbolELF *SignatureSymbol = Section.getGroup();
12096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeSectionData(Asm, Section, Layout);
12103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1211cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecEnd = getStream().tell();
12126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
12137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
12146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
12153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (SignatureSymbol) {
12176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Asm.registerSymbol(*SignatureSymbol);
12186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
12196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (!GroupIdx) {
12206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
12216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        GroupIdx = addToSectionTable(Group);
12226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Group->setAlignment(4);
12236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Groups.push_back(Group);
12246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
12256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      std::vector<const MCSectionELF *> &Members =
12266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          GroupMembers[SignatureSymbol];
12276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Members.push_back(&Section);
12286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (RelSection)
12296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Members.push_back(RelSection);
12306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
12313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SectionIndexMap[&Section] = addToSectionTable(&Section);
12336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (RelSection) {
12346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SectionIndexMap[RelSection] = addToSectionTable(RelSection);
12356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Relocations.push_back(RelSection);
12366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
12376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
12386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (MCSectionELF *Group : Groups) {
12406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    align(Group->getAlignment());
12416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Remember the offset into the file for this section.
1243cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecStart = getStream().tell();
12446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCSymbol *SignatureSymbol = Group->getGroup();
12466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(SignatureSymbol);
12476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    write(uint32_t(ELF::GRP_COMDAT));
12486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
12496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      uint32_t SecIndex = SectionIndexMap.lookup(Member);
12506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      write(SecIndex);
12516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
12526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1253cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecEnd = getStream().tell();
12546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
12556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
12566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Compute symbol table information.
12586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets);
12596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (MCSectionELF *RelSection : Relocations) {
12616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    align(RelSection->getAlignment());
1262a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
12633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
1264cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecStart = getStream().tell();
12656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeRelocations(Asm, *RelSection->getAssociatedSection());
12676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1268cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecEnd = getStream().tell();
12696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
12706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
127144cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
12726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  {
1273cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecStart = getStream().tell();
12746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCSectionELF *Sec = createStringTable(Ctx);
1275cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SecEnd = getStream().tell();
12766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
12773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
12783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
12806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  align(NaturalAlignment);
1281a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
1282cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const unsigned SectionHeaderOffset = getStream().tell();
12830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
12847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the section header table ...
12856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
12866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
12876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE)
12886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                             ? (uint16_t)ELF::SHN_UNDEF
12896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                             : SectionTable.size() + 1;
12906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (sys::IsLittleEndianHost != IsLittleEndian)
12916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    sys::swapByteOrder(NumSections);
12926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned NumSectionsOffset;
12933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (is64Bit()) {
12950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint64_t Val = SectionHeaderOffset;
12960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (sys::IsLittleEndianHost != IsLittleEndian)
12970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(Val);
1298cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1299cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                       offsetof(ELF::Elf64_Ehdr, e_shoff));
13006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
13010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
13020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t Val = SectionHeaderOffset;
13030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (sys::IsLittleEndianHost != IsLittleEndian)
13040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(Val);
1305cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1306cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                       offsetof(ELF::Elf32_Ehdr, e_shoff));
13076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
13080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
1309cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  getStream().pwrite(reinterpret_cast<char *>(&NumSections),
1310cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                     sizeof(NumSections), NumSectionsOffset);
13113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
13123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
13146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
13156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    bool InSet, bool IsPCRel) const {
13166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const auto &SymA = cast<MCSymbolELF>(SA);
13176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (IsPCRel) {
13186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(!InSet);
13196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (::isWeak(SymA))
13206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return false;
13216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
13226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
13236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                                InSet, IsPCRel);
132478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman}
132578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman
13266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool ELFObjectWriter::isWeak(const MCSymbol &S) const {
13276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const auto &Sym = cast<MCSymbolELF>(S);
13286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (::isWeak(Sym))
13296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return true;
13306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
13316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // It is invalid to replace a reference to a global in a comdat
13326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // with a reference to a local since out of comdat references
13336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // to a local are forbidden.
13346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // We could try to return false for more cases, like the reference
13356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // being in the same comdat or Sym being an alias to another global,
13366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // but it is not clear if it is worth the effort.
13376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Sym.getBinding() != ELF::STB_GLOBAL)
13386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return false;
13396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
13406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!Sym.isInSection())
13416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return false;
13426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
13436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const auto &Sec = cast<MCSectionELF>(Sym.getSection());
13446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return Sec.getGroup();
13454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
13464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
13476024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
13480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                            raw_pwrite_stream &OS,
1349bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                            bool IsLittleEndian) {
13507bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola  return new ELFObjectWriter(MOTW, OS, IsLittleEndian);
1351edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola}
1352