MC/Mach-O: Shuffle enums a bit to make it harder to inadvertently use the wrong
[oota-llvm.git] / lib / MC / ELFObjectWriter.cpp
index e11d68e8d8d42201583475bef9a5dfbd896ce5e6..bb523cefedcc6781cdcb3dc06978ef3a53a697ee 100644 (file)
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringMap.h"
@@ -20,6 +21,7 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFSymbolFlags.h"
 #include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSymbol.h"
@@ -30,6 +32,7 @@
 #include "llvm/Target/TargetAsmBackend.h"
 
 #include "../Target/X86/X86FixupKinds.h"
+#include "../Target/ARM/ARMFixupKinds.h"
 
 #include <vector>
 using namespace llvm;
@@ -65,17 +68,6 @@ static unsigned GetVisibility(MCSymbolData &SD) {
   return Visibility;
 }
 
-static bool isFixupKindX86PCRel(unsigned Kind) {
-  switch (Kind) {
-  default:
-    return false;
-  case X86::reloc_pcrel_1byte:
-  case X86::reloc_pcrel_4byte:
-  case X86::reloc_riprel_4byte:
-  case X86::reloc_riprel_4byte_movq_load:
-    return true;
-  }
-}
 
 static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
   switch (Variant) {
@@ -97,6 +89,13 @@ static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
   }
 }
 
+static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
+  const MCFixupKindInfo &FKI =
+    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
+
+  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
+}
+
 namespace {
   class ELFObjectWriter : public MCObjectWriter {
   protected:
@@ -135,12 +134,24 @@ namespace {
       const MCSymbol *Symbol;
       uint64_t r_addend;
 
+      ELFRelocationEntry()
+        : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
+
+      ELFRelocationEntry(uint64_t RelocOffset, int Idx,
+                         unsigned RelType, const MCSymbol *Sym,
+                         uint64_t Addend)
+        : r_offset(RelocOffset), Index(Idx), Type(RelType),
+          Symbol(Sym), r_addend(Addend) {}
+
       // Support lexicographic sorting.
       bool operator<(const ELFRelocationEntry &RE) const {
         return RE.r_offset < r_offset;
       }
     };
 
+    /// The target specific ELF writer instance.
+    llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
+
     SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
     SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
     DenseMap<const MCSymbol *, const MCSymbol *> Renames;
@@ -164,14 +175,6 @@ namespace {
 
     bool NeedsSymtabShndx;
 
-    unsigned Is64Bit : 1;
-
-    bool HasRelocationAddend;
-
-    Triple::OSType OSType;
-
-    uint16_t EMachine;
-
     // This holds the symbol table index of the last local symbol.
     unsigned LastLocalSymbolIndex;
     // This holds the .strtab section index.
@@ -186,20 +189,23 @@ namespace {
                                   const MCValue &Target,
                                   const MCFragment &F) const;
 
+    bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+    bool hasRelocationAddend() const {
+      return TargetObjectWriter->hasRelocationAddend();
+    }
+
   public:
-    ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
-                    uint16_t _EMachine, bool _HasRelAddend,
-                    Triple::OSType _OSType)
+    ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                    raw_ostream &_OS, bool IsLittleEndian)
       : MCObjectWriter(_OS, IsLittleEndian),
-        NeedsGOT(false), NeedsSymtabShndx(false),
-        Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend),
-        OSType(_OSType), EMachine(_EMachine) {
+        TargetObjectWriter(MOTW),
+        NeedsGOT(false), NeedsSymtabShndx(false){
     }
 
     virtual ~ELFObjectWriter();
 
     void WriteWord(uint64_t W) {
-      if (Is64Bit)
+      if (is64Bit())
         Write64(W);
       else
         Write32(W);
@@ -287,10 +293,8 @@ namespace {
                           const SectionIndexMapTy &SectionIndexMap);
 
     virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
-                          const MCFragment *Fragment, const MCFixup &Fixup,
-                                  MCValue Target, uint64_t &FixedValue) {
-      assert(0 && "RecordRelocation is not specific enough");
-    };
+                                  const MCFragment *Fragment, const MCFixup &Fixup,
+                                  MCValue Target, uint64_t &FixedValue);
 
     virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
                                          const MCSymbol *S);
@@ -328,15 +332,17 @@ namespace {
     virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout,
                              GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap);
 
