ELFObjectWriter.cpp revision dff84b03258514463ede477af38f1246b95b0cd0
13565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//                     The LLVM Compiler Infrastructure
43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source
63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details.
73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file implements ELF object file writer information.
113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
148f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola#include "llvm/ADT/SmallPtrSet.h"
153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/STLExtras.h"
163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h"
173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/Twine.h"
183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAssembler.h"
193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h"
203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCELFSymbolFlags.h"
223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCObjectWriter.h"
243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSymbol.h"
263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h"
273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h"
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h"
313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "../Target/X86/X86FixupKinds.h"
334a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim#include "../Target/ARM/ARMFixupKinds.h"
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
38ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindolastatic unsigned GetType(const MCSymbolData &SD) {
39ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola  uint32_t Type = (SD.getFlags() & (0xf << ELF_STT_Shift)) >> ELF_STT_Shift;
40ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola  assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
41ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola         Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
42ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola         Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
43ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola         Type == ELF::STT_TLS);
44ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola  return Type;
45ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola}
46ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola
47e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindolastatic unsigned GetBinding(const MCSymbolData &SD) {
48e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift;
49e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
50e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola         Binding == ELF::STB_WEAK);
51e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  return Binding;
52e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola}
53e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola
54e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindolastatic void SetBinding(MCSymbolData &SD, unsigned Binding) {
55e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL ||
56e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola         Binding == ELF::STB_WEAK);
57e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift);
58e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola  SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift));
59e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola}
60e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola
61152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindolastatic unsigned GetVisibility(MCSymbolData &SD) {
62152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  unsigned Visibility =
63152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola    (SD.getFlags() & (0xf << ELF_STV_Shift)) >> ELF_STV_Shift;
64152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
65152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
66152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  return Visibility;
67152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola}
68152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
694b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
70a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindolastatic bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
71a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  switch (Variant) {
725c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  default:
735c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    return false;
74a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOT:
75a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_PLT:
76a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOTPCREL:
77a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_TPOFF:
78a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_TLSGD:
79a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOTTPOFF:
80a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_INDNTPOFF:
81a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_NTPOFF:
82a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  case MCSymbolRefExpr::VK_GOTNTPOFF:
83a264f72d3fb9dec1427480fcf17ef3c746ea723aRafael Espindola  case MCSymbolRefExpr::VK_TLSLDM:
840cf15d61b7e3bf53f5a99f58ada37b93bc039559Rafael Espindola  case MCSymbolRefExpr::VK_DTPOFF:
85b4d1721eff7b43577e5f2e53f885973fb6c43683Rafael Espindola  case MCSymbolRefExpr::VK_TLSLD:
865c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    return true;
875c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
885c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola}
895c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
903565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingnamespace {
91115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  class ELFObjectWriter : public MCObjectWriter {
92d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  protected:
93b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner    /*static bool isFixupKindX86RIPRel(unsigned Kind) {
943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      return Kind == X86::reloc_riprel_4byte ||
953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming        Kind == X86::reloc_riprel_4byte_movq_load;
96b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner    }*/
973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// ELFSymbolData - Helper struct for containing some precomputed information
1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// on symbols.
1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    struct ELFSymbolData {
1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      MCSymbolData *SymbolData;
1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint64_t StringIndex;
1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint32_t SectionIndex;
1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      // Support lexicographic sorting.
1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      bool operator<(const ELFSymbolData &RHS) const {
108ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola        if (GetType(*SymbolData) == ELF::STT_FILE)
109ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola          return true;
110ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola        if (GetType(*RHS.SymbolData) == ELF::STT_FILE)
111ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola          return false;
11236c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer        return SymbolData->getSymbol().getName() <
11336c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer               RHS.SymbolData->getSymbol().getName();
1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    };
1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @name Relocation Data
1183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @{
1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    struct ELFRelocationEntry {
1213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      // Make these big enough for both 32-bit and 64-bit
1223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint64_t r_offset;
1238f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      int Index;
1248f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      unsigned Type;
1258f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      const MCSymbol *Symbol;
1263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      uint64_t r_addend;
127858e7506e1fabe563eb4222c80ad0fad01641becJason W Kim
1284a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      ELFRelocationEntry()
1294a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
1304a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim
13110907426893019c6b7e59c886e41815d4fe50b19Jason W Kim      ELFRelocationEntry(uint64_t RelocOffset, int Idx,
13210907426893019c6b7e59c886e41815d4fe50b19Jason W Kim                         unsigned RelType, const MCSymbol *Sym,
1334a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim                         uint64_t Addend)
13410907426893019c6b7e59c886e41815d4fe50b19Jason W Kim        : r_offset(RelocOffset), Index(Idx), Type(RelType),
13510907426893019c6b7e59c886e41815d4fe50b19Jason W Kim          Symbol(Sym), r_addend(Addend) {}
1363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      // Support lexicographic sorting.
1383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      bool operator<(const ELFRelocationEntry &RE) const {
1393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming        return RE.r_offset < r_offset;
1403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
1413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    };
1423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1438f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
144484291c27319668ad99cb87def000254357736fbRafael Espindola    SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
14588182132470527e27231f09b25a885893e528c66Rafael Espindola    DenseMap<const MCSymbol *, const MCSymbol *> Renames;
1468f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
1473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    llvm::DenseMap<const MCSectionData*,
1483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                   std::vector<ELFRelocationEntry> > Relocations;
1493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
1503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @}
1523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @name Symbol Table Data
1533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @{
1543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    SmallString<256> StringTable;
1563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    std::vector<ELFSymbolData> LocalSymbolData;
1573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    std::vector<ELFSymbolData> ExternalSymbolData;
1583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    std::vector<ELFSymbolData> UndefinedSymbolData;
1593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// @}
1613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    bool NeedsGOT;
1635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
1647be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    bool NeedsSymtabShndx;
1657be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
1663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned Is64Bit : 1;
1673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    bool HasRelocationAddend;
1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1705baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    Triple::OSType OSType;
1715baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky
172eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck    uint16_t EMachine;
173eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck
1743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // This holds the symbol table index of the last local symbol.
1753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned LastLocalSymbolIndex;
1763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // This holds the .strtab section index.
1773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned StringTableIndex;
1787be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    // This holds the .symtab section index.
1797be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    unsigned SymbolTableIndex;
1803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    unsigned ShstrtabIndex;
1823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1831f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
1841f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola    const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
1851f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                  const MCValue &Target,
1861f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                  const MCFragment &F) const;
1871f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
1883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  public:
189115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar    ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
190115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                    uint16_t _EMachine, bool _HasRelAddend,
191115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                    Triple::OSType _OSType)
192115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      : MCObjectWriter(_OS, IsLittleEndian),
193115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar        NeedsGOT(false), NeedsSymtabShndx(false),
1945baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky        Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend),
195eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck        OSType(_OSType), EMachine(_EMachine) {
1963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
197d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
198d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual ~ELFObjectWriter();
199d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
2003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void WriteWord(uint64_t W) {
201b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner      if (Is64Bit)
202115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar        Write64(W);
203b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner      else
204115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar        Write32(W);
2053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringLE16(char *buf, uint16_t Value) {
2083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[0] = char(Value >> 0);
2093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[1] = char(Value >> 8);
2103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringLE32(char *buf, uint32_t Value) {
21336c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringLE16(buf, uint16_t(Value >> 0));
214c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringLE16(buf + 2, uint16_t(Value >> 16));
2153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringLE64(char *buf, uint64_t Value) {
21836c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringLE32(buf, uint32_t(Value >> 0));
219c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringLE32(buf + 4, uint32_t(Value >> 32));
2203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringBE16(char *buf ,uint16_t Value) {
2233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[0] = char(Value >> 8);
2243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      buf[1] = char(Value >> 0);
2253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringBE32(char *buf, uint32_t Value) {
22836c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringBE16(buf, uint16_t(Value >> 16));
229c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringBE16(buf + 2, uint16_t(Value >> 0));
2303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    void StringBE64(char *buf, uint64_t Value) {
23336c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer      StringBE32(buf, uint32_t(Value >> 32));
234c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer      StringBE32(buf + 4, uint32_t(Value >> 0));
2353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
237af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String8(MCDataFragment &F, uint8_t Value) {
238af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[1];
239af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      buf[0] = Value;
240af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 1);
241af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    }
242af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola
243af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String16(MCDataFragment &F, uint16_t Value) {
244af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[2];
245115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      if (isLittleEndian())
246f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringLE16(buf, Value);
2473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      else
248f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringBE16(buf, Value);
249af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 2);
2503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
252af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String32(MCDataFragment &F, uint32_t Value) {
253af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[4];
254115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      if (isLittleEndian())
255f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringLE32(buf, Value);
2563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      else
257f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringBE32(buf, Value);
258af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 4);
2593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
261af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    void String64(MCDataFragment &F, uint64_t Value) {
262af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      char buf[8];
263115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar      if (isLittleEndian())
264f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringLE64(buf, Value);
2653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      else
266f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman        StringBE64(buf, Value);
267af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      F.getContents() += StringRef(buf, 8);
2683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
2693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
270d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections);
2713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
272d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
2737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          uint64_t name, uint8_t info,
2743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t value, uint64_t size,
2757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          uint8_t other, uint32_t shndx,
2767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          bool Reserved);
2773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
278d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSymbol(MCDataFragment *SymtabF,  MCDataFragment *ShndxF,
2797be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                     ELFSymbolData &MSD,
2803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                     const MCAsmLayout &Layout);
2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
282bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
283d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
2847be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                          const MCAssembler &Asm,
28571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola                          const MCAsmLayout &Layout,
2864beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                          const SectionIndexMapTy &SectionIndexMap);
2873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
288d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
2893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          const MCFragment *Fragment, const MCFixup &Fixup,
290d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  MCValue Target, uint64_t &FixedValue) {
291d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      assert(0 && "RecordRelocation is not specific enough");
2923285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer    }
2933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
294d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
2950b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Kramer                                         const MCSymbol *S);
2963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Map from a group section to the signature symbol
2981f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
2991f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Map from a signature symbol to the group section
3001f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
3011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// ComputeSymbolTable - Compute the symbol table data
3033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ///
3043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// \param StringTable [out] - The string table data.
3053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// \param StringIndexMap [out] - Map from symbol names to offsets in the
3063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    /// string table.
307d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void ComputeSymbolTable(MCAssembler &Asm,
3081f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                            const SectionIndexMapTy &SectionIndexMap,
3091f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                            RevGroupMapTy RevGroupMap);
310bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
311d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void ComputeIndexMap(MCAssembler &Asm,
312bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola                         SectionIndexMapTy &SectionIndexMap);
3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
314d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
3153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                         const MCSectionData &SD);
3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
317d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) {
3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      for (MCAssembler::const_iterator it = Asm.begin(),
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming             ie = Asm.end(); it != ie; ++it) {
3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming        WriteRelocation(Asm, Layout, *it);
3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
324d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
3254beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                const SectionIndexMapTy &SectionIndexMap);
3263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
327d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout,
3281f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                             GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap);
3292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
330d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void ExecutePostLayoutBinding(MCAssembler &Asm);
3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
332d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
3333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t Address, uint64_t Offset,
3343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t Size, uint32_t Link, uint32_t Info,
3353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                          uint64_t Alignment, uint64_t EntrySize);
3363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
337d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F,
3383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                  const MCSectionData *SD);
3393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
340d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
3417070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola                              const MCValue Target,
3427070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola                              bool IsPCRel,
3437070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola                              const MCFragment *DF) const;
3447070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
345d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
346d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void WriteSection(MCAssembler &Asm,
347c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                      const SectionIndexMapTy &SectionIndexMap,
3482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      uint32_t GroupSymbolIndex,
349c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                      uint64_t Offset, uint64_t Size, uint64_t Alignment,
350c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                      const MCSectionELF &Section);
3513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  };
3523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
353d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  //===- X86ELFObjectWriter -------------------------------------------===//
354d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
355d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  class X86ELFObjectWriter : public ELFObjectWriter {
356d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  public:
357d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
358d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                       uint16_t _EMachine, bool _HasRelAddend,
359d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                       Triple::OSType _OSType);
3604b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
361d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual ~X86ELFObjectWriter();
362d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void RecordRelocation(const MCAssembler &Asm,
363d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  const MCAsmLayout &Layout,
364d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  const MCFragment *Fragment,
365d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  const MCFixup &Fixup, MCValue Target,
366d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  uint64_t &FixedValue);
3674a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim
36828ef0a5719c41ed9654156aa9db7a656d020d7b5Jason W Kim  private:
3694a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    static bool isFixupKindPCRel(unsigned Kind) {
3704a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      switch (Kind) {
3714a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      default:
3724a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        return false;
373e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
374e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_2:
375e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
3764a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      case X86::reloc_riprel_4byte:
3774a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      case X86::reloc_riprel_4byte_movq_load:
3784a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        return true;
3794a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      }
3804a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    }
381d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  };
382d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
383d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
384d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  //===- ARMELFObjectWriter -------------------------------------------===//
385d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
386d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  class ARMELFObjectWriter : public ELFObjectWriter {
387d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  public:
388d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
389d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                       uint16_t _EMachine, bool _HasRelAddend,
390d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                       Triple::OSType _OSType);
3914b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
392d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual ~ARMELFObjectWriter();
393d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    virtual void RecordRelocation(const MCAssembler &Asm,
394d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  const MCAsmLayout &Layout,
395d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  const MCFragment *Fragment,
396d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  const MCFixup &Fixup, MCValue Target,
397d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                  uint64_t &FixedValue);
3984a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim
39985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  protected:
40085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    // Fixme: pull up to ELFObjectWriter
40185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
40285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim                          bool IsPCRel);
40328ef0a5719c41ed9654156aa9db7a656d020d7b5Jason W Kim  private:
4044a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    static bool isFixupKindPCRel(unsigned Kind) {
4054a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      switch (Kind) {
4064a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      default:
4074a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        return false;
408e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
409e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_2:
410e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
411dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach      case ARM::fixup_arm_ldst_pcrel_12:
4129d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson      case ARM::fixup_arm_pcrel_10:
413ccbe000e093e53979056ba091291f4427c54bd99Jason W Kim      case ARM::fixup_arm_branch:
4144a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        return true;
4154a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      }
4164a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    }
417d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  };
4184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
4194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  //===- MBlazeELFObjectWriter -------------------------------------------===//
4204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
4214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  class MBlazeELFObjectWriter : public ELFObjectWriter {
4224b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  public:
4234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
4244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                          uint16_t _EMachine, bool _HasRelAddend,
4254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                          Triple::OSType _OSType);
4264b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
4274b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    virtual ~MBlazeELFObjectWriter();
4284b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    virtual void RecordRelocation(const MCAssembler &Asm,
4294b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                  const MCAsmLayout &Layout,
4304b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                  const MCFragment *Fragment,
4314b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                  const MCFixup &Fixup, MCValue Target,
4324b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                  uint64_t &FixedValue);
4334a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim
43428ef0a5719c41ed9654156aa9db7a656d020d7b5Jason W Kim  private:
4354a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    static bool isFixupKindPCRel(unsigned Kind) {
4364a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      switch (Kind) {
4374a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      default:
4384a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        return false;
439e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
440e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_2:
441e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
4424a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim        return true;
4434a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim      }
4444a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    }
4454b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  };
4463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
448d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
449d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
450d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
4513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
452115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
453115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  unsigned NumberOfSections) {
4543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
4553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
4563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
4573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
4583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
4593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
4603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0x7f); // e_ident[EI_MAG0]
4633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('E');  // e_ident[EI_MAG1]
4643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('L');  // e_ident[EI_MAG2]
4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('F');  // e_ident[EI_MAG3]
4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
470115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
4713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
4735baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
4745baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  switch (OSType) {
4755baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    case Triple::FreeBSD:  Write8(ELF::ELFOSABI_FREEBSD); break;
4765baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    case Triple::Linux:    Write8(ELF::ELFOSABI_LINUX); break;
4775baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    default:               Write8(ELF::ELFOSABI_NONE); break;
4785baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  }
4793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0);                  // e_ident[EI_ABIVERSION]
4803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
4823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(ELF::ET_REL);             // e_type
4843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
485eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck  Write16(EMachine); // e_machine = target
4863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(ELF::EV_CURRENT);         // e_version
4883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
4893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
490eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer  WriteWord(SectionDataSize + (Is64Bit ? sizeof(ELF::Elf64_Ehdr) :
491eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
4923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make this configurable.
4943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(0);   // e_flags = whatever the target wants
4953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
4973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(Is64Bit ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
4983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phentsize = prog header entry size
5003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phnum = # prog header entries = 0
5013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
5033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(Is64Bit ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
5043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
5067be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
5077be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(0);
5087be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
5097be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(NumberOfSections);
5103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
5127be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
5137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ELF::SHN_XINDEX);
5147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
5157be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ShstrtabIndex);
5163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
518115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
519115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
520115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t name,
521115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint8_t info, uint64_t value,
522115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t size, uint8_t other,
523115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t shndx,
524115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       bool Reserved) {
5257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (ShndxF) {
5267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
527af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, shndx);
5287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    else
529af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, 0);
5307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
5317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
532af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
533af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    uint16_t(ELF::SHN_XINDEX) : shndx;
5343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
535af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  if (Is64Bit) {
536af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
537af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
538af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
539af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
540af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, value); // st_value
541af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, size);  // st_size
5423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
543af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
544af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, value); // st_value
545af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, size);  // st_size
546af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
547af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
548af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
5493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
5503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
5513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5522c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindolastatic uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) {
5532c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (Data.isCommon() && Data.isExternal())
5542c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return Data.getCommonAlignment();
5552c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
5562c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
5572c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (!Symbol.isInSection())
5582c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return 0;
5592c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
5601973d4379250a88938a9358c12d96e96bdc8dedeRafael Espindola  if (MCFragment *FF = Data.getFragment())
5611973d4379250a88938a9358c12d96e96bdc8dedeRafael Espindola    return Layout.getSymbolAddress(&Data) -
5621973d4379250a88938a9358c12d96e96bdc8dedeRafael Espindola      Layout.getSectionAddress(FF->getParent());
5632c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
5642c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  return 0;
5652c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
5662c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
567115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
56888182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
56988182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
57088182132470527e27231f09b25a885893e528c66Rafael Espindola
57188182132470527e27231f09b25a885893e528c66Rafael Espindola  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
57288182132470527e27231f09b25a885893e528c66Rafael Espindola         ie = Asm.symbol_end(); it != ie; ++it) {
57388182132470527e27231f09b25a885893e528c66Rafael Espindola    const MCSymbol &Alias = it->getSymbol();
57494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &Symbol = Alias.AliasedSymbol();
575f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    MCSymbolData &SD = Asm.getSymbolData(Symbol);
576f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
577f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
578f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    if (&Symbol == &Alias)
579f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
580f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
58107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
58288182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
58388182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
58488182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
58588182132470527e27231f09b25a885893e528c66Rafael Espindola
586f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
587f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
588f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    it->setExternal(SD.isExternal());
589f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    SetBinding(*it, GetBinding(SD));
590f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
59107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
59288182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
59388182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
59488182132470527e27231f09b25a885893e528c66Rafael Espindola
59583ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
59683ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
59783ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
59883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
59983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
60007ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
60188182132470527e27231f09b25a885893e528c66Rafael Espindola  }
60288182132470527e27231f09b25a885893e528c66Rafael Espindola}
60388182132470527e27231f09b25a885893e528c66Rafael Espindola
604115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
605115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  MCDataFragment *ShndxF,
606115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  ELFSymbolData &MSD,
607115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
608de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &OrigData = *MSD.SymbolData;
609de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &Data =
61094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
611152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
6127be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
6137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Data.getSymbol().isVariable();
6147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
615152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Binding = GetBinding(OrigData);
616152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Visibility = GetVisibility(OrigData);
617152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Type = GetType(Data);
618152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
619152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
620152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Other = Visibility;
621152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
6222c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  uint64_t Value = SymbolValue(Data, Layout);
6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
6243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  const MCExpr *ESize;
6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
626f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(!(Data.isCommon() && !Data.isExternal()));
627f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  ESize = Data.getSize();
6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (Data.getSize()) {
6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCValue Res;
6313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    if (ESize->getKind() == MCExpr::Binary) {
6323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(ESize);
6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      if (BE->EvaluateAsRelocatable(Res, &Layout)) {
63524f1206c7de0f21d309d27737071ad742d5ddf27Benjamin Kramer        assert(!Res.getSymA() || !Res.getSymA()->getSymbol().isDefined());
63624f1206c7de0f21d309d27737071ad742d5ddf27Benjamin Kramer        assert(!Res.getSymB() || !Res.getSymB()->getSymbol().isDefined());
637f230df9af4012f9510de664b6d62b128e26a5861Rafael Espindola        Size = Res.getConstant();
6383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      }
6393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else if (ESize->getKind() == MCExpr::Constant) {
640368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer      Size = static_cast<const MCConstantExpr *>(ESize)->getValue();
6413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
6423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(0 && "Unsupported size expression");
6433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
6443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
6477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
6487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                   Size, Other, MSD.SectionIndex, IsReserved);
6493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
651115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
652115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
653115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAssembler &Asm,
654115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAsmLayout &Layout,
6554beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                     const SectionIndexMapTy &SectionIndexMap) {
6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The string table must be emitted first because we need the index
6573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // into the string table for all the symbol names.
6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(StringTable.size() && "Missing string table");
6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make sure the start of the symbol table is aligned.
6613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry is the undefined symbol entry.
6637be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
6643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write the symbol table entries.
6663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
6673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = LocalSymbolData[i];
6697be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
6703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
67271859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Write out a symbol table entry for each regular section.
6734beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
6744beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola       ++i) {
675a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    const MCSectionELF &Section =
6764beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola      static_cast<const MCSectionELF&>(i->getSection());
6774beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola    if (Section.getType() == ELF::SHT_RELA ||
6784beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_REL ||
6794beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_STRTAB ||
6804beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_SYMTAB)
681a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman      continue;
6827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
6834beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false);
684a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    LastLocalSymbolIndex++;
685a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman  }
6863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
6883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = ExternalSymbolData[i];
6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
6903223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    assert(((Data.getFlags() & ELF_STB_Global) ||
6913223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola            (Data.getFlags() & ELF_STB_Weak)) &&
6923223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola           "External symbol requires STB_GLOBAL or STB_WEAK flag");
6937be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
694e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola    if (GetBinding(Data) == ELF::STB_LOCAL)
6953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
6963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
6993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = UndefinedSymbolData[i];
7003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
7017be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
702e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola    if (GetBinding(Data) == ELF::STB_LOCAL)
7033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
7043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
7053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7071f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
7081f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCValue &Target,
7091f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCFragment &F) const {
7101f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
71194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
71294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol *Renamed = Renames.lookup(&Symbol);
71394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
71494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola
71594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (ASymbol.isUndefined()) {
71694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
71794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
71894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &ASymbol;
7191f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
7201f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
72194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (SD.isExternal()) {
72294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
72394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
72494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
72594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
7267eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
7277eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola  const MCSectionELF &Section =
72894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    static_cast<const MCSectionELF&>(ASymbol.getSection());
72925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  const SectionKind secKind = Section.getKind();
7307eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
73125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isBSS())
7321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola    return NULL;
7337eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
73425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isThreadLocal()) {
73525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    if (Renamed)
73625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola      return Renamed;
73725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    return &Symbol;
73825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
73925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
7408cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
7413729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola  const MCSectionELF &Sec2 =
7423729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola    static_cast<const MCSectionELF&>(F.getParent()->getSection());
7433729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
7448cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  if (&Sec2 != &Section &&
745c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola      (Kind == MCSymbolRefExpr::VK_PLT ||
746c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
74725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
74894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
74994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
75094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
75194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
7523729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
7531f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  if (Section.getFlags() & MCSectionELF::SHF_MERGE) {
75494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Target.getConstant() == 0)
75594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return NULL;
75694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
75794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
75894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
7591f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
760c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
7611f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  return NULL;
76273ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
76373ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
7643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7650b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t
766115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
767115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             const MCSymbol *S) {
7687b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer  MCSymbolData &SD = Asm.getSymbolData(*S);
769ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  return SD.getIndex();
7703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
772737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindolastatic bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
77388182132470527e27231f09b25a885893e528c66Rafael Espindola                       bool Used, bool Renamed) {
774484291c27319668ad99cb87def000254357736fbRafael Espindola  if (Data.getFlags() & ELF_Other_Weakref)
775484291c27319668ad99cb87def000254357736fbRafael Espindola    return false;
776484291c27319668ad99cb87def000254357736fbRafael Espindola
777bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
778bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
779bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
78088182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
78188182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
78288182132470527e27231f09b25a885893e528c66Rafael Espindola
783737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
784a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
785d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
786d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola    return true;
787d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola
78894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &A = Symbol.AliasedSymbol();
789d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (!A.isVariable() && A.isUndefined() && !Data.isCommon())
790a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
791a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
792737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
793737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
794737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
795bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
796737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
797737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
798737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
799737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
800737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
8011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindolastatic bool isLocal(const MCSymbolData &Data, bool isSignature,
8021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    bool isUsedInReloc) {
803737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (Data.isExternal())
804737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
805737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
806737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
80794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
8081f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8091f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
8101f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (isSignature && !isUsedInReloc)
8111f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      return true;
8121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
813737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
8141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  }
815737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
816737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
817737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
818737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
819115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
820115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                      SectionIndexMapTy &SectionIndexMap) {
821bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  unsigned Index = 1;
822bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
823bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
824bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    const MCSectionELF &Section =
825bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
8272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionIndexMap[&Section] = Index++;
8292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
8302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
8312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
8322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         ie = Asm.end(); it != ie; ++it) {
8332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
8342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
8352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() == ELF::SHT_GROUP)
8362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
837bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    SectionIndexMap[&Section] = Index++;
838bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  }
839bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola}
840bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
841115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
8421f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
8431f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      RevGroupMapTy RevGroupMap) {
8445c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  // FIXME: Is this the correct place to do this?
8455c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  if (NeedsGOT) {
8465c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
8475c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
8485c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
8495c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    Data.setExternal(true);
850f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    SetBinding(Data, ELF::STB_GLOBAL);
8515c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
8525c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
8533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Build section lookup table.
854ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  int NumRegularSections = Asm.size();
8553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Index 0 is always the empty string.
8573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringMap<uint64_t> StringIndexMap;
8583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTable += '\x00';
8593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
860a0949b50dcea35c08b50542091f97275f401529dRafael Espindola  // Add the data for the symbols.
8613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
8623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.symbol_end(); it != ie; ++it) {
8633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSymbol &Symbol = it->getSymbol();
8643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
865484291c27319668ad99cb87def000254357736fbRafael Espindola    bool Used = UsedInReloc.count(&Symbol);
866484291c27319668ad99cb87def000254357736fbRafael Espindola    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
8671f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool isSignature = RevGroupMap.count(&Symbol);
8681f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
8691f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!isInSymtab(Asm, *it,
8701f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    Used || WeakrefUsed || isSignature,
87188182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
8733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
8753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MSD.SymbolData = it;
87694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8781f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Undefined symbols are global, but this is the first place we
8791f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // are able to set it.
8801f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool Local = isLocal(*it, isSignature, Used);
8811f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!Local && GetBinding(*it) == ELF::STB_LOCAL) {
8821f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
8831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      SetBinding(*it, ELF::STB_GLOBAL);
8841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      SetBinding(SD, ELF::STB_GLOBAL);
8851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    }
8861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
887484291c27319668ad99cb87def000254357736fbRafael Espindola    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
888484291c27319668ad99cb87def000254357736fbRafael Espindola      SetBinding(*it, ELF::STB_WEAK);
889484291c27319668ad99cb87def000254357736fbRafael Espindola
890f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    if (it->isCommon()) {
891a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
892f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
893bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
894a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      MSD.SectionIndex = ELF::SHN_ABS;
89588182132470527e27231f09b25a885893e528c66Rafael Espindola    } else if (RefSymbol.isUndefined()) {
8961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      if (isSignature && !Used)
8971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
8981f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      else
8991f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
9003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
901bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
902bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola        static_cast<const MCSectionELF&>(RefSymbol.getSection());
903bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
9047be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
9057be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola        NeedsSymtabShndx = true;
9063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
9075df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
9085df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
90988182132470527e27231f09b25a885893e528c66Rafael Espindola    // The @@@ in symbol version is replaced with @ in undefined symbols and
91088182132470527e27231f09b25a885893e528c66Rafael Espindola    // @@ in defined ones.
91188182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
9121261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    SmallString<32> Buf;
9131261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer
91488182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = Name.find("@@@");
91588182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos != StringRef::npos) {
9161261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(0, Pos);
9171261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
9181261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(Pos + Skip);
9191261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Name = Buf;
92088182132470527e27231f09b25a885893e528c66Rafael Espindola    }
92188182132470527e27231f09b25a885893e528c66Rafael Espindola
9221261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    uint64_t &Entry = StringIndexMap[Name];
923a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (!Entry) {
924a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      Entry = StringTable.size();
9251261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      StringTable += Name;
926a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      StringTable += '\x00';
9273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
928a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    MSD.StringIndex = Entry;
929a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (MSD.SectionIndex == ELF::SHN_UNDEF)
930a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      UndefinedSymbolData.push_back(MSD);
931a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else if (Local)
932a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
933a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
934a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
9353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
9363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
9383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
9393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
9403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
9413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
9433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
944ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  unsigned Index = 1;
9453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
9463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    LocalSymbolData[i].SymbolData->setIndex(Index++);
947ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
948ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  Index += NumRegularSections;
949ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
9503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
9513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ExternalSymbolData[i].SymbolData->setIndex(Index++);
9523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
9533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
9543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
9553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
956115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
957115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                      const MCSectionData &SD) {
9583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  if (!Relocations[&SD].empty()) {
9593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCContext &Ctx = Asm.getContext();
9604283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *RelaSection;
9613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
9623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      static_cast<const MCSectionELF&>(SD.getSection());
9633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const StringRef SectionName = Section.getSectionName();
965377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer    std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel";
9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    RelaSectionName += SectionName;
967299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer
968299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    unsigned EntrySize;
969299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    if (HasRelocationAddend)
970299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer      EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
971299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    else
972299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer      EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
974377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer    RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ?
975377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer                                    ELF::SHT_RELA : ELF::SHT_REL, 0,
9763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming                                    SectionKind::getReadOnly(),
9772ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                                    EntrySize, "");
9783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
980a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    RelaSD.setAlignment(Is64Bit ? 8 : 4);
9813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCDataFragment *F = new MCDataFragment(&RelaSD);
9833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
9843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    WriteRelocationsFragment(Asm, F, &SD);
9853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
986115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar    Asm.AddSectionToTheEnd(*this, RelaSD, Layout);
9873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
9883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
9893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
990115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
991115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
992115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
993115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
994115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
995115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
9963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Name);        // sh_name: index into string table
9973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Type);        // sh_type
9983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
9993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
10003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
10013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
10023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Link);        // sh_link
10033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Info);        // sh_info
10043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
10053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
10063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1008115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
1009115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               MCDataFragment *F,
1010115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               const MCSectionData *SD) {
10113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
10123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // sort by the r_offset just like gnu as does
10133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(Relocs.begin(), Relocs.end());
10143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
10163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFRelocationEntry entry = Relocs[e - i - 1];
10173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
101812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    if (!entry.Index)
101912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      ;
102012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    else if (entry.Index < 0)
10218f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
10228f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    else
102312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      entry.Index += LocalSymbolData.size();
10245e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    if (Is64Bit) {
1025af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, entry.r_offset);
10265e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10278f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf64_Rela ERE64;
10288f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE64.setSymbolAndType(entry.Index, entry.Type);
1029af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, ERE64.r_info);
10305e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1031af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      if (HasRelocationAddend)
1032af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String64(*F, entry.r_addend);
10335e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
1034af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, entry.r_offset);
10355e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
10368f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
10378f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE32.setSymbolAndType(entry.Index, entry.Type);
1038af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, ERE32.r_info);
10395e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
1040af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      if (HasRelocationAddend)
1041af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String32(*F, entry.r_addend);
10425e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
10433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
10443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
10453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1046115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
1047115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             MCAsmLayout &Layout,
10484beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                    const SectionIndexMapTy &SectionIndexMap) {
10493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCContext &Ctx = Asm.getContext();
10503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F;
10513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
10533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
105438738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
10554283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *ShstrtabSection =
10567be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
10573f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                      SectionKind::getReadOnly());
105871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
105971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabSD.setAlignment(1);
106071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabIndex = Asm.size();
106171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
10624283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *SymtabSection =
10637be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
10647be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                      SectionKind::getReadOnly(),
10652ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      EntrySize, "");
10663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
10673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  SymtabSD.setAlignment(Is64Bit ? 8 : 4);
10687be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  SymbolTableIndex = Asm.size();
10697be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
10707be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCSectionData *SymtabShndxSD = NULL;
10717be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
10727be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
10734283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *SymtabShndxSection =
10747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
10752ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                        SectionKind::getReadOnly(), 4, "");
10767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
10777be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD->setAlignment(4);
10787be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
10793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
10803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  const MCSection *StrtabSection;
10813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
10823f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                    SectionKind::getReadOnly());
10833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
10843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSD.setAlignment(1);
10853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTableIndex = Asm.size();
10863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1087c3c413f63117896f186fc4385bdaac0578d3613fRafael Espindola  WriteRelocations(Asm, Layout);
108871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
108971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Symbol table
109071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  F = new MCDataFragment(&SymtabSD);
10917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCDataFragment *ShndxF = NULL;
10927be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
10937be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShndxF = new MCDataFragment(SymtabShndxSD);
1094115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar    Asm.AddSectionToTheEnd(*this, *SymtabShndxSD, Layout);
10957be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
10964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
1097115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Asm.AddSectionToTheEnd(*this, SymtabSD, Layout);
109871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
10993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&StrtabSD);
11003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents().append(StringTable.begin(), StringTable.end());
1101115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Asm.AddSectionToTheEnd(*this, StrtabSD, Layout);
11023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&ShstrtabSD);
11043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Section header string table.
11063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
11073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry of a string table holds a null character so skip
11083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // section 0.
11093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Index = 1;
11103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents() += '\x00';
11113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  StringMap<uint64_t> SecStringMap;
11133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::const_iterator it = Asm.begin(),
11143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.end(); it != ie; ++it) {
11153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
1116368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer      static_cast<const MCSectionELF&>(it->getSection());
111751efe7a253190b672519e8388ce5d45f1dcf1a24Rafael Espindola    // FIXME: We could merge suffixes like in .text and .rela.text.
11183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    StringRef Name = Section.getSectionName();
11202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (SecStringMap.count(Name)) {
11212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      SectionStringTableIndex[&Section] =  SecStringMap[Name];
11222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
11232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
11243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the index into the string table so we can write it
11253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // into the sh_name field of the section header table.
11262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionStringTableIndex[&Section] = Index;
11272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SecStringMap[Name] = Index;
11283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Index += Name.size() + 1;
11302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    F->getContents() += Name;
11313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    F->getContents() += '\x00';
11323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
11333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1134115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Asm.AddSectionToTheEnd(*this, ShstrtabSD, Layout);
11357070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola}
11367070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
1137115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarbool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
1138115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                           const MCValue Target,
1139115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                           bool IsPCRel,
1140115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                           const MCFragment *DF) const {
11417070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  // If this is a PCrel relocation, find the section this fixup value is
11427070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  // relative to.
11437070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  const MCSection *BaseSection = 0;
11447070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  if (IsPCRel) {
11457070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola    BaseSection = &DF->getParent()->getSection();
11467070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola    assert(BaseSection);
11477070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  }
11487070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
11497070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  const MCSection *SectionA = 0;
11507070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  const MCSymbol *SymbolA = 0;
11517070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  if (const MCSymbolRefExpr *A = Target.getSymA()) {
11522c920850343810535c0cd8720a81eddf7997663aRafael Espindola    SymbolA = &A->getSymbol();
11532c920850343810535c0cd8720a81eddf7997663aRafael Espindola    SectionA = &SymbolA->AliasedSymbol().getSection();
11547070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  }
11557070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
11567070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  const MCSection *SectionB = 0;
115712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  const MCSymbol *SymbolB = 0;
11587070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  if (const MCSymbolRefExpr *B = Target.getSymB()) {
115912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    SymbolB = &B->getSymbol();
116012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    SectionB = &SymbolB->AliasedSymbol().getSection();
11617070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  }
11627070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
11637070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  if (!BaseSection)
11647070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola    return SectionA == SectionB;
11657070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
116612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  if (SymbolB)
116712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    return false;
116812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola
116912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  // Absolute address but PCrel instruction, so we need a relocation.
117012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  if (!SymbolA)
117112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    return false;
117212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola
11732c920850343810535c0cd8720a81eddf7997663aRafael Espindola  // FIXME: This is in here just to match gnu as output. If the two ends
11742c920850343810535c0cd8720a81eddf7997663aRafael Espindola  // are in the same section, there is nothing that the linker can do to
11752c920850343810535c0cd8720a81eddf7997663aRafael Espindola  // break it.
11767070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA);
11777070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola  if (DataA.isExternal())
11787070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola    return false;
11797070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
118012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  return BaseSection == SectionA;
11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
11823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1183115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
1184115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                          MCAsmLayout &Layout,
11851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                          GroupMapTy &GroupMap,
11861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                          RevGroupMapTy &RevGroupMap) {
11872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Build the groups
11882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
11892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it) {
11902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
11912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
11922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!(Section.getFlags() & MCSectionELF::SHF_GROUP))
11932ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
11942ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
11952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSymbol *SignatureSymbol = Section.getGroup();
11962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Asm.getOrCreateSymbolData(*SignatureSymbol);
11971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
11982ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!Group) {
11992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Group = Asm.getContext().CreateELFGroupSection();
12002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12012ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Data.setAlignment(4);
12022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCDataFragment *F = new MCDataFragment(&Data);
12032ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      String32(*F, ELF::GRP_COMDAT);
12042ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
12052ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupMap[Group] = SignatureSymbol;
12062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12072ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Add sections to the groups
12092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  unsigned Index = 1;
12101f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  unsigned NumGroups = RevGroupMap.size();
12112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it, ++Index) {
12132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
12142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
12152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!(Section.getFlags() & MCSectionELF::SHF_GROUP))
12162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
12171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
12182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
12192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    // FIXME: we could use the previous fragment
12202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCDataFragment *F = new MCDataFragment(&Data);
12212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    String32(*F, NumGroups + Index);
12222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
12241f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  for (RevGroupMapTy::const_iterator i = RevGroupMap.begin(),
12251f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola         e = RevGroupMap.end(); i != e; ++i) {
12262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF *Group = i->second;
12272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
1228115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar    Asm.AddSectionToTheEnd(*this, Data, Layout);
12292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
12312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1232115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
1233115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const SectionIndexMapTy &SectionIndexMap,
1234115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint32_t GroupSymbolIndex,
1235115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Offset, uint64_t Size,
1236115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Alignment,
1237115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const MCSectionELF &Section) {
1238c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
1239c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
1240c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1241c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
1242c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
1243c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionStringTableIndex[&Section];
1244c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = 0;
1245c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1246c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1247c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
1248c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
1249c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *SymtabSection;
1250c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *InfoSection;
1251c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
1252c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                   0,
12533f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                   SectionKind::getReadOnly());
1254c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionIndexMap.lookup(SymtabSection);
1255c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
1256c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1257c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Remove ".rel" and ".rela" prefixes.
1258c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
1259c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
1260c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1261c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    InfoSection = Asm.getContext().getELFSection(SectionName,
1262c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                 ELF::SHT_PROGBITS, 0,
12633f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                 SectionKind::getReadOnly());
1264c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
1265c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1266c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1267c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1268c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
1269c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
1270c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
1271c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
1272c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1273c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1274c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
1275c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
1276c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1277c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1278c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_PROGBITS:
1279c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_STRTAB:
1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NOBITS:
1281c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NULL:
1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_ARM_ATTRIBUTES:
1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Nothing to do.
1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
12862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  case ELF::SHT_GROUP: {
12872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
12882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
12892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
12902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
12912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  default:
1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(0 && "FIXME: sh_type value not supported!");
1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1295c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Alignment, Section.getEntrySize());
1300c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola}
1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1302115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
1303115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
13042ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  GroupMapTy GroupMap;
13051f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
13061f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
13071f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                      RevGroupMap);
13082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1309bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1310bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
1311bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap);
1312bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
13138f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola  // Compute symbol table information.
13141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap);
13158f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
13163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
13174beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         const_cast<MCAsmLayout&>(Layout),
13184beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         SectionIndexMap);
13193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13201d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola  // Update to include the metadata sections.
13211d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap);
13221d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
13233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Add 1 for the null section.
13243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  unsigned NumSections = Asm.size() + 1;
1325a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t NaturalAlignment = Is64Bit ? 8 : 4;
1326a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t HeaderSize = Is64Bit ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr);
1327a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t FileOff = HeaderSize;
13283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  std::vector<const MCSectionELF*> Sections;
13302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  Sections.resize(NumSections);
13312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
13322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (SectionIndexMapTy::const_iterator i=
13332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
13342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
13352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Sections[p.second] = p.first;
13362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
13372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
13382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (unsigned i = 1; i < NumSections; ++i) {
13392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
13402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
13413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1342a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1343a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Get the size of the section in the output file (including padding).
13453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    uint64_t Size = Layout.getSectionFileSize(&SD);
1346a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
1347a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff += Size;
13483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
13493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1350a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
1351a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the ELF header ...
1353a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteHeader(FileOff - HeaderSize, NumSections);
1354a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
1355a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = HeaderSize;
13563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ... then all of the sections ...
13583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  DenseMap<const MCSection*, uint64_t> SectionOffsetMap;
13593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (unsigned i = 1; i < NumSections; ++i) {
13612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
13622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
1363a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
1364a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
1365a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    WriteZeros(Padding);
1366a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff += Padding;
1367a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
13692ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionOffsetMap[&Section] = FileOff;
137044cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
13713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    FileOff += Layout.getSectionFileSize(&SD);
13723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1373115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar    Asm.WriteSectionData(&SD, Layout, this);
13743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
13753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1376a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
1377a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteZeros(Padding);
1378a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff += Padding;
1379a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
13803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ... and then the section header table.
13813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Should we align the section header table?
13823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
13833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Null section first.
13847be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  uint64_t FirstSectionSize =
13857be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
13867be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  uint32_t FirstSectionLink =
13877be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
13887be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
13893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (unsigned i = 1; i < NumSections; ++i) {
13912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
13922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
13932ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    uint32_t GroupSymbolIndex;
13942ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
13952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      GroupSymbolIndex = 0;
13962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    else
13972ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]);
13983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
13992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
14002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                 SectionOffsetMap[&Section], Layout.getSectionSize(&SD),
1401c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                 SD.getAlignment(), Section);
14023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
14033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
14043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1405115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarMCObjectWriter *llvm::createELFObjectWriter(raw_ostream &OS,
1406115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                            bool Is64Bit,
1407115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                            Triple::OSType OSType,
1408115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                            uint16_t EMachine,
1409115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                            bool IsLittleEndian,
1410115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                            bool HasRelocationAddend) {
1411d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  switch (EMachine) {
1412d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_386:
1413d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_X86_64:
1414d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      return new X86ELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine,
1415d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                    HasRelocationAddend, OSType); break;
1416d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_ARM:
1417d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      return new ARMELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine,
1418d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                    HasRelocationAddend, OSType); break;
14194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case ELF::EM_MBLAZE:
14204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      return new MBlazeELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine,
14214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                       HasRelocationAddend, OSType); break;
14223285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer    default: llvm_unreachable("Unsupported architecture"); break;
1423d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1424d3443e99e43945fdb0742177da06a32fa225740dJason W Kim}
1425d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1426d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1427d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter
1428d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===//
1429d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1430d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
1431d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       bool _IsLittleEndian,
1432d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       uint16_t _EMachine, bool _HasRelocationAddend,
1433d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       Triple::OSType _OSType)
1434d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine,
1435d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                    _HasRelocationAddend, _OSType)
1436d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1437d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1438d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter()
1439d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1440d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
144185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
144285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim                                          const MCFixup &Fixup,
144385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim                                          bool IsPCRel) {
144485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
144585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
144685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
144785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (IsPCRel) {
144885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch (Modifier) {
144985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: assert(0 && "Unimplemented Modifier");
145085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case MCSymbolRefExpr::VK_None: break;
145185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
145285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
145385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: assert(0 && "Unimplemented");
145485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_branch: return ELF::R_ARM_CALL; break;
145585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
145685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  } else {
145785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
145885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: llvm_unreachable("invalid fixup kind!");
1459dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_ldst_pcrel_12:
14609d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    case ARM::fixup_arm_pcrel_10:
1461dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_adr_pcrel_12:
146285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      assert(0 && "Unimplemented"); break;
146385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_branch:
146485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      return ELF::R_ARM_CALL; break;
146585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_movt_hi16:
146685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      return ELF::R_ARM_MOVT_ABS; break;
146785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_movw_lo16:
146885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      return ELF::R_ARM_MOVW_ABS_NC; break;
146985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
147085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  }
147185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
147285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (RelocNeedsGOT(Modifier))
147385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    NeedsGOT = true;
147485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  return -1;
147585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim}
147685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
1477d3443e99e43945fdb0742177da06a32fa225740dJason W Kimvoid ARMELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
1478d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                          const MCAsmLayout &Layout,
1479d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                          const MCFragment *Fragment,
1480d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                          const MCFixup &Fixup,
1481d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                          MCValue Target,
1482d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                          uint64_t &FixedValue) {
148385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  int64_t Addend = 0;
148485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  int Index = 0;
148585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  int64_t Value = Target.getConstant();
148685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  const MCSymbol *RelocSymbol = NULL;
148785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
148885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  bool IsPCRel = isFixupKindPCRel(Fixup.getKind());
148985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (!Target.isAbsolute()) {
149085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
149185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
149285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
149385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
149485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
149585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
149685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
149785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      IsPCRel = true;
149885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      MCSectionData *Sec = Fragment->getParent();
149985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
150085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      // Offset of the symbol in the section
150185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
150285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
150385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      // Ofeset of the relocation in the section
150485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
150585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      Value += b - a;
150685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
150785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
150885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    if (!RelocSymbol) {
150985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
151085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      MCFragment *F = SD.getFragment();
151185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
151285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      Index = F->getParent()->getOrdinal() + 1;
151385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
151485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      MCSectionData *FSD = F->getParent();
151585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      // Offset of the symbol in the section
151685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
151785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    } else {
151885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
151985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
152085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      else
152185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim        UsedInReloc.insert(RelocSymbol);
152285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      Index = -1;
152385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
152485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    Addend = Value;
152585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    // Compensate for the addend on i386.
152685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    if (Is64Bit)
152785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim      Value = 0;
152885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  }
152985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
153085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  FixedValue = Value;
153185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
153285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  // determine the type of the relocation
153385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
153485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
153585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
153685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    Fixup.getOffset();
153785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
153885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (!HasRelocationAddend) Addend = 0;
153985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
154085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
1541d3443e99e43945fdb0742177da06a32fa225740dJason W Kim}
1542d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
15434b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===//
1544d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
15454b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
15464b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             bool _IsLittleEndian,
15474b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             uint16_t _EMachine,
15484b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             bool _HasRelocationAddend,
15494b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             Triple::OSType _OSType)
15504b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine,
15514b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                    _HasRelocationAddend, _OSType) {
15524b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
15534b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15544b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
15554b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
15564b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15574b04713423c6da988db75c7546baa3db7ddfa119Wesley Peckvoid MBlazeELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
15584b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             const MCAsmLayout &Layout,
15594b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             const MCFragment *Fragment,
15604b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             const MCFixup &Fixup,
15614b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             MCValue Target,
15624b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             uint64_t &FixedValue) {
15634b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  int64_t Addend = 0;
15644b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  int Index = 0;
15654b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  int64_t Value = Target.getConstant();
15664b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
15674b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
15684b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  const MCSymbol *RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
15694b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15704a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim  bool IsPCRel = isFixupKindPCRel(Fixup.getKind());
15714b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  if (!Target.isAbsolute()) {
15724b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
15734b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      const MCSymbol &SymbolB = RefB->getSymbol();
15744b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
15754b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      IsPCRel = true;
15764b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      MCSectionData *Sec = Fragment->getParent();
15774b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15784b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      // Offset of the symbol in the section
15794b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
15804b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15814b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      // Ofeset of the relocation in the section
15824b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
15834b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Value += b - a;
15844b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
15854b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    if (!RelocSymbol) {
15874b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
15884b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      MCFragment *F = SD.getFragment();
15894b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15904b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Index = F->getParent()->getOrdinal();
15914b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15924b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      MCSectionData *FSD = F->getParent();
15934b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      // Offset of the symbol in the section
15944b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
15954b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    } else {
15964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
15974b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck        WeakrefUsedInReloc.insert(RelocSymbol);
15984b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      else
15994b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck        UsedInReloc.insert(RelocSymbol);
16004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Index = -1;
16014b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
16024b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    Addend = Value;
16034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  }
16044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
16054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  FixedValue = Value;
16064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
16074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  // determine the type of the relocation
16084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  unsigned Type;
16094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  if (IsPCRel) {
16104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
16114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default:
16124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      llvm_unreachable("Unimplemented");
1613e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_4:
16144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_64_PCREL;
16154b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
1616e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_2:
16174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32_PCREL;
16184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
16194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
16204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  } else {
16214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
16224b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default: llvm_unreachable("invalid fixup kind!");
16234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_4:
16244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = (RelocSymbol || Addend !=0) ? ELF::R_MICROBLAZE_32
16254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                         : ELF::R_MICROBLAZE_64;
16264b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
16274b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_2:
16284b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32;
16294b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
16304b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
16314b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  }
16324b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
16334b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
16344b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  if (RelocNeedsGOT(Modifier))
16354b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    NeedsGOT = true;
16364b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
1637858e7506e1fabe563eb4222c80ad0fad01641becJason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
16384a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    Fixup.getOffset();
16394b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
164010907426893019c6b7e59c886e41815d4fe50b19Jason W Kim  if (!HasRelocationAddend) Addend = 0;
16414a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
16424b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  Relocations[Fragment->getParent()].push_back(ERE);
16434b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
1644d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1645d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===//
1646d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1647d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1648d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
1649d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       bool _IsLittleEndian,
1650d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       uint16_t _EMachine, bool _HasRelocationAddend,
1651d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       Triple::OSType _OSType)
1652d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine,
1653d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                    _HasRelocationAddend, _OSType)
1654d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1655d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1656d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter()
1657d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1658d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1659d3443e99e43945fdb0742177da06a32fa225740dJason W Kimvoid X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
1660d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       const MCAsmLayout &Layout,
1661d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       const MCFragment *Fragment,
1662d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       const MCFixup &Fixup,
1663d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       MCValue Target,
1664d3443e99e43945fdb0742177da06a32fa225740dJason W Kim                                       uint64_t &FixedValue) {
1665d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  int64_t Addend = 0;
1666d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  int Index = 0;
1667d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  int64_t Value = Target.getConstant();
166812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  const MCSymbol *RelocSymbol = NULL;
1669d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
16704a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim  bool IsPCRel = isFixupKindPCRel(Fixup.getKind());
1671d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  if (!Target.isAbsolute()) {
167212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
167312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
167412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
167512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola
1676d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1677d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
1678d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
1679d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      IsPCRel = true;
1680d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      MCSectionData *Sec = Fragment->getParent();
1681d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1682d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // Offset of the symbol in the section
1683d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
1684d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1685d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // Ofeset of the relocation in the section
1686d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1687d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      Value += b - a;
1688d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1689d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1690d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (!RelocSymbol) {
169194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
1692d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      MCFragment *F = SD.getFragment();
1693d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
169412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      Index = F->getParent()->getOrdinal() + 1;
1695d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1696d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      MCSectionData *FSD = F->getParent();
1697d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // Offset of the symbol in the section
1698d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
1699d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1700d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
1701d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
1702d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      else
1703d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        UsedInReloc.insert(RelocSymbol);
1704d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      Index = -1;
1705d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1706d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    Addend = Value;
1707d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    // Compensate for the addend on i386.
1708d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (Is64Bit)
1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      Value = 0;
1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  FixedValue = Value;
1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  // determine the type of the relocation
1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
171612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
171712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  unsigned Type;
1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  if (Is64Bit) {
1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch (Modifier) {
1722d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default:
1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        llvm_unreachable("Unimplemented");
1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_None:
1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_PC32;
1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_PLT:
1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_PLT32;
1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_GOTPCREL:
1731d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_GOTPCREL;
1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_GOTTPOFF:
1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_GOTTPOFF;
1735d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_TLSGD:
1737d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_TLSGD;
1738d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1739d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_TLSLD:
1740d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_TLSLD;
1741d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1743d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1744d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1745d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1746d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_8: Type = ELF::R_X86_64_64; break;
1747d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1748e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
1749d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        assert(isInt<32>(Target.getConstant()));
1750d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1751d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1752d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1753d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1754d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_32S;
1755d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1756d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1757d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOT32;
1758d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1759d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTPCREL:
1760d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOTPCREL;
1761d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1762d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1763d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_TPOFF32;
1764d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1765d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1766d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_DTPOFF32;
1767d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1768d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1769d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1770d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1771d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_32;
1772d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1773d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_X86_64_16; break;
1774e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1775d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_X86_64_8; break;
1776d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1777d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1778d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  } else {
1779d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
1780d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch (Modifier) {
1781d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default:
1782d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        llvm_unreachable("Unimplemented");
1783d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_None:
1784d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_PC32;
1785d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1786d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_PLT:
1787d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_PLT32;
1788d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1789d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1790d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1791d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1792d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1793d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1794d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_global_offset_table:
1795d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_GOTPC;
1796d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1797d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1798d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1799d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // instead?
1800d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1801e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
1802d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1803d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1804d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1805d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1806d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1807d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_32;
1808d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1809d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1810d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOT32;
1811d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1812d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTOFF:
1813d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOTOFF;
1814d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1815d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSGD:
1816d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GD;
1817d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1818d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1819d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE_32;
1820d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1821d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_INDNTPOFF:
1822d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_IE;
1823d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1824d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_NTPOFF:
1825d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE;
1826d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1827d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTNTPOFF:
1828d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GOTIE;
1829d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1830d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSLDM:
1831d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDM;
1832d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1833d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1834d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDO_32;
1835d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1836d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1837d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1838d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_386_16; break;
1839e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1840d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_386_8; break;
1841d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1842d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1843d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1844d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1845d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  if (RelocNeedsGOT(Modifier))
1846d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    NeedsGOT = true;
1847d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1848d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1849858e7506e1fabe563eb4222c80ad0fad01641becJason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
18504a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim    Fixup.getOffset();
1851d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
185210907426893019c6b7e59c886e41815d4fe50b19Jason W Kim  if (!HasRelocationAddend) Addend = 0;
18534a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
1854d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
18553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1856