LCOV - code coverage report
Current view: top level - lib/Object - ELFObjectFile.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 126 163 77.3 %
Date: 2017-09-14 15:23:50 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
       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             : // Part of the ELFObjectFile class implementation.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "llvm/Object/ELFObjectFile.h"
      15             : #include "llvm/ADT/Triple.h"
      16             : #include "llvm/BinaryFormat/ELF.h"
      17             : #include "llvm/MC/SubtargetFeature.h"
      18             : #include "llvm/Object/ELF.h"
      19             : #include "llvm/Object/ELFTypes.h"
      20             : #include "llvm/Object/Error.h"
      21             : #include "llvm/Support/ARMAttributeParser.h"
      22             : #include "llvm/Support/ARMBuildAttributes.h"
      23             : #include "llvm/Support/Endian.h"
      24             : #include "llvm/Support/ErrorHandling.h"
      25             : #include "llvm/Support/MathExtras.h"
      26             : #include <algorithm>
      27             : #include <cstddef>
      28             : #include <cstdint>
      29             : #include <memory>
      30             : #include <string>
      31             : #include <system_error>
      32             : #include <utility>
      33             : 
      34             : using namespace llvm;
      35             : using namespace object;
      36             : 
      37        3870 : ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
      38        3870 :     : ObjectFile(Type, Source) {}
      39             : 
      40             : ErrorOr<std::unique_ptr<ObjectFile>>
      41        3723 : ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
      42             :   std::pair<unsigned char, unsigned char> Ident =
      43        7446 :       getElfArchType(Obj.getBuffer());
      44             :   std::size_t MaxAlignment =
      45        7446 :       1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
      46             : 
      47        3723 :   if (MaxAlignment < 2)
      48             :     return object_error::parse_failed;
      49             : 
      50        3722 :   std::error_code EC;
      51        3722 :   std::unique_ptr<ObjectFile> R;
      52        3722 :   if (Ident.first == ELF::ELFCLASS32) {
      53        1032 :     if (Ident.second == ELF::ELFDATA2LSB)
      54        1652 :       R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC));
      55         206 :     else if (Ident.second == ELF::ELFDATA2MSB)
      56         412 :       R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC));
      57             :     else
      58             :       return object_error::parse_failed;
      59        2690 :   } else if (Ident.first == ELF::ELFCLASS64) {
      60        2689 :     if (Ident.second == ELF::ELFDATA2LSB)
      61        5062 :       R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
      62         158 :     else if (Ident.second == ELF::ELFDATA2MSB)
      63         314 :       R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
      64             :     else
      65             :       return object_error::parse_failed;
      66             :   } else {
      67             :     return object_error::parse_failed;
      68             :   }
      69             : 
      70        3720 :   if (EC)
      71             :     return EC;
      72        3715 :   return std::move(R);
      73             : }
      74             : 
      75          94 : SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
      76          94 :   SubtargetFeatures Features;
      77             :   unsigned PlatformFlags;
      78          94 :   getPlatformFlags(PlatformFlags);
      79             : 
      80          94 :   switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
      81             :   case ELF::EF_MIPS_ARCH_1:
      82             :     break;
      83           0 :   case ELF::EF_MIPS_ARCH_2:
      84           0 :     Features.AddFeature("mips2");
      85           0 :     break;
      86           0 :   case ELF::EF_MIPS_ARCH_3:
      87           0 :     Features.AddFeature("mips3");
      88           0 :     break;
      89           0 :   case ELF::EF_MIPS_ARCH_4:
      90           0 :     Features.AddFeature("mips4");
      91           0 :     break;
      92           0 :   case ELF::EF_MIPS_ARCH_5:
      93           0 :     Features.AddFeature("mips5");
      94           0 :     break;
      95          50 :   case ELF::EF_MIPS_ARCH_32:
      96          50 :     Features.AddFeature("mips32");
      97          50 :     break;
      98          17 :   case ELF::EF_MIPS_ARCH_64:
      99          17 :     Features.AddFeature("mips64");
     100          17 :     break;
     101           6 :   case ELF::EF_MIPS_ARCH_32R2:
     102           6 :     Features.AddFeature("mips32r2");
     103           6 :     break;
     104           9 :   case ELF::EF_MIPS_ARCH_64R2:
     105           9 :     Features.AddFeature("mips64r2");
     106           9 :     break;
     107           8 :   case ELF::EF_MIPS_ARCH_32R6:
     108           8 :     Features.AddFeature("mips32r6");
     109           8 :     break;
     110           3 :   case ELF::EF_MIPS_ARCH_64R6:
     111           3 :     Features.AddFeature("mips64r6");
     112           3 :     break;
     113           0 :   default:
     114           0 :     llvm_unreachable("Unknown EF_MIPS_ARCH value");
     115             :   }
     116             : 
     117          94 :   switch (PlatformFlags & ELF::EF_MIPS_MACH) {
     118             :   case ELF::EF_MIPS_MACH_NONE:
     119             :     // No feature associated with this value.
     120             :     break;
     121           0 :   case ELF::EF_MIPS_MACH_OCTEON:
     122           0 :     Features.AddFeature("cnmips");
     123           0 :     break;
     124           0 :   default:
     125           0 :     llvm_unreachable("Unknown EF_MIPS_ARCH value");
     126             :   }
     127             : 
     128          94 :   if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
     129           0 :     Features.AddFeature("mips16");
     130          94 :   if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
     131          10 :     Features.AddFeature("micromips");
     132             : 
     133          94 :   return Features;
     134             : }
     135             : 
     136         103 : SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
     137         206 :   SubtargetFeatures Features;
     138         206 :   ARMAttributeParser Attributes;
     139         103 :   std::error_code EC = getBuildAttributes(Attributes);
     140         103 :   if (EC)
     141           0 :     return SubtargetFeatures();
     142             : 
     143             :   // both ARMv7-M and R have to support thumb hardware div
     144         103 :   bool isV7 = false;
     145             :   if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
     146          34 :     isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
     147             :       == ARMBuildAttrs::v7;
     148             : 
     149             :   if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
     150          23 :     switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
     151          18 :     case ARMBuildAttrs::ApplicationProfile:
     152          18 :       Features.AddFeature("aclass");
     153          18 :       break;
     154           2 :     case ARMBuildAttrs::RealTimeProfile:
     155           2 :       Features.AddFeature("rclass");
     156           2 :       if (isV7)
     157           2 :         Features.AddFeature("hwdiv");
     158             :       break;
     159           3 :     case ARMBuildAttrs::MicroControllerProfile:
     160           3 :       Features.AddFeature("mclass");
     161           3 :       if (isV7)
     162           2 :         Features.AddFeature("hwdiv");
     163             :       break;
     164             :     }
     165             :   }
     166             : 
     167             :   if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
     168          29 :     switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
     169             :     default:
     170             :       break;
     171           0 :     case ARMBuildAttrs::Not_Allowed:
     172           0 :       Features.AddFeature("thumb", false);
     173           0 :       Features.AddFeature("thumb2", false);
     174           0 :       break;
     175          20 :     case ARMBuildAttrs::AllowThumb32:
     176          20 :       Features.AddFeature("thumb2");
     177          20 :       break;
     178             :     }
     179             :   }
     180             : 
     181             :   if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
     182          24 :     switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
     183             :     default:
     184             :       break;
     185           3 :     case ARMBuildAttrs::Not_Allowed:
     186           3 :       Features.AddFeature("vfp2", false);
     187           3 :       Features.AddFeature("vfp3", false);
     188           3 :       Features.AddFeature("vfp4", false);
     189           3 :       break;
     190           1 :     case ARMBuildAttrs::AllowFPv2:
     191           1 :       Features.AddFeature("vfp2");
     192           1 :       break;
     193          16 :     case ARMBuildAttrs::AllowFPv3A:
     194             :     case ARMBuildAttrs::AllowFPv3B:
     195          16 :       Features.AddFeature("vfp3");
     196          16 :       break;
     197           3 :     case ARMBuildAttrs::AllowFPv4A:
     198             :     case ARMBuildAttrs::AllowFPv4B:
     199           3 :       Features.AddFeature("vfp4");
     200           3 :       break;
     201             :     }
     202             :   }
     203             : 
     204             :   if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) {
     205          17 :     switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) {
     206             :     default:
     207             :       break;
     208           0 :     case ARMBuildAttrs::Not_Allowed:
     209           0 :       Features.AddFeature("neon", false);
     210           0 :       Features.AddFeature("fp16", false);
     211           0 :       break;
     212          14 :     case ARMBuildAttrs::AllowNeon:
     213          14 :       Features.AddFeature("neon");
     214          14 :       break;
     215           3 :     case ARMBuildAttrs::AllowNeon2:
     216           3 :       Features.AddFeature("neon");
     217           3 :       Features.AddFeature("fp16");
     218           3 :       break;
     219             :     }
     220             :   }
     221             : 
     222             :   if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
     223           3 :     switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
     224             :     default:
     225             :       break;
     226           0 :     case ARMBuildAttrs::DisallowDIV:
     227           0 :       Features.AddFeature("hwdiv", false);
     228           0 :       Features.AddFeature("hwdiv-arm", false);
     229           0 :       break;
     230           3 :     case ARMBuildAttrs::AllowDIVExt:
     231           3 :       Features.AddFeature("hwdiv");
     232           3 :       Features.AddFeature("hwdiv-arm");
     233           3 :       break;
     234             :     }
     235             :   }
     236             : 
     237             :   return Features;
     238             : }
     239             : 
     240         500 : SubtargetFeatures ELFObjectFileBase::getFeatures() const {
     241         500 :   switch (getEMachine()) {
     242          94 :   case ELF::EM_MIPS:
     243          94 :     return getMIPSFeatures();
     244         103 :   case ELF::EM_ARM:
     245         103 :     return getARMFeatures();
     246         303 :   default:
     247         303 :     return SubtargetFeatures();
     248             :   }
     249             : }
     250             : 
     251             : // FIXME Encode from a tablegen description or target parser.
     252         103 : void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
     253         103 :   if (TheTriple.getSubArch() != Triple::NoSubArch)
     254          73 :     return;
     255             : 
     256          60 :   ARMAttributeParser Attributes;
     257          30 :   std::error_code EC = getBuildAttributes(Attributes);
     258          30 :   if (EC)
     259             :     return;
     260             : 
     261          60 :   std::string Triple;
     262             :   // Default to ARM, but use the triple if it's been set.
     263          23 :   if (TheTriple.isThumb())
     264             :     Triple = "thumb";
     265             :   else
     266             :     Triple = "arm";
     267             : 
     268             :   if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
     269          14 :     switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
     270           1 :     case ARMBuildAttrs::v4:
     271             :       Triple += "v4";
     272             :       break;
     273           1 :     case ARMBuildAttrs::v4T:
     274             :       Triple += "v4t";
     275             :       break;
     276           1 :     case ARMBuildAttrs::v5T:
     277             :       Triple += "v5t";
     278             :       break;
     279           1 :     case ARMBuildAttrs::v5TE:
     280             :       Triple += "v5te";
     281             :       break;
     282           0 :     case ARMBuildAttrs::v5TEJ:
     283             :       Triple += "v5tej";
     284             :       break;
     285           1 :     case ARMBuildAttrs::v6:
     286             :       Triple += "v6";
     287             :       break;
     288           0 :     case ARMBuildAttrs::v6KZ:
     289             :       Triple += "v6kz";
     290             :       break;
     291           1 :     case ARMBuildAttrs::v6T2:
     292             :       Triple += "v6t2";
     293             :       break;
     294           1 :     case ARMBuildAttrs::v6K:
     295             :       Triple += "v6k";
     296             :       break;
     297           6 :     case ARMBuildAttrs::v7:
     298             :       Triple += "v7";
     299             :       break;
     300           1 :     case ARMBuildAttrs::v6_M:
     301             :       Triple += "v6m";
     302             :       break;
     303           0 :     case ARMBuildAttrs::v6S_M:
     304             :       Triple += "v6sm";
     305             :       break;
     306           0 :     case ARMBuildAttrs::v7E_M:
     307             :       Triple += "v7em";
     308             :       break;
     309             :     }
     310             :   }
     311          30 :   if (!isLittleEndian())
     312             :     Triple += "eb";
     313             : 
     314          30 :   TheTriple.setArchName(Triple);
     315             : }

Generated by: LCOV version 1.13