-    virtual void ExecutePostLayoutBinding(MCAssembler &Asm);
+    virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+                                          const MCAsmLayout &Layout);
 
     virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
                           uint64_t Address, uint64_t Offset,
                           uint64_t Size, uint32_t Link, uint32_t Info,
                           uint64_t Alignment, uint64_t EntrySize);
 
-    virtual void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F,
-                                  const MCSectionData *SD);
+    virtual void WriteRelocationsFragment(const MCAssembler &Asm,
+                                          MCDataFragment *F,
+                                          const MCSectionData *SD);
 
     virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
                               const MCValue Target,
@@ -349,22 +355,26 @@ namespace {
                       uint32_t GroupSymbolIndex,
                       uint64_t Offset, uint64_t Size, uint64_t Alignment,
                       const MCSectionELF &Section);
+
+  protected:
+    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                  bool IsPCRel, bool IsRelocWithSymbol,
+                                  int64_t Addend) = 0;
   };
 
   //===- X86ELFObjectWriter -------------------------------------------===//
 
   class X86ELFObjectWriter : public ELFObjectWriter {
   public:
-    X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
-                       uint16_t _EMachine, bool _HasRelAddend,
-                       Triple::OSType _OSType);
-    
+    X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                       raw_ostream &_OS,
+                       bool IsLittleEndian);
+
     virtual ~X86ELFObjectWriter();
-    virtual void RecordRelocation(const MCAssembler &Asm,
-                                  const MCAsmLayout &Layout,
-                                  const MCFragment *Fragment,
-                                  const MCFixup &Fixup, MCValue Target,
-                                  uint64_t &FixedValue);
+  protected:
+    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                  bool IsPCRel, bool IsRelocWithSymbol,
+                                  int64_t Addend);
   };
 
 
@@ -372,16 +382,30 @@ namespace {
 
   class ARMELFObjectWriter : public ELFObjectWriter {
   public:
-    ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian,
-                       uint16_t _EMachine, bool _HasRelAddend,
-                       Triple::OSType _OSType);
-    
+    ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                       raw_ostream &_OS,
+                       bool IsLittleEndian);
+
     virtual ~ARMELFObjectWriter();
-    virtual void RecordRelocation(const MCAssembler &Asm,
-                                  const MCAsmLayout &Layout,
-                                  const MCFragment *Fragment,
-                                  const MCFixup &Fixup, MCValue Target,
-                                  uint64_t &FixedValue);
+  protected:
+    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                  bool IsPCRel, bool IsRelocWithSymbol,
+                                  int64_t Addend);
+  };
+
+  //===- MBlazeELFObjectWriter -------------------------------------------===//
+
+  class MBlazeELFObjectWriter : public ELFObjectWriter {
+  public:
+    MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                          raw_ostream &_OS,
+                          bool IsLittleEndian);
+
+    virtual ~MBlazeELFObjectWriter();
+  protected:
+    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                  bool IsPCRel, bool IsRelocWithSymbol,
+                                  int64_t Addend);
   };
 }
 
@@ -404,14 +428,14 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
   Write8('L');  // e_ident[EI_MAG2]
   Write8('F');  // e_ident[EI_MAG3]
 
-  Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
+  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
 
   // e_ident[EI_DATA]
   Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
 
   Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
   // e_ident[EI_OSABI]
