LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMELFObjectWriter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 91 121 75.2 %
Date: 2018-02-19 17:12:42 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "MCTargetDesc/ARMFixupKinds.h"
      11             : #include "MCTargetDesc/ARMMCTargetDesc.h"
      12             : #include "llvm/BinaryFormat/ELF.h"
      13             : #include "llvm/MC/MCContext.h"
      14             : #include "llvm/MC/MCELFObjectWriter.h"
      15             : #include "llvm/MC/MCExpr.h"
      16             : #include "llvm/MC/MCFixup.h"
      17             : #include "llvm/MC/MCObjectWriter.h"
      18             : #include "llvm/MC/MCValue.h"
      19             : #include "llvm/Support/ErrorHandling.h"
      20             : #include "llvm/Support/raw_ostream.h"
      21             : #include <cstdint>
      22             : 
      23             : using namespace llvm;
      24             : 
      25             : namespace {
      26             : 
      27             :   class ARMELFObjectWriter : public MCELFObjectTargetWriter {
      28             :     enum { DefaultEABIVersion = 0x05000000U };
      29             : 
      30             :     unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
      31             :                                bool IsPCRel, MCContext &Ctx) const;
      32             : 
      33             :   public:
      34             :     ARMELFObjectWriter(uint8_t OSABI);
      35             : 
      36         378 :     ~ARMELFObjectWriter() override = default;
      37             : 
      38             :     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
      39             :                           const MCFixup &Fixup, bool IsPCRel) const override;
      40             : 
      41             :     bool needsRelocateWithSymbol(const MCSymbol &Sym,
      42             :                                  unsigned Type) const override;
      43             :   };
      44             : 
      45             : } // end anonymous namespace
      46             : 
      47         383 : ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
      48             :   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
      49             :                             ELF::EM_ARM,
      50         383 :                             /*HasRelocationAddend*/ false) {}
      51             : 
      52        1009 : bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
      53             :                                                  unsigned Type) const {
      54             :   // FIXME: This is extremely conservative. This really needs to use a
      55             :   // whitelist with a clear explanation for why each realocation needs to
      56             :   // point to the symbol, not to the section.
      57        1009 :   switch (Type) {
      58             :   default:
      59             :     return true;
      60             : 
      61         930 :   case ELF::R_ARM_PREL31:
      62             :   case ELF::R_ARM_ABS32:
      63         930 :     return false;
      64             :   }
      65             : }
      66             : 
      67             : // Need to examine the Fixup when determining whether to 
      68             : // emit the relocation as an explicit symbol or as a section relative
      69             : // offset
      70        2392 : unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
      71             :                                           const MCFixup &Fixup,
      72             :                                           bool IsPCRel) const {
      73        2392 :   return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
      74             : }
      75             : 
      76        2392 : unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
      77             :                                                const MCFixup &Fixup,
      78             :                                                bool IsPCRel,
      79             :                                                MCContext &Ctx) const {
      80        2392 :   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
      81             : 
      82        2392 :   if (IsPCRel) {
      83         669 :     switch ((unsigned)Fixup.getKind()) {
      84             :     default:
      85           2 :       Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
      86             :       return ELF::R_ARM_NONE;
      87           7 :     case FK_Data_4:
      88           7 :       switch (Modifier) {
      89           0 :       default:
      90           0 :         llvm_unreachable("Unsupported Modifier");
      91             :       case MCSymbolRefExpr::VK_None:
      92             :         return ELF::R_ARM_REL32;
      93           0 :       case MCSymbolRefExpr::VK_GOTTPOFF:
      94           0 :         return ELF::R_ARM_TLS_IE32;
      95           0 :       case MCSymbolRefExpr::VK_ARM_GOT_PREL:
      96           0 :         return ELF::R_ARM_GOT_PREL;
      97           4 :       case MCSymbolRefExpr::VK_ARM_PREL31:
      98           4 :         return ELF::R_ARM_PREL31;
      99             :       }
     100         228 :     case ARM::fixup_arm_blx:
     101             :     case ARM::fixup_arm_uncondbl:
     102         228 :       switch (Modifier) {
     103             :       case MCSymbolRefExpr::VK_PLT:
     104             :         return ELF::R_ARM_CALL;
     105           0 :       case MCSymbolRefExpr::VK_TLSCALL:
     106           0 :         return ELF::R_ARM_TLS_CALL;
     107             :       default:
     108             :         return ELF::R_ARM_CALL;
     109             :       }
     110             :     case ARM::fixup_arm_condbl:
     111             :     case ARM::fixup_arm_condbranch:
     112             :     case ARM::fixup_arm_uncondbranch:
     113             :       return ELF::R_ARM_JUMP24;
     114          17 :     case ARM::fixup_t2_condbranch:
     115          17 :       return ELF::R_ARM_THM_JUMP19;
     116          31 :     case ARM::fixup_t2_uncondbranch:
     117          31 :       return ELF::R_ARM_THM_JUMP24;
     118           8 :     case ARM::fixup_arm_movt_hi16:
     119           8 :       return ELF::R_ARM_MOVT_PREL;
     120           7 :     case ARM::fixup_arm_movw_lo16:
     121           7 :       return ELF::R_ARM_MOVW_PREL_NC;
     122           8 :     case ARM::fixup_t2_movt_hi16:
     123           8 :       return ELF::R_ARM_THM_MOVT_PREL;
     124           7 :     case ARM::fixup_t2_movw_lo16:
     125           7 :       return ELF::R_ARM_THM_MOVW_PREL_NC;
     126           1 :     case ARM::fixup_arm_thumb_br:
     127           1 :       return ELF::R_ARM_THM_JUMP11;
     128           1 :     case ARM::fixup_arm_thumb_bcc:
     129           1 :       return ELF::R_ARM_THM_JUMP8;
     130         317 :     case ARM::fixup_arm_thumb_bl:
     131             :     case ARM::fixup_arm_thumb_blx:
     132         317 :       switch (Modifier) {
     133             :       case MCSymbolRefExpr::VK_TLSCALL:
     134             :         return ELF::R_ARM_THM_TLS_CALL;
     135         317 :       default:
     136         317 :         return ELF::R_ARM_THM_CALL;
     137             :       }
     138             :     }
     139             :   }
     140        1723 :   switch ((unsigned)Fixup.getKind()) {
     141             :   default:
     142           2 :     Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
     143             :     return ELF::R_ARM_NONE;
     144           4 :   case FK_Data_1:
     145           4 :     switch (Modifier) {
     146           0 :     default:
     147           0 :       llvm_unreachable("unsupported Modifier");
     148             :     case MCSymbolRefExpr::VK_None:
     149             :       return ELF::R_ARM_ABS8;
     150             :     }
     151           4 :   case FK_Data_2:
     152           4 :     switch (Modifier) {
     153           0 :     default:
     154           0 :       llvm_unreachable("unsupported modifier");
     155             :     case MCSymbolRefExpr::VK_None:
     156             :       return ELF::R_ARM_ABS16;
     157             :     }
     158        1647 :   case FK_Data_4:
     159        1647 :     switch (Modifier) {
     160           0 :     default:
     161           0 :       llvm_unreachable("Unsupported Modifier");
     162             :     case MCSymbolRefExpr::VK_ARM_NONE:
     163             :       return ELF::R_ARM_NONE;
     164           9 :     case MCSymbolRefExpr::VK_GOT:
     165           9 :       return ELF::R_ARM_GOT_BREL;
     166          17 :     case MCSymbolRefExpr::VK_TLSGD:
     167          17 :       return ELF::R_ARM_TLS_GD32;
     168           8 :     case MCSymbolRefExpr::VK_TPOFF:
     169           8 :       return ELF::R_ARM_TLS_LE32;
     170           8 :     case MCSymbolRefExpr::VK_GOTTPOFF:
     171           8 :       return ELF::R_ARM_TLS_IE32;
     172         229 :     case MCSymbolRefExpr::VK_None:
     173         229 :       return ELF::R_ARM_ABS32;
     174           7 :     case MCSymbolRefExpr::VK_GOTOFF:
     175           7 :       return ELF::R_ARM_GOTOFF32;
     176           5 :     case MCSymbolRefExpr::VK_ARM_GOT_PREL:
     177           5 :       return ELF::R_ARM_GOT_PREL;
     178           6 :     case MCSymbolRefExpr::VK_ARM_TARGET1:
     179           6 :       return ELF::R_ARM_TARGET1;
     180           5 :     case MCSymbolRefExpr::VK_ARM_TARGET2:
     181           5 :       return ELF::R_ARM_TARGET2;
     182         871 :     case MCSymbolRefExpr::VK_ARM_PREL31:
     183         871 :       return ELF::R_ARM_PREL31;
     184           8 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     185           8 :       return ELF::R_ARM_SBREL32;
     186           8 :     case MCSymbolRefExpr::VK_ARM_TLSLDO:
     187           8 :       return ELF::R_ARM_TLS_LDO32;
     188           4 :     case MCSymbolRefExpr::VK_TLSCALL:
     189           4 :       return ELF::R_ARM_TLS_CALL;
     190           5 :     case MCSymbolRefExpr::VK_TLSDESC:
     191           5 :       return ELF::R_ARM_TLS_GOTDESC;
     192           6 :     case MCSymbolRefExpr::VK_TLSLDM:
     193           6 :       return ELF::R_ARM_TLS_LDM32;
     194           3 :     case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
     195           3 :       return ELF::R_ARM_TLS_DESCSEQ;
     196             :     }
     197             :   case ARM::fixup_arm_condbranch:
     198             :   case ARM::fixup_arm_uncondbranch:
     199             :     return ELF::R_ARM_JUMP24;
     200          19 :   case ARM::fixup_arm_movt_hi16:
     201          19 :     switch (Modifier) {
     202           0 :     default:
     203           0 :       llvm_unreachable("Unsupported Modifier");
     204             :     case MCSymbolRefExpr::VK_None:
     205             :       return ELF::R_ARM_MOVT_ABS;
     206           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     207           0 :       return ELF::R_ARM_MOVT_BREL;
     208             :     }
     209          22 :   case ARM::fixup_arm_movw_lo16:
     210          22 :     switch (Modifier) {
     211           0 :     default:
     212           0 :       llvm_unreachable("Unsupported Modifier");
     213             :     case MCSymbolRefExpr::VK_None:
     214             :       return ELF::R_ARM_MOVW_ABS_NC;
     215           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     216           0 :       return ELF::R_ARM_MOVW_BREL_NC;
     217             :     }
     218          12 :   case ARM::fixup_t2_movt_hi16:
     219          12 :     switch (Modifier) {
     220           0 :     default:
     221           0 :       llvm_unreachable("Unsupported Modifier");
     222             :     case MCSymbolRefExpr::VK_None:
     223             :       return ELF::R_ARM_THM_MOVT_ABS;
     224           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     225           0 :       return ELF::R_ARM_THM_MOVT_BREL;
     226             :     }
     227          13 :   case ARM::fixup_t2_movw_lo16:
     228          13 :     switch (Modifier) {
     229           0 :     default:
     230           0 :       llvm_unreachable("Unsupported Modifier");
     231             :     case MCSymbolRefExpr::VK_None:
     232             :       return ELF::R_ARM_THM_MOVW_ABS_NC;
     233           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     234           0 :       return ELF::R_ARM_THM_MOVW_BREL_NC;
     235             :     }
     236             :   }
     237             : }
     238             : 
     239             : std::unique_ptr<MCObjectWriter>
     240         383 : llvm::createARMELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI,
     241             :                                bool IsLittleEndian) {
     242         766 :   return createELFObjectWriter(llvm::make_unique<ARMELFObjectWriter>(OSABI), OS,
     243        1532 :                                IsLittleEndian);
     244             : }

Generated by: LCOV version 1.13