Write => in a more normal form.
[oota-llvm.git] / lib / MC / ELFObjectWriter.cpp
index b80d6ca1f84d8f6c20f256237139b67275135874..93c3b09e9881d6a00bfe790cb3f418bef0bb1c0e 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "../Target/X86/X86FixupKinds.h"
 #include "../Target/ARM/ARMFixupKinds.h"
-#include "../Target/MBlaze/MBlazeFixupKinds.h"
 
 #include <vector>
 using namespace llvm;
@@ -129,11 +128,11 @@ namespace {
       ELFRelocationEntry()
         : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
 
-      ELFRelocationEntry(uint64_t RelocOffset, int _Index,
-                         unsigned _Type, const MCSymbol *_Symbol,
+      ELFRelocationEntry(uint64_t RelocOffset, int Idx,
+                         unsigned RelType, const MCSymbol *Sym,
                          uint64_t Addend)
-        : r_offset(RelocOffset), Index(_Index), Type(_Type),
-          Symbol(_Symbol), r_addend(Addend) {}
+        : r_offset(RelocOffset), Index(Idx), Type(RelType),
+          Symbol(Sym), r_addend(Addend) {}
 
       // Support lexicographic sorting.
       bool operator<(const ELFRelocationEntry &RE) const {
@@ -287,10 +286,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,7 +325,8 @@ 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,
@@ -349,6 +347,13 @@ 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;
+
+    virtual bool isFixupKindPCRel(unsigned Kind) const = 0;
   };
 
   //===- X86ELFObjectWriter -------------------------------------------===//
@@ -360,18 +365,18 @@ namespace {
                        Triple::OSType _OSType);
 
     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);
 
-    static bool isFixupKindPCRel(unsigned Kind) {
+    virtual bool isFixupKindPCRel(unsigned Kind) const {
       switch (Kind) {
       default:
         return false;
-      case X86::reloc_pcrel_1byte:
-      case X86::reloc_pcrel_4byte:
+      case FK_PCRel_1:
+      case FK_PCRel_2:
+      case FK_PCRel_4:
       case X86::reloc_riprel_4byte:
       case X86::reloc_riprel_4byte_movq_load:
         return true;
@@ -389,22 +394,23 @@ namespace {
                        Triple::OSType _OSType);
 
     virtual ~ARMELFObjectWriter();
-    virtual void RecordRelocation(const MCAssembler &Asm,
-                                  const MCAsmLayout &Layout,
-                                  const MCFragment *Fragment,
-                                  const MCFixup &Fixup, MCValue Target,
-                                  uint64_t &FixedValue);
-
-    static bool isFixupKindPCRel(unsigned Kind) {
+  protected:
+    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                  bool IsPCRel, bool IsRelocWithSymbol,
+                                  int64_t Addend);
+    virtual bool isFixupKindPCRel(unsigned Kind) const {
       switch (Kind) {
       default:
         return false;
-      case MBlaze::reloc_pcrel_2byte:
-      case MBlaze::reloc_pcrel_4byte:
+      case FK_PCRel_1:
+      case FK_PCRel_2:
+      case FK_PCRel_4:
+      case ARM::fixup_arm_ldst_pcrel_12:
+      case ARM::fixup_arm_pcrel_10:
+      case ARM::fixup_arm_branch:
         return true;
       }
     }
-
   };
 
   //===- MBlazeELFObjectWriter -------------------------------------------===//
@@ -416,19 +422,18 @@ namespace {
                           Triple::OSType _OSType);
 
     virtual ~MBlazeELFObjectWriter();
-    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);
 
-    static bool isFixupKindPCRel(unsigned Kind) {
+    virtual bool isFixupKindPCRel(unsigned Kind) const {
       switch (Kind) {
       default:
         return false;
-      case ARM::fixup_arm_pcrel_12:
-      case ARM::fixup_arm_vfp_pcrel_12:
-      case ARM::fixup_arm_branch:
+      case FK_PCRel_1:
+      case FK_PCRel_2:
+      case FK_PCRel_4:
         return true;
       }
     }
@@ -547,14 +552,14 @@ static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) {
   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;
 }
 
-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.
 
@@ -716,10 +721,17 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
 
   const MCSectionELF &Section =
     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());
@@ -745,6 +757,70 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
 }
 
 