-  switch (OSType) {
+  switch (TargetObjectWriter->getOSType()) {
     case Triple::FreeBSD:  Write8(ELF::ELFOSABI_FREEBSD); break;
     case Triple::Linux:    Write8(ELF::ELFOSABI_LINUX); break;
     default:               Write8(ELF::ELFOSABI_NONE); break;
@@ -422,25 +446,25 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
 
   Write16(ELF::ET_REL);             // e_type
 
-  Write16(EMachine); // e_machine = target
+  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
 
   Write32(ELF::EV_CURRENT);         // e_version
   WriteWord(0);                    // e_entry, no entry point in .o file
   WriteWord(0);                    // e_phoff, no program header for .o
-  WriteWord(SectionDataSize + (Is64Bit ? sizeof(ELF::Elf64_Ehdr) :
+  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
             sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
 
   // FIXME: Make this configurable.
   Write32(0);   // e_flags = whatever the target wants
 
   // e_ehsize = ELF header size
-  Write16(Is64Bit ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
+  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
 
   Write16(0);                  // e_phentsize = prog header entry size
   Write16(0);                  // e_phnum = # prog header entries = 0
 
   // e_shentsize = Section header entry size
-  Write16(Is64Bit ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
+  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
 
   // e_shnum     = # of section header ents
   if (NumberOfSections >= ELF::SHN_LORESERVE)
@@ -472,7 +496,7 @@ void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
   uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
     uint16_t(ELF::SHN_XINDEX) : shndx;
 
-  if (Is64Bit) {
+  if (is64Bit()) {
     String32(*SymtabF, name);  // st_name
     String8(*SymtabF, info);   // st_info
     String8(*SymtabF, other);  // st_other
@@ -494,49 +518,33 @@ static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) {
     return Data.getCommonAlignment();
 
   const MCSymbol &Symbol = Data.getSymbol();
+
+  if (Symbol.isAbsolute() && Symbol.isVariable()) {
+    if (const MCExpr *Value = Symbol.getVariableValue()) {
+      int64_t IntValue;
+      if (Value->EvaluateAsAbsolute(IntValue, Layout))
+       return (uint64_t)IntValue;
+    }
+  }
+
   if (!Symbol.isInSection())
     return 0;
 
-  if (MCFragment *FF = Data.getFragment())
-    return Layout.getSymbolAddress(&Data) -
-      Layout.getSectionAddress(FF->getParent());
+  if (Data.getFragment())
+    return Layout.getSymbolOffset(&Data);
 
   return 0;
 }
 
-static const MCSymbol &AliasedSymbol(const MCSymbol &Symbol) {
-  const MCSymbol *S = &Symbol;
-  while (S->isVariable()) {
-    const MCExpr *Value = S->getVariableValue();
-    MCExpr::ExprKind Kind = Value->getKind();
-    switch (Kind) {
-    case MCExpr::SymbolRef: {
-      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Value);
-      S = &Ref->getSymbol();
-      break;
-    }
-    case MCExpr::Target: {
-      const MCTargetExpr *TExp = static_cast<const MCTargetExpr*>(Value);
-      MCValue Res;
-      TExp->EvaluateAsRelocatableImpl(Res, NULL);
-      S = &Res.getSymA()->getSymbol();
-      break;
-    }
-    default:
-      return *S;
-    }
-  }
-  return *S;
-}
-
-void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
+void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
+                                               const MCAsmLayout &Layout) {
   // The presence of symbol versions causes undefined symbols and
   // versions declared with @@@ to be renamed.
 
   for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
          ie = Asm.symbol_end(); it != ie; ++it) {
     const MCSymbol &Alias = it->getSymbol();
-    const MCSymbol &Symbol = AliasedSymbol(Alias);
+    const MCSymbol &Symbol = Alias.AliasedSymbol();
     MCSymbolData &SD = Asm.getSymbolData(Symbol);
 
     // Not an alias.
@@ -572,7 +580,7 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
                                   const MCAsmLayout &Layout) {
   MCSymbolData &OrigData = *MSD.SymbolData;
   MCSymbolData &Data =
-    Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol()));
+    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
 
   bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
     Data.getSymbol().isVariable();
@@ -673,32 +681,35 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
                                                const MCValue &Target,
                                                const MCFragment &F) const {
   const MCSymbol &Symbol = Target.getSymA()->getSymbol();
-  const MCSymbol &ASymbol = AliasedSymbol(Symbol);
-  const MCSymbol *RenamedP = Renames.lookup(&Symbol);
-
-  if (!RenamedP) {
-    if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-        Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
-      RenamedP = &ASymbol;
-    else
-      RenamedP = &Symbol;
+  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
+  const MCSymbol *Renamed = Renames.lookup(&Symbol);
+  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
+
+  if (ASymbol.isUndefined()) {
+    if (Renamed)
+      return Renamed;
+    return &ASymbol;
   }
-  const MCSymbol &Renamed = *RenamedP;
-
-  MCSymbolData &SD = Asm.getSymbolData(Symbol);
 
-  if (Symbol.isUndefined())
-    return &Renamed;
-
-  if (SD.isExternal())
-    return &Renamed;
+  if (SD.isExternal()) {
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
+  }
 
   const MCSectionELF &Section =
-    static_cast<const MCSectionELF&>(Symbol.getSection());
+    static_cast<const MCSectionELF&>(ASymbol.getSection());
+  const SectionKind secKind = Section.getKind();
 
-  if (Section.getKind().isBSS())
+  if (secKind.isBSS())
     return NULL;
 
+  if (secKind.isThreadLocal()) {
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
+  }
+
   MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
   const MCSectionELF &Sec2 =
     static_cast<const MCSectionELF&>(F.getParent()->getSection());
@@ -706,19 +717,89 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
   if (&Sec2 != &Section &&
       (Kind == MCSymbolRefExpr::VK_PLT ||
        Kind == MCSymbolRefExpr::VK_GOTPCREL ||
-       Kind == MCSymbolRefExpr::VK_GOTOFF))
-    return &Renamed;
+       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
+  }
 
   if (Section.getFlags() & MCSectionELF::SHF_MERGE) {
-    if (Target.getConstant() != 0)
-      return &Renamed;
-    return NULL;
+    if (Target.getConstant() == 0)
+      return NULL;
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
   }
 
   return NULL;
 }
 
 
+void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
+                                       const MCAsmLayout &Layout,
+                                       const MCFragment *Fragment,
+                                       const MCFixup &Fixup,
+                                       MCValue Target,
+                                       uint64_t &FixedValue) {
+  int64_t Addend = 0;
+  int Index = 0;
+  int64_t Value = Target.getConstant();
+  const MCSymbol *RelocSymbol = NULL;
+
+  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
+  if (!Target.isAbsolute()) {
+    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
+    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
+    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
+
+    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
+      const MCSymbol &SymbolB = RefB->getSymbol();
+      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
+      IsPCRel = true;
+
+      // Offset of the symbol in the section
+      int64_t a = Layout.getSymbolOffset(&SDB);
+
+      // Ofeset of the relocation in the section
+      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
+      Value += b - a;
+    }
+
+    if (!RelocSymbol) {
+      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
+      MCFragment *F = SD.getFragment();
+
+      Index = F->getParent()->getOrdinal() + 1;
+
+      // Offset of the symbol in the section
+      Value += Layout.getSymbolOffset(&SD);
+    } else {
+      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
+        WeakrefUsedInReloc.insert(RelocSymbol);
+      else
+        UsedInReloc.insert(RelocSymbol);
+      Index = -1;
+    }
+    Addend = Value;
+    // Compensate for the addend on i386.
+    if (is64Bit())
+      Value = 0;
+  }
+
+  FixedValue = Value;
+  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
+                               (RelocSymbol != 0), Addend);
+  
+  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
+    Fixup.getOffset();
+
+  if (!hasRelocationAddend())
+    Addend = 0;
+  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
+  Relocations[Fragment->getParent()].push_back(ERE);
+}
+
+
 uint64_t
 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
                                              const MCSymbol *S) {
@@ -742,7 +823,7 @@ static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
   if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
     return true;
 
-  const MCSymbol &A = AliasedSymbol(Symbol);
+  const MCSymbol &A = Symbol.AliasedSymbol();
   if (!A.isVariable() && A.isUndefined() && !Data.isCommon())
     return false;
 
@@ -761,7 +842,7 @@ static bool isLocal(const MCSymbolData &Data, bool isSignature,
     return false;
 
   const MCSymbol &Symbol = Data.getSymbol();
-  const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
+  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
 
   if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
     if (isSignature && !isUsedInReloc)
@@ -830,7 +911,7 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
 
     ELFSymbolData MSD;
     MSD.SymbolData = it;
-    const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
+    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
 
     // Undefined symbols are global, but this is the first place we
     // are able to set it.
@@ -919,28 +1000,26 @@ void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
       static_cast<const MCSectionELF&>(SD.getSection());
 
     const StringRef SectionName = Section.getSectionName();
-    std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel";
+    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
     RelaSectionName += SectionName;
 
     unsigned EntrySize;
-    if (HasRelocationAddend)
-      EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
+    if (hasRelocationAddend())
+      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
     else
-      EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
+      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
 
-    RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ?
+    RelaSection = Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
                                     ELF::SHT_RELA : ELF::SHT_REL, 0,
                                     SectionKind::getReadOnly(),
                                     EntrySize, "");
 
     MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
-    RelaSD.setAlignment(Is64Bit ? 8 : 4);
+    RelaSD.setAlignment(is64Bit() ? 8 : 4);
 
     MCDataFragment *F = new MCDataFragment(&RelaSD);
 
     WriteRelocationsFragment(Asm, F, &SD);
-
-    Asm.AddSectionToTheEnd(*this, RelaSD, Layout);
   }
 }
 
