LCOV - code coverage report
Current view: top level - lib/Object - ELF.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 304 550 55.3 %
Date: 2018-10-20 13:21:21 Functions: 11 23 47.8 %
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        7002 : StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
      24             :                                                  uint32_t Type) {
      25        7002 :   switch (Machine) {
      26         940 :   case ELF::EM_X86_64:
      27             :     switch (Type) {
      28             : #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
      29             :     default:
      30             :       break;
      31             :     }
      32             :     break;
      33         314 :   case ELF::EM_386:
      34             :   case ELF::EM_IAMCU:
      35             :     switch (Type) {
      36             : #include "llvm/BinaryFormat/ELFRelocs/i386.def"
      37             :     default:
      38             :       break;
      39             :     }
      40             :     break;
      41        2879 :   case ELF::EM_MIPS:
      42             :     switch (Type) {
      43             : #include "llvm/BinaryFormat/ELFRelocs/Mips.def"
      44             :     default:
      45             :       break;
      46             :     }
      47             :     break;
      48         788 :   case ELF::EM_AARCH64:
      49             :     switch (Type) {
      50             : #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
      51             :     default:
      52             :       break;
      53             :     }
      54             :     break;
      55         622 :   case ELF::EM_ARM:
      56             :     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             :     switch (Type) {
      65             : #include "llvm/BinaryFormat/ELFRelocs/ARC.def"
      66             :     default:
      67             :       break;
      68             :     }
      69             :     break;
      70          71 :   case ELF::EM_AVR:
      71             :     switch (Type) {
      72             : #include "llvm/BinaryFormat/ELFRelocs/AVR.def"
      73             :     default:
      74             :       break;
      75             :     }
      76             :     break;
      77         117 :   case ELF::EM_HEXAGON:
      78             :     switch (Type) {
      79             : #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
      80             :     default:
      81             :       break;
      82             :     }
      83             :     break;
      84          14 :   case ELF::EM_LANAI:
      85             :     switch (Type) {
      86             : #include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
      87             :     default:
      88             :       break;
      89             :     }
      90             :     break;
      91           3 :   case ELF::EM_PPC:
      92             :     switch (Type) {
      93             : #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
      94             :     default:
      95             :       break;
      96             :     }
      97             :     break;
      98         981 :   case ELF::EM_PPC64:
      99             :     switch (Type) {
     100             : #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
     101             :     default:
     102             :       break;
     103             :     }
     104             :     break;
     105           0 :   case ELF::EM_RISCV:
     106             :     switch (Type) {
     107             : #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
     108             :     default:
     109             :       break;
     110             :     }
     111             :     break;
     112          31 :   case ELF::EM_S390:
     113             :     switch (Type) {
     114             : #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
     115             :     default:
     116             :       break;
     117             :     }
     118             :     break;
     119         182 :   case ELF::EM_SPARC:
     120             :   case ELF::EM_SPARC32PLUS:
     121             :   case ELF::EM_SPARCV9:
     122             :     switch (Type) {
     123             : #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
     124             :     default:
     125             :       break;
     126             :     }
     127             :     break;
     128          57 :   case ELF::EM_AMDGPU:
     129             :     switch (Type) {
     130             : #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
     131             :     default:
     132             :       break;
     133             :     }
     134             :     break;
     135           3 :   case ELF::EM_BPF:
     136             :     switch (Type) {
     137             : #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
     138             :     default:
     139             :       break;
     140             :     }
     141             :     break;
     142             :   default:
     143             :     break;
     144             :   }
     145           2 :   return "Unknown";
     146             : }
     147             : 
     148             : #undef ELF_RELOC
     149             : 
     150           7 : uint32_t llvm::object::getELFRelrRelocationType(uint32_t Machine) {
     151           7 :   switch (Machine) {
     152             :   case ELF::EM_X86_64:
     153             :     return ELF::R_X86_64_RELATIVE;
     154             :   case ELF::EM_386:
     155             :   case ELF::EM_IAMCU:
     156             :     return ELF::R_386_RELATIVE;
     157             :   case ELF::EM_MIPS:
     158             :     break;
     159           1 :   case ELF::EM_AARCH64:
     160           1 :     return ELF::R_AARCH64_RELATIVE;
     161           2 :   case ELF::EM_ARM:
     162           2 :     return ELF::R_ARM_RELATIVE;
     163           0 :   case ELF::EM_ARC_COMPACT:
     164             :   case ELF::EM_ARC_COMPACT2:
     165           0 :     return ELF::R_ARC_RELATIVE;
     166             :   case ELF::EM_AVR:
     167             :     break;
     168           0 :   case ELF::EM_HEXAGON:
     169           0 :     return ELF::R_HEX_RELATIVE;
     170             :   case ELF::EM_LANAI:
     171             :     break;
     172             :   case ELF::EM_PPC:
     173             :     break;
     174           0 :   case ELF::EM_PPC64:
     175           0 :     return ELF::R_PPC64_RELATIVE;
     176           0 :   case ELF::EM_RISCV:
     177           0 :     return ELF::R_RISCV_RELATIVE;
     178           0 :   case ELF::EM_S390:
     179           0 :     return ELF::R_390_RELATIVE;
     180           0 :   case ELF::EM_SPARC:
     181             :   case ELF::EM_SPARC32PLUS:
     182             :   case ELF::EM_SPARCV9:
     183           0 :     return ELF::R_SPARC_RELATIVE;
     184             :   case ELF::EM_AMDGPU:
     185             :     break;
     186             :   case ELF::EM_BPF:
     187             :     break;
     188             :   default:
     189             :     break;
     190             :   }
     191           0 :   return 0;
     192             : }
     193             : 
     194      397982 : StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
     195      397982 :   switch (Machine) {
     196         808 :   case ELF::EM_ARM:
     197             :     switch (Type) {
     198          74 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
     199           0 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
     200          12 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
     201           0 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
     202           0 :       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
     203             :     }
     204             :     break;
     205          10 :   case ELF::EM_HEXAGON:
     206           0 :     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
     207             :     break;
     208      395173 :   case ELF::EM_X86_64:
     209          32 :     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
     210             :     break;
     211         761 :   case ELF::EM_MIPS:
     212             :   case ELF::EM_MIPS_RS3_LE:
     213             :     switch (Type) {
     214          48 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
     215          19 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
     216          67 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
     217           1 :       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
     218             :     }
     219             :     break;
     220             :   default:
     221             :     break;
     222             :   }
     223             : 
     224      397729 :   switch (Type) {
     225         700 :     STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
     226      132529 :     STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
     227         684 :     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
     228        1328 :     STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
     229         239 :     STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
     230         177 :     STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
     231         182 :     STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
     232          33 :     STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
     233      261307 :     STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
     234         176 :     STRINGIFY_ENUM_CASE(ELF, SHT_REL);
     235           0 :     STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
     236         181 :     STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
     237          11 :     STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
     238           7 :     STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
     239           5 :     STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
     240          41 :     STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
     241           3 :     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
     242           3 :     STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
     243           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
     244           2 :     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
     245           0 :     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
     246           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
     247           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
     248           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
     249           2 :     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);
     250           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
     251         106 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
     252           1 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
     253           2 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
     254           3 :     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
     255             :   default:
     256           2 :     return "Unknown";
     257             :   }
     258             : }
     259             : 
     260             : template <class ELFT>
     261             : Expected<std::vector<typename ELFT::Rela>>
     262           7 : ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
     263             :   // This function decodes the contents of an SHT_RELR packed relocation
     264             :   // section.
     265             :   //
     266             :   // Proposal for adding SHT_RELR sections to generic-abi is here:
     267             :   //   https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
     268             :   //
     269             :   // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
     270             :   // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
     271             :   //
     272             :   // i.e. start with an address, followed by any number of bitmaps. The address
     273             :   // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
     274             :   // relocations each, at subsequent offsets following the last address entry.
     275             :   //
     276             :   // The bitmap entries must have 1 in the least significant bit. The assumption
     277             :   // here is that an address cannot have 1 in lsb. Odd addresses are not
     278             :   // supported.
     279             :   //
     280             :   // Excluding the least significant bit in the bitmap, each non-zero bit in
     281             :   // the bitmap represents a relocation to be applied to a corresponding machine
     282             :   // word that follows the base address word. The second least significant bit
     283             :   // represents the machine word immediately following the initial address, and
     284             :   // each bit that follows represents the next word, in linear order. As such,
     285             :   // a single bitmap can encode up to 31 relocations in a 32-bit object, and
     286             :   // 63 relocations in a 64-bit object.
     287             :   //
     288             :   // This encoding has a couple of interesting properties:
     289             :   // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
     290             :   //    even means address, odd means bitmap.
     291             :   // 2. Just a simple list of addresses is a valid encoding.
     292             : 
     293             :   Elf_Rela Rela;
     294             :   Rela.r_info = 0;
     295             :   Rela.r_addend = 0;
     296           7 :   Rela.setType(getRelrRelocationType(), false);
     297             :   std::vector<Elf_Rela> Relocs;
     298             : 
     299             :   // Word type: uint32_t for Elf32, and uint64_t for Elf64.
     300             :   typedef typename ELFT::uint Word;
     301             : 
     302             :   // Word size in number of bytes.
     303             :   const size_t WordSize = sizeof(Word);
     304             : 
     305             :   // Number of bits used for the relocation offsets bitmap.
     306             :   // These many relative relocations can be encoded in a single entry.
     307             :   const size_t NBits = 8*WordSize - 1;
     308             : 
     309             :   Word Base = 0;
     310          34 :   for (const Elf_Relr &R : relrs) {
     311             :     Word Entry = R;
     312          27 :     if ((Entry&1) == 0) {
     313             :       // Even entry: encodes the offset for next relocation.
     314             :       Rela.r_offset = Entry;
     315          11 :       Relocs.push_back(Rela);
     316             :       // Set base offset for subsequent bitmap entries.
     317          11 :       Base = Entry + WordSize;
     318          11 :       continue;
     319             :     }
     320             : 
     321             :     // Odd entry: encodes bitmap for relocations starting at base.
     322             :     Word Offset = Base;
     323         385 :     while (Entry != 0) {
     324         369 :       Entry >>= 1;
     325         369 :       if ((Entry&1) != 0) {
     326             :         Rela.r_offset = Offset;
     327         141 :         Relocs.push_back(Rela);
     328             :       }
     329         369 :       Offset += WordSize;
     330             :     }
     331             : 
     332             :     // Advance base offset by NBits words.
     333          16 :     Base += NBits * WordSize;
     334             :   }
     335             : 
     336           7 :   return Relocs;
     337             : }
     338           0 : 
     339             : template <class ELFT>
     340             : Expected<std::vector<typename ELFT::Rela>>
     341             : ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const {
     342             :   // This function reads relocations in Android's packed relocation format,
     343             :   // which is based on SLEB128 and delta encoding.
     344             :   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
     345             :   if (!ContentsOrErr)
     346             :     return ContentsOrErr.takeError();
     347             :   const uint8_t *Cur = ContentsOrErr->begin();
     348             :   const uint8_t *End = ContentsOrErr->end();
     349             :   if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
     350             :       Cur[2] != 'S' || Cur[3] != '2')
     351             :     return createError("invalid packed relocation header");
     352             :   Cur += 4;
     353             : 
     354             :   const char *ErrStr = nullptr;
     355             :   auto ReadSLEB = [&]() -> int64_t {
     356             :     if (ErrStr)
     357             :       return 0;
     358             :     unsigned Len;
     359             :     int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
     360             :     Cur += Len;
     361             :     return Result;
     362             :   };
     363             : 
     364             :   uint64_t NumRelocs = ReadSLEB();
     365             :   uint64_t Offset = ReadSLEB();
     366             :   uint64_t Addend = 0;
     367             : 
     368             :   if (ErrStr)
     369             :     return createError(ErrStr);
     370             : 
     371             :   std::vector<Elf_Rela> Relocs;
     372           0 :   Relocs.reserve(NumRelocs);
     373             :   while (NumRelocs) {
     374             :     uint64_t NumRelocsInGroup = ReadSLEB();
     375             :     if (NumRelocsInGroup > NumRelocs)
     376             :       return createError("relocation group unexpectedly large");
     377             :     NumRelocs -= NumRelocsInGroup;
     378             : 
     379             :     uint64_t GroupFlags = ReadSLEB();
     380             :     bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
     381             :     bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
     382             :     bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
     383             :     bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
     384             : 
     385             :     uint64_t GroupOffsetDelta;
     386           0 :     if (GroupedByOffsetDelta)
     387             :       GroupOffsetDelta = ReadSLEB();
     388           0 : 
     389             :     uint64_t GroupRInfo;
     390             :     if (GroupedByInfo)
     391           0 :       GroupRInfo = ReadSLEB();
     392             : 
     393           0 :     if (GroupedByAddend && GroupHasAddend)
     394           0 :       Addend += ReadSLEB();
     395             : 
     396             :     if (!GroupHasAddend)
     397             :       Addend = 0;
     398             : 
     399           0 :     for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
     400           0 :       Elf_Rela R;
     401           0 :       Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
     402             :       R.r_offset = Offset;
     403           0 :       R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
     404             :       if (GroupHasAddend && !GroupedByAddend)
     405           0 :         Addend += ReadSLEB();
     406             :       R.r_addend = Addend;
     407             :       Relocs.push_back(R);
     408             : 
     409           0 :       if (ErrStr)
     410             :         return createError(ErrStr);
     411             :     }
     412           0 : 
     413             :     if (ErrStr)
     414           3 :       return createError(ErrStr);
     415             :   }
     416             : 
     417             :   return Relocs;
     418             : }
     419             : 
     420             : template <class ELFT>
     421             : const char *ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
     422             :                                                  uint64_t Type) const {
     423             : #define DYNAMIC_STRINGIFY_ENUM(tag, value)                                     \
     424             :   case value:                                                                  \
     425             :     return #tag;
     426             : 
     427             : #define DYNAMIC_TAG(n, v)
     428             :   switch (Arch) {
     429             :   case ELF::EM_HEXAGON:
     430             :     switch (Type) {
     431             : #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
     432             : #include "llvm/BinaryFormat/DynamicTags.def"
     433             : #undef HEXAGON_DYNAMIC_TAG
     434             :     }
     435             : 
     436             :   case ELF::EM_MIPS:
     437             :     switch (Type) {
     438             : #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
     439             : #include "llvm/BinaryFormat/DynamicTags.def"
     440             : #undef MIPS_DYNAMIC_TAG
     441             :     }
     442             : 
     443             :   case ELF::EM_PPC64:
     444             :     switch (Type) {
     445             : #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
     446             : #include "llvm/BinaryFormat/DynamicTags.def"
     447             : #undef PPC64_DYNAMIC_TAG
     448           3 :     }
     449             :   }
     450             : #undef DYNAMIC_TAG
     451             :   switch (Type) {
     452             : // Now handle all dynamic tags except the architecture specific ones
     453             : #define MIPS_DYNAMIC_TAG(name, value)
     454             : #define HEXAGON_DYNAMIC_TAG(name, value)
     455             : #define PPC64_DYNAMIC_TAG(name, value)
     456             : // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
     457             : #define DYNAMIC_TAG_MARKER(name, value)
     458             : #define DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
     459             : #include "llvm/BinaryFormat/DynamicTags.def"
     460             : #undef DYNAMIC_TAG
     461             : #undef MIPS_DYNAMIC_TAG
     462          15 : #undef HEXAGON_DYNAMIC_TAG
     463             : #undef PPC64_DYNAMIC_TAG
     464          12 : #undef DYNAMIC_TAG_MARKER
     465             : #undef DYNAMIC_STRINGIFY_ENUM
     466             :   default:
     467           5 :     return "unknown";
     468             :   }
     469           5 : }
     470           5 : 
     471             : template <class ELFT>
     472             : const char *ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {
     473             :   return getDynamicTagAsString(getHeader()->e_machine, Type);
     474             : }
     475         195 : 
     476         188 : template <class ELFT>
     477         188 : Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
     478             :   ArrayRef<Elf_Dyn> Dyn;
     479          61 :   size_t DynSecSize = 0;
     480             : 
     481         188 :   auto ProgramHeadersOrError = program_headers();
     482             :   if (!ProgramHeadersOrError)
     483             :     return ProgramHeadersOrError.takeError();
     484             : 
     485           7 :   for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
     486             :     if (Phdr.p_type == ELF::PT_DYNAMIC) {
     487             :       Dyn = makeArrayRef(
     488           3 :           reinterpret_cast<const Elf_Dyn *>(base() + Phdr.p_offset),
     489             :           Phdr.p_filesz / sizeof(Elf_Dyn));
     490           0 :       DynSecSize = Phdr.p_filesz;
     491             :       break;
     492             :     }
     493             :   }
     494             : 
     495             :   // If we can't find the dynamic section in the program headers, we just fall
     496             :   // back on the sections.
     497             :   if (Dyn.empty()) {
     498             :     auto SectionsOrError = sections();
     499             :     if (!SectionsOrError)
     500             :       return SectionsOrError.takeError();
     501             : 
     502             :     for (const Elf_Shdr &Sec : *SectionsOrError) {
     503             :       if (Sec.sh_type == ELF::SHT_DYNAMIC) {
     504             :         Expected<ArrayRef<Elf_Dyn>> DynOrError =
     505             :             getSectionContentsAsArray<Elf_Dyn>(&Sec);
     506             :         if (!DynOrError)
     507             :           return DynOrError.takeError();
     508             :         Dyn = *DynOrError;
     509             :         DynSecSize = Sec.sh_size;
     510             :         break;
     511             :       }
     512             :     }
     513             : 
     514             :     if (!Dyn.data())
     515             :       return ArrayRef<Elf_Dyn>();
     516             :   }
     517             : 
     518             :   if (Dyn.empty())
     519             :     return createError("invalid empty dynamic section");
     520             : 
     521             :   if (DynSecSize % sizeof(Elf_Dyn) != 0)
     522             :     return createError("malformed dynamic section");
     523             : 
     524           0 :   if (Dyn.back().d_tag != ELF::DT_NULL)
     525             :     return createError("dynamic sections must be DT_NULL terminated");
     526             : 
     527             :   return Dyn;
     528             : }
     529             : 
     530             : template <class ELFT>
     531             : Expected<const uint8_t *> ELFFile<ELFT>::toMappedAddr(uint64_t VAddr) const {
     532             :   auto ProgramHeadersOrError = program_headers();
     533             :   if (!ProgramHeadersOrError)
     534             :     return ProgramHeadersOrError.takeError();
     535             : 
     536             :   llvm::SmallVector<Elf_Phdr *, 4> LoadSegments;
     537             : 
     538           0 :   for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)
     539             :     if (Phdr.p_type == ELF::PT_LOAD)
     540           0 :       LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
     541             : 
     542             :   const Elf_Phdr *const *I =
     543           0 :       std::upper_bound(LoadSegments.begin(), LoadSegments.end(), VAddr,
     544             :                        [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
     545           0 :                          return VAddr < Phdr->p_vaddr;
     546           0 :                        });
     547             : 
     548             :   if (I == LoadSegments.begin())
     549             :     return createError("Virtual address is not in any segment");
     550             :   --I;
     551           0 :   const Elf_Phdr &Phdr = **I;
     552           0 :   uint64_t Delta = VAddr - Phdr.p_vaddr;
     553           0 :   if (Delta >= Phdr.p_filesz)
     554             :     return createError("Virtual address is not in any segment");
     555           0 :   return base() + Phdr.p_offset + Delta;
     556             : }
     557           0 : 
     558             : template class llvm::object::ELFFile<ELF32LE>;
     559             : template class llvm::object::ELFFile<ELF32BE>;
     560             : template class llvm::object::ELFFile<ELF64LE>;
     561           0 : template class llvm::object::ELFFile<ELF64BE>;

Generated by: LCOV version 1.13