LCOV - code coverage report
Current view: top level - lib/Object - ELF.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 118 128 92.2 %
Date: 2018-06-17 00:07:59 Functions: 6 10 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ELF.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             : #include "llvm/Object/ELF.h"
      11             : #include "llvm/BinaryFormat/ELF.h"
      12             : #include "llvm/Support/LEB128.h"
      13             : 
      14             : using namespace llvm;
      15             : using namespace object;
      16             : 
      17             : #define STRINGIFY_ENUM_CASE(ns, name)                                          \
      18             :   case ns::name:                                                               \
      19             :     return #name;
      20             : 
      21             : #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
      22             : 
      23        6525 : StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
      24             :                                                  uint32_t Type) {
      25        6525 :   switch (Machine) {
      26         864 :   case ELF::EM_X86_64:
      27         864 :     switch (Type) {
      28             : #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
      29             :     default:
      30             :       break;
      31             :     }
      32             :     break;
      33         286 :   case ELF::EM_386:
      34             :   case ELF::EM_IAMCU:
      35         286 :     switch (Type) {
      36             : #include "llvm/BinaryFormat/ELFRelocs/i386.def"
      37             :     default:
      38             :       break;
      39             :     }
      40             :     break;
      41        2866 :   case ELF::EM_MIPS:
      42        2866 :     switch (Type) {
      43             : #include "llvm/BinaryFormat/ELFRelocs/Mips.def"
      44             :     default:
      45             :       break;
      46             :     }
      47             :     break;
      48         717 :   case ELF::EM_AARCH64:
      49         717 :     switch (Type) {
      50             : #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
      51             :     default:
      52             :       break;
      53             :     }
      54             :     break;
      55         556 :   case ELF::EM_ARM:
      56         556 :     switch (Type) {
      57             : #include "llvm/BinaryFormat/ELFRelocs/ARM.def"
      58             :     default:
      59             :       break;
      60             :     }
      61             :     break;
      62           0 :   case ELF::EM_ARC_COMPACT:
      63             :   case ELF::EM_ARC_COMPACT2:
      64           0 :     switch (Type) {
      65             : #include "llvm/BinaryFormat/ELFRelocs/ARC.def"
      66             :     default:
      67             :       break;
      68             :     }
      69             :     break;
      70          71 :   case ELF::EM_AVR:
      71          71 :     switch (Type) {
      72             : #include "llvm/BinaryFormat/ELFRelocs/AVR.def"
      73             :     default:
      74             :       break;
      75             :     }
      76             :     break;
      77         117 :   case ELF::EM_HEXAGON:
      78         117 :     switch (Type) {
      79             : #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
      80             :     default:
      81             :       break;
      82             :     }
      83             :     break;
      84          14 :   case ELF::EM_LANAI:
      85          14 :     switch (Type) {
      86             : #include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
      87             :     default:
      88             :       break;
      89             :     }
      90             :     break;
      91           3 :   case ELF::EM_PPC:
      92           3 :     switch (Type) {
      93             : #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
      94             :     default:
      95             :       break;
      96             :     }
      97             :     break;
      98         809 :   case ELF::EM_PPC64:
      99         809 :     switch (Type) {
     100             : #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
     101             :     default:
     102             :       break;
     103             :     }
     104             :     break;
     105           0 :   case ELF::EM_RISCV:
     106           0 :     switch (Type) {
     107             : #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
     108             :     default:
     109             :       break;
     110             :     }
     111             :     break;
     112          31 :   case ELF::EM_S390:
     113          31 :     switch (Type) {
     114             : #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
     115             :     default:
     116             :       break;
     117             :     }
     118             :     break;
     119         134 :   case ELF::EM_SPARC:
     120             :   case ELF::EM_SPARC32PLUS:
     121             :   case ELF::EM_SPARCV9:
     122         134 :     switch (Type) {
     123             : #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
     124             :     default:
     125             :       break;
     126             :     }
     127             :     break;
     128           0 :   case ELF::EM_WEBASSEMBLY:
     129           0 :     switch (Type) {
     130             : #include "llvm/BinaryFormat/ELFRelocs/WebAssembly.def"
     131             :     default:
     132             :       break;
     133             :     }
     134             :     break;
     135          54 :   case ELF::EM_AMDGPU:
     136          54 :     switch (Type) {
     137             : #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
     138             :     default:
     139             :       break;
     140             :     }
     141             :     break;
     142           3 :   case ELF::EM_BPF:
     143           3 :     switch (Type) {
     144             : #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
     145             :     default:
     146             :       break;
     147             :     }
     148             :     break;
     149             :   default:
     150             :     break;
     151             :   }
     152           2 :   return "Unknown";
     153             : }
     154             : 
     155             : #undef ELF_RELOC
     156             : 
     157      136282 : StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
     158      136282 :   switch (Machine) {
     159         759 :   case ELF::EM_ARM:
     160         759 :     switch (Type) {
     161          74 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
     162           0 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
     163          11 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
     164           0 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
     165           0 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
     166             :     }
     167             :     break;
     168           5 :   case ELF::EM_HEXAGON:
     169           5 :     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
     170             :     break;
     171      133568 :   case ELF::EM_X86_64:
     172      133568 :     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
     173             :     break;
     174         755 :   case ELF::EM_MIPS:
     175             :   case ELF::EM_MIPS_RS3_LE:
     176         755 :     switch (Type) {
     177          48 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
     178          19 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
     179          67 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
     180           1 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
     181             :     }
     182             :     break;
     183             :   default:
     184             :     break;
     185             :   }
     186             : 
     187      136031 :   switch (Type) {
     188         620 :     STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
     189      132349 :     STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
     190         606 :     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
     191        1179 :     STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
     192         211 :     STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
     193         171 :     STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
     194         174 :     STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
     195          33 :     STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
     196         173 :     STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
     197         175 :     STRINGIFY_ENUM_CASE(ELF, SHT_REL);
     198           0 :     STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
     199         175 :     STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
     200          11 :     STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
     201           7 :     STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
     202           5 :     STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
     203          27 :     STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
     204           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
     205           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
     206           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
     207           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
     208           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
     209           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
     210           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
     211         100 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
     212           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
     213           2 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
     214           3 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
     215             :   default:
     216           2 :     return "Unknown";
     217             :   }
     218             : }
     219             : 
     220             : template <class ELFT>
     221             : Expected<std::vector<typename ELFT::Rela>>
     222          12 : ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const {
     223             :   // This function reads relocations in Android's packed relocation format,
     224             :   // which is based on SLEB128 and delta encoding.
     225          12 :   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
     226          12 :   if (!ContentsOrErr)
     227             :     return ContentsOrErr.takeError();
     228          12 :   const uint8_t *Cur = ContentsOrErr->begin();
     229          12 :   const uint8_t *End = ContentsOrErr->end();
     230          24 :   if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
     231          36 :       Cur[2] != 'S' || Cur[3] != '2')
     232             :     return createError("invalid packed relocation header");
     233          11 :   Cur += 4;
     234             : 
     235          11 :   const char *ErrStr = nullptr;
     236         198 :   auto ReadSLEB = [&]() -> int64_t {
     237         187 :     if (ErrStr)
     238             :       return 0;
     239             :     unsigned Len;
     240         185 :     int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
     241         185 :     Cur += Len;
     242         185 :     return Result;
     243             :   };
     244             : 
     245          11 :   uint64_t NumRelocs = ReadSLEB();
     246          11 :   uint64_t Offset = ReadSLEB();
     247             :   uint64_t Addend = 0;
     248             : 
     249          11 :   if (ErrStr)
     250             :     return createError(ErrStr);
     251             : 
     252             :   std::vector<Elf_Rela> Relocs;
     253          10 :   Relocs.reserve(NumRelocs);
     254          34 :   while (NumRelocs) {
     255          27 :     uint64_t NumRelocsInGroup = ReadSLEB();
     256          27 :     if (NumRelocsInGroup > NumRelocs)
     257             :       return createError("relocation group unexpectedly large");
     258          26 :     NumRelocs -= NumRelocsInGroup;
     259             : 
     260          26 :     uint64_t GroupFlags = ReadSLEB();
     261          26 :     bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
     262          26 :     bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
     263          26 :     bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
     264          26 :     bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
     265             : 
     266             :     uint64_t GroupOffsetDelta;
     267          26 :     if (GroupedByOffsetDelta)
     268          15 :       GroupOffsetDelta = ReadSLEB();
     269             : 
     270             :     uint64_t GroupRInfo;
     271          26 :     if (GroupedByInfo)
     272          14 :       GroupRInfo = ReadSLEB();
     273             : 
     274          26 :     if (GroupedByAddend && GroupHasAddend)
     275           2 :       Addend += ReadSLEB();
     276             : 
     277         202 :     for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
     278             :       Elf_Rela R;
     279          89 :       Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
     280          46 :       R.r_offset = Offset;
     281          89 :       R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
     282             : 
     283          89 :       if (GroupHasAddend) {
     284          34 :         if (!GroupedByAddend)
     285          30 :           Addend += ReadSLEB();
     286             :         R.r_addend = Addend;
     287             :       } else {
     288             :         R.r_addend = 0;
     289             :       }
     290             : 
     291          89 :       Relocs.push_back(R);
     292             : 
     293          89 :       if (ErrStr)
     294             :         return createError(ErrStr);
     295             :     }
     296             : 
     297          25 :     if (ErrStr)
     298             :       return createError(ErrStr);
     299             :   }
     300             : 
     301             :   return Relocs;
     302             : }
     303             : 
     304             : template class llvm::object::ELFFile<ELF32LE>;
     305             : template class llvm::object::ELFFile<ELF32BE>;
     306             : template class llvm::object::ELFFile<ELF64LE>;
     307             : template class llvm::object::ELFFile<ELF64BE>;

Generated by: LCOV version 1.13