@@ -972,18 +1051,20 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
   for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
     ELFRelocationEntry entry = Relocs[e - i - 1];
 
-    if (entry.Index < 0)
+    if (!entry.Index)
+      ;
+    else if (entry.Index < 0)
       entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
     else
-      entry.Index += LocalSymbolData.size() + 1;
-    if (Is64Bit) {
+      entry.Index += LocalSymbolData.size();
+    if (is64Bit()) {
       String64(*F, entry.r_offset);
 
       struct ELF::Elf64_Rela ERE64;
       ERE64.setSymbolAndType(entry.Index, entry.Type);
       String64(*F, ERE64.r_info);
 
-      if (HasRelocationAddend)
+      if (hasRelocationAddend())
         String64(*F, entry.r_addend);
     } else {
       String32(*F, entry.r_offset);
@@ -992,7 +1073,7 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
       ERE32.setSymbolAndType(entry.Index, entry.Type);
       String32(*F, ERE32.r_info);
 
-      if (HasRelocationAddend)
+      if (hasRelocationAddend())
         String32(*F, entry.r_addend);
     }
   }
@@ -1004,7 +1085,7 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
   MCContext &Ctx = Asm.getContext();
   MCDataFragment *F;
 
-  unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
+  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
 
   // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
   const MCSectionELF *ShstrtabSection =
