Write => in a more normal form.
[oota-llvm.git] / lib / MC / ELFObjectWriter.cpp
index 4daab49089aca36b34a04764900a29c40f6f1b2e..93c3b09e9881d6a00bfe790cb3f418bef0bb1c0e 100644 (file)
@@ -325,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,
@@ -557,7 +558,8 @@ static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) {
   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.
 
@@ -1365,11 +1367,11 @@ static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
   return Layout.getSectionFileSize(&SD);
 }
 
-static uint64_t GetSectionSize(const MCAsmLayout &Layout,
-                                   const MCSectionData &SD) {
+static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
+                                      const MCSectionData &SD) {
   if (IsELFMetaDataSection(SD))
     return DataSectionSize(SD);
-  return Layout.getSectionSize(&SD);
+  return Layout.getSectionAddressSize(&SD);
 }
 
 static void WriteDataSectionData(ELFObjectWriter *W, const MCSectionData &SD) {
@@ -1479,7 +1481,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
     else
       GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]);
 
-    uint64_t Size = GetSectionSize(Layout, SD);
+    uint64_t Size = GetSectionAddressSize(Layout, SD);
 
     WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
                  SectionOffsetMap[&Section], Size,
@@ -1531,35 +1533,70 @@ unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
   MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
     MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
 
+  unsigned Type = 0;
   if (IsPCRel) {
-    switch (Modifier) {
-    default: assert(0 && "Unimplemented Modifier");
-    case MCSymbolRefExpr::VK_None: break;
-    }
     switch ((unsigned)Fixup.getKind()) {
     default: assert(0 && "Unimplemented");
-    case ARM::fixup_arm_branch: return ELF::R_ARM_CALL; break;
+    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:
-      return ELF::R_ARM_CALL; break;
+      // 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: 
-      return ELF::R_ARM_MOVT_ABS; break;
+      Type = ELF::R_ARM_MOVT_ABS; break;
     case ARM::fixup_arm_movw_lo16:
-      return ELF::R_ARM_MOVW_ABS_NC; break;
+      Type = ELF::R_ARM_MOVW_ABS_NC; break;
     }
   }
 
   if (RelocNeedsGOT(Modifier))
     NeedsGOT = true;
-  return -1;
+  
+  return Type;
 }
 
 //===- MBlazeELFObjectWriter -------------------------------------------===//