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

Generated by: LCOV version 1.13