@@ -1019,7 +1100,7 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
                       SectionKind::getReadOnly(),
                       EntrySize, "");
   MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
-  SymtabSD.setAlignment(Is64Bit ? 8 : 4);
+  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
   SymbolTableIndex = Asm.size();
 
   MCSectionData *SymtabShndxSD = NULL;
@@ -1046,14 +1127,11 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
   MCDataFragment *ShndxF = NULL;
   if (NeedsSymtabShndx) {
     ShndxF = new MCDataFragment(SymtabShndxSD);
-    Asm.AddSectionToTheEnd(*this, *SymtabShndxSD, Layout);
   }
   WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
-  Asm.AddSectionToTheEnd(*this, SymtabSD, Layout);
 
   F = new MCDataFragment(&StrtabSD);
   F->getContents().append(StringTable.begin(), StringTable.end());
-  Asm.AddSectionToTheEnd(*this, StrtabSD, Layout);
 
   F = new MCDataFragment(&ShstrtabSD);
 
@@ -1085,8 +1163,6 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
     F->getContents() += Name;
     F->getContents() += '\x00';
   }
-
-  Asm.AddSectionToTheEnd(*this, ShstrtabSD, Layout);
 }
 
 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
@@ -1105,22 +1181,34 @@ bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
   const MCSymbol *SymbolA = 0;
   if (const MCSymbolRefExpr *A = Target.getSymA()) {
     SymbolA = &A->getSymbol();
-    SectionA = &SymbolA->getSection();
+    SectionA = &SymbolA->AliasedSymbol().getSection();
   }
 
   const MCSection *SectionB = 0;
+  const MCSymbol *SymbolB = 0;
   if (const MCSymbolRefExpr *B = Target.getSymB()) {
-    SectionB = &B->getSymbol().getSection();
+    SymbolB = &B->getSymbol();
+    SectionB = &SymbolB->AliasedSymbol().getSection();
   }
 
   if (!BaseSection)
     return SectionA == SectionB;
 
+  if (SymbolB)
+    return false;
+
+  // Absolute address but PCrel instruction, so we need a relocation.
+  if (!SymbolA)
+    return false;
+
+  // FIXME: This is in here just to match gnu as output. If the two ends
+  // are in the same section, there is nothing that the linker can do to
+  // break it.
   const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA);
   if (DataA.isExternal())
     return false;
 
-  return !SectionB && BaseSection == SectionA;
+  return BaseSection == SectionA;
 }
 
 void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
@@ -1163,13 +1251,6 @@ void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
     MCDataFragment *F = new MCDataFragment(&Data);
     String32(*F, NumGroups + Index);
   }
-
-  for (RevGroupMapTy::const_iterator i = RevGroupMap.begin(),
-         e = RevGroupMap.end(); i != e; ++i) {
-    const MCSectionELF *Group = i->second;
-    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
-    Asm.AddSectionToTheEnd(*this, Data, Layout);
-  }
 }
 
 void ELFObjectWriter::WriteSection(MCAssembler &Asm,
@@ -1242,6 +1323,45 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
                    Alignment, Section.getEntrySize());
 }
 
