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 125 74.4 %
Date: 2018-10-20 13:21:21 Functions: 6 7 85.7 %
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/MCObjectFileInfo.h"
      18             : #include "llvm/MC/MCObjectWriter.h"
      19             : #include "llvm/MC/MCValue.h"
      20             : #include "llvm/Support/ErrorHandling.h"
      21             : #include "llvm/Support/raw_ostream.h"
      22             : #include <cstdint>
      23             : 
      24             : using namespace llvm;
      25             : 
      26             : namespace {
      27             : 
      28             :   class ARMELFObjectWriter : public MCELFObjectTargetWriter {
      29             :     enum { DefaultEABIVersion = 0x05000000U };
      30             : 
      31             :     unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
      32             :                                bool IsPCRel, MCContext &Ctx) const;
      33             : 
      34             :   public:
      35             :     ARMELFObjectWriter(uint8_t OSABI);
      36             : 
      37        2986 :     ~ARMELFObjectWriter() override = default;
      38             : 
      39             :     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
      40             :                           const MCFixup &Fixup, bool IsPCRel) const override;
      41             : 
      42             :     bool needsRelocateWithSymbol(const MCSymbol &Sym,
      43             :                                  unsigned Type) const override;
      44             : 
      45             :     void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
      46             :   };
      47             : 
      48             : } // end anonymous namespace
      49             : 
      50           0 : ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
      51             :   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
      52             :                             ELF::EM_ARM,
      53           0 :                             /*HasRelocationAddend*/ false) {}
      54             : 
      55        1034 : bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
      56             :                                                  unsigned Type) const {
      57             :   // FIXME: This is extremely conservative. This really needs to use a
      58             :   // whitelist with a clear explanation for why each realocation needs to
      59             :   // point to the symbol, not to the section.
      60        1034 :   switch (Type) {
      61             :   default:
      62             :     return true;
      63             : 
      64         952 :   case ELF::R_ARM_PREL31:
      65             :   case ELF::R_ARM_ABS32:
      66         952 :     return false;
      67             :   }
      68             : }
      69             : 
      70             : // Need to examine the Fixup when determining whether to
      71             : // emit the relocation as an explicit symbol or as a section relative
      72             : // offset
      73        2498 : unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
      74             :                                           const MCFixup &Fixup,
      75             :                                           bool IsPCRel) const {
      76        2498 :   return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
      77             : }
      78             : 
      79        2498 : unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
      80             :                                                const MCFixup &Fixup,
      81             :                                                bool IsPCRel,
      82             :                                                MCContext &Ctx) const {
      83        2498 :   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
      84             : 
      85        2498 :   if (IsPCRel) {
      86         705 :     switch ((unsigned)Fixup.getKind()) {
      87             :     default:
      88           2 :       Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
      89             :       return ELF::R_ARM_NONE;
      90           7 :     case FK_Data_4:
      91           7 :       switch (Modifier) {
      92           0 :       default:
      93           0 :         llvm_unreachable("Unsupported Modifier");
      94             :       case MCSymbolRefExpr::VK_None:
      95             :         return ELF::R_ARM_REL32;
      96           0 :       case MCSymbolRefExpr::VK_GOTTPOFF:
      97           0 :         return ELF::R_ARM_TLS_IE32;
      98           0 :       case MCSymbolRefExpr::VK_ARM_GOT_PREL:
      99           0 :         return ELF::R_ARM_GOT_PREL;
     100           4 :       case MCSymbolRefExpr::VK_ARM_PREL31:
     101           4 :         return ELF::R_ARM_PREL31;
     102             :       }
     103         234 :     case ARM::fixup_arm_blx:
     104             :     case ARM::fixup_arm_uncondbl:
     105         234 :       switch (Modifier) {
     106             :       case MCSymbolRefExpr::VK_PLT:
     107             :         return ELF::R_ARM_CALL;
     108           0 :       case MCSymbolRefExpr::VK_TLSCALL:
     109           0 :         return ELF::R_ARM_TLS_CALL;
     110             :       default:
     111             :         return ELF::R_ARM_CALL;
     112             :       }
     113             :     case ARM::fixup_arm_condbl:
     114             :     case ARM::fixup_arm_condbranch:
     115             :     case ARM::fixup_arm_uncondbranch:
     116             :       return ELF::R_ARM_JUMP24;
     117          19 :     case ARM::fixup_t2_condbranch:
     118          19 :       return ELF::R_ARM_THM_JUMP19;
     119          34 :     case ARM::fixup_t2_uncondbranch:
     120          34 :       return ELF::R_ARM_THM_JUMP24;
     121           8 :     case ARM::fixup_arm_movt_hi16:
     122           8 :       return ELF::R_ARM_MOVT_PREL;
     123           7 :     case ARM::fixup_arm_movw_lo16:
     124           7 :       return ELF::R_ARM_MOVW_PREL_NC;
     125           8 :     case ARM::fixup_t2_movt_hi16:
     126           8 :       return ELF::R_ARM_THM_MOVT_PREL;
     127           7 :     case ARM::fixup_t2_movw_lo16:
     128           7 :       return ELF::R_ARM_THM_MOVW_PREL_NC;
     129           1 :     case ARM::fixup_arm_thumb_br:
     130           1 :       return ELF::R_ARM_THM_JUMP11;
     131           1 :     case ARM::fixup_arm_thumb_bcc:
     132           1 :       return ELF::R_ARM_THM_JUMP8;
     133         339 :     case ARM::fixup_arm_thumb_bl:
     134             :     case ARM::fixup_arm_thumb_blx:
     135         339 :       switch (Modifier) {
     136             :       case MCSymbolRefExpr::VK_TLSCALL:
     137             :         return ELF::R_ARM_THM_TLS_CALL;
     138         339 :       default:
     139         339 :         return ELF::R_ARM_THM_CALL;
     140             :       }
     141             :     }
     142             :   }
     143        1793 :   switch ((unsigned)Fixup.getKind()) {
     144             :   default:
     145           2 :     Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
     146             :     return ELF::R_ARM_NONE;
     147           4 :   case FK_Data_1:
     148           4 :     switch (Modifier) {
     149           0 :     default:
     150           0 :       llvm_unreachable("unsupported Modifier");
     151             :     case MCSymbolRefExpr::VK_None:
     152             :       return ELF::R_ARM_ABS8;
     153             :     }
     154           4 :   case FK_Data_2:
     155           4 :     switch (Modifier) {
     156           0 :     default:
     157           0 :       llvm_unreachable("unsupported modifier");
     158             :     case MCSymbolRefExpr::VK_None:
     159             :       return ELF::R_ARM_ABS16;
     160             :     }
     161        1717 :   case FK_Data_4:
     162        1717 :     switch (Modifier) {
     163           0 :     default:
     164           0 :       llvm_unreachable("Unsupported Modifier");
     165             :     case MCSymbolRefExpr::VK_ARM_NONE:
     166             :       return ELF::R_ARM_NONE;
     167           9 :     case MCSymbolRefExpr::VK_GOT:
     168           9 :       return ELF::R_ARM_GOT_BREL;
     169          17 :     case MCSymbolRefExpr::VK_TLSGD:
     170          17 :       return ELF::R_ARM_TLS_GD32;
     171           8 :     case MCSymbolRefExpr::VK_TPOFF:
     172           8 :       return ELF::R_ARM_TLS_LE32;
     173           8 :     case MCSymbolRefExpr::VK_GOTTPOFF:
     174           8 :       return ELF::R_ARM_TLS_IE32;
     175         284 :     case MCSymbolRefExpr::VK_None:
     176         284 :       return ELF::R_ARM_ABS32;
     177           7 :     case MCSymbolRefExpr::VK_GOTOFF:
     178           7 :       return ELF::R_ARM_GOTOFF32;
     179           5 :     case MCSymbolRefExpr::VK_ARM_GOT_PREL:
     180           5 :       return ELF::R_ARM_GOT_PREL;
     181           6 :     case MCSymbolRefExpr::VK_ARM_TARGET1:
     182           6 :       return ELF::R_ARM_TARGET1;
     183           5 :     case MCSymbolRefExpr::VK_ARM_TARGET2:
     184           5 :       return ELF::R_ARM_TARGET2;
     185         880 :     case MCSymbolRefExpr::VK_ARM_PREL31:
     186         880 :       return ELF::R_ARM_PREL31;
     187           8 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     188           8 :       return ELF::R_ARM_SBREL32;
     189           8 :     case MCSymbolRefExpr::VK_ARM_TLSLDO:
     190           8 :       return ELF::R_ARM_TLS_LDO32;
     191           4 :     case MCSymbolRefExpr::VK_TLSCALL:
     192           4 :       return ELF::R_ARM_TLS_CALL;
     193           5 :     case MCSymbolRefExpr::VK_TLSDESC:
     194           5 :       return ELF::R_ARM_TLS_GOTDESC;
     195           6 :     case MCSymbolRefExpr::VK_TLSLDM:
     196           6 :       return ELF::R_ARM_TLS_LDM32;
     197           3 :     case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
     198           3 :       return ELF::R_ARM_TLS_DESCSEQ;
     199             :     }
     200             :   case ARM::fixup_arm_condbranch:
     201             :   case ARM::fixup_arm_uncondbranch:
     202             :     return ELF::R_ARM_JUMP24;
     203          19 :   case ARM::fixup_arm_movt_hi16:
     204          19 :     switch (Modifier) {
     205           0 :     default:
     206           0 :       llvm_unreachable("Unsupported Modifier");
     207             :     case MCSymbolRefExpr::VK_None:
     208             :       return ELF::R_ARM_MOVT_ABS;
     209           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     210           0 :       return ELF::R_ARM_MOVT_BREL;
     211             :     }
     212          22 :   case ARM::fixup_arm_movw_lo16:
     213          22 :     switch (Modifier) {
     214           0 :     default:
     215           0 :       llvm_unreachable("Unsupported Modifier");
     216             :     case MCSymbolRefExpr::VK_None:
     217             :       return ELF::R_ARM_MOVW_ABS_NC;
     218           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     219           0 :       return ELF::R_ARM_MOVW_BREL_NC;
     220             :     }
     221          12 :   case ARM::fixup_t2_movt_hi16:
     222          12 :     switch (Modifier) {
     223           0 :     default:
     224           0 :       llvm_unreachable("Unsupported Modifier");
     225             :     case MCSymbolRefExpr::VK_None:
     226             :       return ELF::R_ARM_THM_MOVT_ABS;
     227           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     228           0 :       return ELF::R_ARM_THM_MOVT_BREL;
     229             :     }
     230          13 :   case ARM::fixup_t2_movw_lo16:
     231          13 :     switch (Modifier) {
     232           0 :     default:
     233           0 :       llvm_unreachable("Unsupported Modifier");
     234             :     case MCSymbolRefExpr::VK_None:
     235             :       return ELF::R_ARM_THM_MOVW_ABS_NC;
     236           0 :     case MCSymbolRefExpr::VK_ARM_SBREL:
     237           0 :       return ELF::R_ARM_THM_MOVW_BREL_NC;
     238             :     }
     239             :   }
     240             : }
     241             : 
     242        1650 : void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
     243             :                                                MCSectionELF &Sec) {
     244             :   // The mix of execute-only and non-execute-only at link time is
     245             :   // non-execute-only. To avoid the empty implicitly created .text
     246             :   // section from making the whole .text section non-execute-only, we
     247             :   // mark it execute-only if it is empty and there is at least one
     248             :   // execute-only section in the object.
     249             :   MCSectionELF *TextSection =
     250        1650 :       static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
     251        1650 :   if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions() &&
     252             :       !TextSection->hasData()) {
     253           1 :     TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
     254             :   }
     255        1650 : }
     256             : 
     257             : std::unique_ptr<MCObjectTargetWriter>
     258        3017 : llvm::createARMELFObjectWriter(uint8_t OSABI) {
     259        3017 :   return llvm::make_unique<ARMELFObjectWriter>(OSABI);
     260             : }

Generated by: LCOV version 1.13