+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(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) {
@@ -965,8 +1041,6 @@ void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
     MCDataFragment *F = new MCDataFragment(&RelaSD);
 
     WriteRelocationsFragment(Asm, F, &SD);
-
-    Asm.AddSectionToTheEnd(*this, RelaSD, Layout);
   }
 }
 
@@ -1074,14 +1148,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);
 
@@ -1113,8 +1184,6 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
     F->getContents() += Name;
     F->getContents() += '\x00';
   }
-
-  Asm.AddSectionToTheEnd(*this, ShstrtabSD, Layout);
 }
 
 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
@@ -1203,13 +1272,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,
@@ -1282,6 +1344,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;
@@ -1325,9 +1426,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);
@@ -1351,9 +1450,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, this);
   }
 
   uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
@@ -1379,8 +1481,10 @@ 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);
   }
 }
@@ -1421,13 +1525,78 @@ ARMELFObjectWriter::ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
 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");
+                                          bool IsPCRel,
+                                          bool IsRelocWithSymbol,
+                                          int64_t Addend) {
+  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
+    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+
+  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;
+    }
+  }
+
+  if (RelocNeedsGOT(Modifier))
+    NeedsGOT = true;
+  
+  return Type;
 }
 
 //===- MBlazeELFObjectWriter -------------------------------------------===//
@@ -1444,66 +1613,21 @@ MBlazeELFObjectWriter::MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
 MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
 }
 
-void MBlazeELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
-                                             const MCAsmLayout &Layout,
-                                             const MCFragment *Fragment,
+unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
                                              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 &ASymbol = Symbol.AliasedSymbol();
-  const MCSymbol *RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
-
-  bool IsPCRel = isFixupKindPCRel(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();
-
-      // Offset of the symbol in the section
-      int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
-
-      // 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();
-
-      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;
-  }
-
-  FixedValue = Value;
-
+                                             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 MBlaze::reloc_pcrel_4byte:
+    case FK_PCRel_4:
       Type = ELF::R_MICROBLAZE_64_PCREL;
       break;
-    case MBlaze::reloc_pcrel_2byte:
+    case FK_PCRel_2:
       Type = ELF::R_MICROBLAZE_32_PCREL;
       break;
     }
@@ -1511,25 +1635,16 @@ void MBlazeELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
     switch ((unsigned)Fixup.getKind()) {
     default: llvm_unreachable("invalid fixup kind!");
     case FK_Data_4:
-      Type = (RelocSymbol || Addend !=0) ? ELF::R_MICROBLAZE_32
-                                         : ELF::R_MICROBLAZE_64;
+      Type = ((IsRelocWithSymbol || Addend !=0)
+              ? ELF::R_MICROBLAZE_32
+              : ELF::R_MICROBLAZE_64);
       break;
     case FK_Data_2:
       Type = ELF::R_MICROBLAZE_32;
       break;
     }
   }
-
-  MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
-  if (RelocNeedsGOT(Modifier))
-    NeedsGOT = true;
-
-  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);
+  return Type;
 }
 
 //===- X86ELFObjectWriter -------------------------------------------===//
@@ -1546,61 +1661,11 @@ X86ELFObjectWriter::X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit,
 X86ELFObjectWriter::~X86ELFObjectWriter()
 {}
 
-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 *RelocSymbol = NULL;
-
-  bool IsPCRel = isFixupKindPCRel(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;
-      MCSectionData *Sec = Fragment->getParent();
-
-      // Offset of the symbol in the section
-      int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
-
-      // 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;
-
-      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;
-  }
-
-  FixedValue = Value;
-
+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.isAbsolute() ?
@@ -1635,7 +1700,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:
@@ -1661,7 +1726,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;
       }
     }
@@ -1688,7 +1753,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:
@@ -1726,7 +1791,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;
       }
     }
@@ -1735,11 +1800,5 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
   if (RelocNeedsGOT(Modifier))
     NeedsGOT = true;
 
-
-  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);
+  return Type;
 }