+static bool IsELFMetaDataSection(const MCSectionData &SD) {
+  return SD.getOrdinal() == ~UINT32_C(0) &&
+    !SD.getSection().isVirtualSection();
+}
+
+static uint64_t DataSectionSize(const MCSectionData &SD) {
+  uint64_t Ret = 0;
+  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
+       ++i) {
+    const MCFragment &F = *i;
+    assert(F.getKind() == MCFragment::FT_Data);
+    Ret += cast<MCDataFragment>(F).getContents().size();
+  }
+  return Ret;
+}
+
+static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
+                                   const MCSectionData &SD) {
+  if (IsELFMetaDataSection(SD))
+    return DataSectionSize(SD);
+  return Layout.getSectionFileSize(&SD);
+}
+
+static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
+                                      const MCSectionData &SD) {
+  if (IsELFMetaDataSection(SD))
+    return DataSectionSize(SD);
+  return Layout.getSectionAddressSize(&SD);
+}
+
+static void WriteDataSectionData(ELFObjectWriter *W, const MCSectionData &SD) {
+  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
+       ++i) {
+    const MCFragment &F = *i;
+    assert(F.getKind() == MCFragment::FT_Data);
+    W->WriteBytes(cast<MCDataFragment>(F).getContents().str());
+  }
+}
+
 void ELFObjectWriter::WriteObject(MCAssembler &Asm,
                                   const MCAsmLayout &Layout) {
   GroupMapTy GroupMap;
@@ -1265,8 +1385,9 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
 
   // Add 1 for the null section.
   unsigned NumSections = Asm.size() + 1;
-  uint64_t NaturalAlignment = Is64Bit ? 8 : 4;
-  uint64_t HeaderSize = Is64Bit ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr);
+  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
+  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
+                                    sizeof(ELF::Elf32_Ehdr);
   uint64_t FileOff = HeaderSize;
 
   std::vector<const MCSectionELF*> Sections;
@@ -1285,9 +1406,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
     FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
 
     // Get the size of the section in the output file (including padding).
-    uint64_t Size = Layout.getSectionFileSize(&SD);
-
-    FileOff += Size;
+    FileOff += GetSectionFileSize(Layout, SD);
   }
 
   FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
@@ -1311,9 +1430,12 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
     // Remember the offset into the file for this section.
     SectionOffsetMap[&Section] = FileOff;
 
-    FileOff += Layout.getSectionFileSize(&SD);
+    FileOff += GetSectionFileSize(Layout, SD);
 
-    Asm.WriteSectionData(&SD, Layout, this);
+    if (IsELFMetaDataSection(SD))
+      WriteDataSectionData(this, SD);
+    else
+      Asm.WriteSectionData(&SD, Layout);
   }
 
   uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
@@ -1339,27 +1461,26 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
     else
       GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]);
 
+    uint64_t Size = GetSectionAddressSize(Layout, SD);
+
     WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
-                 SectionOffsetMap[&Section], Layout.getSectionSize(&SD),
+                 SectionOffsetMap[&Section], Size,
                  SD.getAlignment(), Section);
   }
 }
 
-MCObjectWriter *llvm::createELFObjectWriter(raw_ostream &OS,
-                                            bool Is64Bit,
-                                            Triple::OSType OSType,
-                                            uint16_t EMachine,
-                                            bool IsLittleEndian,
-                                            bool HasRelocationAddend) {
-  switch (EMachine) {
+MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                                            raw_ostream &OS,
+                                            bool IsLittleEndian) {
+  switch (MOTW->getEMachine()) {
     case ELF::EM_386:
     case ELF::EM_X86_64:
-      return new X86ELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine,
-                                    HasRelocationAddend, OSType); break;
+      return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break;
     case ELF::EM_ARM:
-      return new ARMELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine,
-                                    HasRelocationAddend, OSType); break;
-    default: assert(0 && "Unsupported architecture"); break;
+      return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
+    case ELF::EM_MBLAZE:
+      return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
+    default: llvm_unreachable("Unsupported architecture"); break;
   }
 }
 
@@ -1367,99 +1488,157 @@ MCObjectWriter *llvm::createELFObjectWriter(raw_ostream &OS,
 /// START OF SUBCLASSES for ELFObjectWriter
 //===- ARMELFObjectWriter -------------------------------------------===//
 
-ARMELFObjectWriter::ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
-                                       bool _IsLittleEndian,
-                                       uint16_t _EMachine, bool _HasRelocationAddend,
-                                       Triple::OSType _OSType)
-  : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine,
-                    _HasRelocationAddend, _OSType)
+ARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                                       raw_ostream &_OS,
+                                       bool IsLittleEndian)
+  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
 {}
 
 ARMELFObjectWriter::~ARMELFObjectWriter()
 {}
 
-void ARMELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
-                                          const MCAsmLayout &Layout,
-                                          const MCFragment *Fragment,
+unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
                                           const MCFixup &Fixup,
-                                          MCValue Target,
-                                          uint64_t &FixedValue) {
-  assert(0 && "ARMELFObjectWriter::RecordRelocation() unimplemented");
-}
-
-
-
-//===- X86ELFObjectWriter -------------------------------------------===//
-
+                                          bool IsPCRel,
+                                          bool IsRelocWithSymbol,
+                                          int64_t Addend) {
+  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
+    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
 
-X86ELFObjectWriter::X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
-                                       bool _IsLittleEndian,
-                                       uint16_t _EMachine, bool _HasRelocationAddend,
-                                       Triple::OSType _OSType)
-  : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine,
-                    _HasRelocationAddend, _OSType)
-{}
+  unsigned Type = 0;
+  if (IsPCRel) {
+    switch ((unsigned)Fixup.getKind()) {
+    default: assert(0 && "Unimplemented");
+    case FK_Data_4:
+      switch (Modifier) {
+      default: llvm_unreachable("Unsupported Modifier");
+      case MCSymbolRefExpr::VK_None:
+        Type = ELF::R_ARM_BASE_PREL; break;
+      case MCSymbolRefExpr::VK_ARM_TLSGD:
+        assert(0 && "unimplemented"); break;
+      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
+        Type = ELF::R_ARM_TLS_IE32;
+      } break;
+    case ARM::fixup_arm_branch:
+      switch (Modifier) {
+      case MCSymbolRefExpr::VK_ARM_PLT:
+        Type = ELF::R_ARM_PLT32; break;
+      default:
+        Type = ELF::R_ARM_CALL; break;
+      } break;
+    }
+  } else {
+    switch ((unsigned)Fixup.getKind()) {
+    default: llvm_unreachable("invalid fixup kind!");
+    case FK_Data_4:
+      switch (Modifier) {
+      default: llvm_unreachable("Unsupported Modifier"); break;
+      case MCSymbolRefExpr::VK_ARM_GOT:
+        Type = ELF::R_ARM_GOT_BREL; break;
+      case MCSymbolRefExpr::VK_ARM_TLSGD:
+        Type = ELF::R_ARM_TLS_GD32; break;
+      case MCSymbolRefExpr::VK_ARM_TPOFF:
+        Type = ELF::R_ARM_TLS_LE32; break;
+      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
+        Type = ELF::R_ARM_TLS_IE32; break;
+      case MCSymbolRefExpr::VK_None:
+        Type = ELF::R_ARM_ABS32; break;
+      case MCSymbolRefExpr::VK_ARM_GOTOFF:
+        Type = ELF::R_ARM_GOTOFF32; break;
+      } break;
+    case ARM::fixup_arm_ldst_pcrel_12:
+    case ARM::fixup_arm_pcrel_10:
+    case ARM::fixup_arm_adr_pcrel_12:
+    case ARM::fixup_arm_thumb_bl:
+    case ARM::fixup_arm_thumb_cb:
+    case ARM::fixup_arm_thumb_cp:
+    case ARM::fixup_arm_thumb_br:
+      assert(0 && "Unimplemented"); break;
+    case ARM::fixup_arm_branch:
+      // FIXME: Differentiate between R_ARM_CALL and
+      // R_ARM_JUMP24 (latter used for conditional jumps)
+      Type = ELF::R_ARM_CALL; break;
+    case ARM::fixup_arm_movt_hi16: 
+      Type = ELF::R_ARM_MOVT_ABS; break;
+    case ARM::fixup_arm_movw_lo16:
+      Type = ELF::R_ARM_MOVW_ABS_NC; break;
+    }
+  }
 
-X86ELFObjectWriter::~X86ELFObjectWriter()
-{}
+  if (RelocNeedsGOT(Modifier))
+    NeedsGOT = true;
+  
+  return Type;
+}
 
-void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
-                                       const MCAsmLayout &Layout,
-                                       const MCFragment *Fragment,
-                                       const MCFixup &Fixup,
-                                       MCValue Target,
-                                       uint64_t &FixedValue) {
-  int64_t Addend = 0;
-  int Index = 0;
-  int64_t Value = Target.getConstant();
-  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
-  const MCSymbol *RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
+//===- MBlazeELFObjectWriter -------------------------------------------===//
 
-  bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
-  if (!Target.isAbsolute()) {
-    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
-      const MCSymbol &SymbolB = RefB->getSymbol();
-      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
-      IsPCRel = true;
-      MCSectionData *Sec = Fragment->getParent();
+MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                                             raw_ostream &_OS,
+                                             bool IsLittleEndian)
+  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
+}
 
-      // Offset of the symbol in the section
-      int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
+MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
+}
 
-      // Ofeset of the relocation in the section
-      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
-      Value += b - a;
+unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
+                                             const MCFixup &Fixup,
+                                             bool IsPCRel,
+                                             bool IsRelocWithSymbol,
+                                             int64_t Addend) {
+  // determine the type of the relocation
+  unsigned Type;
+  if (IsPCRel) {
+    switch ((unsigned)Fixup.getKind()) {
+    default:
+      llvm_unreachable("Unimplemented");
+    case FK_PCRel_4:
+      Type = ELF::R_MICROBLAZE_64_PCREL;
+      break;
+    case FK_PCRel_2:
+      Type = ELF::R_MICROBLAZE_32_PCREL;
+      break;
     }
+  } else {
+    switch ((unsigned)Fixup.getKind()) {
+    default: llvm_unreachable("invalid fixup kind!");
+    case FK_Data_4:
+      Type = ((IsRelocWithSymbol || Addend !=0)
+              ? ELF::R_MICROBLAZE_32
+              : ELF::R_MICROBLAZE_64);
+      break;
+    case FK_Data_2:
+      Type = ELF::R_MICROBLAZE_32;
+      break;
+    }
+  }
+  return Type;
+}
 
-    if (!RelocSymbol) {
-      MCSymbolData &SD = Asm.getSymbolData(Symbol);
-      MCFragment *F = SD.getFragment();
+//===- X86ELFObjectWriter -------------------------------------------===//
 
-      Index = F->getParent()->getOrdinal();
 
-      MCSectionData *FSD = F->getParent();
-      // Offset of the symbol in the section
-      Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
-    } else {
-      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
-        WeakrefUsedInReloc.insert(RelocSymbol);
-      else
-        UsedInReloc.insert(RelocSymbol);
-      Index = -1;
-    }
-    Addend = Value;
-    // Compensate for the addend on i386.
-    if (Is64Bit)
-      Value = 0;
-  }
+X86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                                       raw_ostream &_OS,
+                                       bool IsLittleEndian)
+  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
+{}
 
-  FixedValue = Value;
+X86ELFObjectWriter::~X86ELFObjectWriter()
+{}
 
+unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
+                                          const MCFixup &Fixup,
+                                          bool IsPCRel,
+                                          bool IsRelocWithSymbol,
+                                          int64_t Addend) {
   // determine the type of the relocation
 
-  MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
+  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
+    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
   unsigned Type;
-  if (Is64Bit) {
+  if (is64Bit()) {
     if (IsPCRel) {
       switch (Modifier) {
       default:
@@ -1488,7 +1667,7 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
       default: llvm_unreachable("invalid fixup kind!");
       case FK_Data_8: Type = ELF::R_X86_64_64; break;
       case X86::reloc_signed_4byte:
-      case X86::reloc_pcrel_4byte:
+      case FK_PCRel_4:
         assert(isInt<32>(Target.getConstant()));
         switch (Modifier) {
         default:
@@ -1514,7 +1693,7 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
         Type = ELF::R_X86_64_32;
         break;
       case FK_Data_2: Type = ELF::R_X86_64_16; break;
-      case X86::reloc_pcrel_1byte:
+      case FK_PCRel_1:
       case FK_Data_1: Type = ELF::R_X86_64_8; break;
       }
     }
@@ -1541,7 +1720,7 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
       // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
       // instead?
       case X86::reloc_signed_4byte:
-      case X86::reloc_pcrel_4byte:
+      case FK_PCRel_4:
       case FK_Data_4:
         switch (Modifier) {
         default:
@@ -1579,7 +1758,7 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
         }
         break;
       case FK_Data_2: Type = ELF::R_386_16; break;
-      case X86::reloc_pcrel_1byte:
+      case FK_PCRel_1:
       case FK_Data_1: Type = ELF::R_386_8; break;
       }
     }
@@ -1588,18 +1767,5 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
   if (RelocNeedsGOT(Modifier))
     NeedsGOT = true;
 
-  ELFRelocationEntry ERE;
-
-  ERE.Index = Index;
-  ERE.Type = Type;
-  ERE.Symbol = RelocSymbol;
-
-  ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
-
-  if (HasRelocationAddend)
-    ERE.r_addend = Addend;
-  else
-    ERE.r_addend = 0; // Silence compiler warning.
-
-  Relocations[Fragment->getParent()].push_back(ERE);
+  return Type;
 }