LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/RuntimeDyld/Targets - RuntimeDyldCOFFI386.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 66 71 93.0 %
Date: 2018-10-20 13:21:21 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- RuntimeDyldCOFFI386.h --- COFF/X86_64 specific code ---*- C++ --*-===//
       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             : // COFF x86 support for MC-JIT runtime dynamic linker.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H
      15             : #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H
      16             : 
      17             : #include "../RuntimeDyldCOFF.h"
      18             : #include "llvm/BinaryFormat/COFF.h"
      19             : #include "llvm/Object/COFF.h"
      20             : 
      21             : #define DEBUG_TYPE "dyld"
      22             : 
      23             : namespace llvm {
      24             : 
      25             : class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
      26             : public:
      27             :   RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM,
      28             :                       JITSymbolResolver &Resolver)
      29           1 :       : RuntimeDyldCOFF(MM, Resolver) {}
      30             : 
      31           3 :   unsigned getMaxStubSize() override {
      32           3 :     return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad
      33             :   }
      34             : 
      35           5 :   unsigned getStubAlignment() override { return 1; }
      36             : 
      37             :   Expected<relocation_iterator>
      38          14 :   processRelocationRef(unsigned SectionID,
      39             :                        relocation_iterator RelI,
      40             :                        const ObjectFile &Obj,
      41             :                        ObjSectionToIDMap &ObjSectionToID,
      42             :                        StubMap &Stubs) override {
      43             : 
      44          14 :     auto Symbol = RelI->getSymbol();
      45          14 :     if (Symbol == Obj.symbol_end())
      46           0 :       report_fatal_error("Unknown symbol in relocation");
      47             : 
      48             :     Expected<StringRef> TargetNameOrErr = Symbol->getName();
      49          14 :     if (!TargetNameOrErr)
      50             :       return TargetNameOrErr.takeError();
      51          14 :     StringRef TargetName = *TargetNameOrErr;
      52             : 
      53             :     auto SectionOrErr = Symbol->getSection();
      54          14 :     if (!SectionOrErr)
      55             :       return SectionOrErr.takeError();
      56          14 :     auto Section = *SectionOrErr;
      57             : 
      58          14 :     uint64_t RelType = RelI->getType();
      59          14 :     uint64_t Offset = RelI->getOffset();
      60             : 
      61             :     // Determine the Addend used to adjust the relocation value.
      62             :     uint64_t Addend = 0;
      63          14 :     SectionEntry &AddendSection = Sections[SectionID];
      64          14 :     uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;
      65          14 :     uint8_t *Displacement = (uint8_t *)ObjTarget;
      66             : 
      67             :     switch (RelType) {
      68          13 :     case COFF::IMAGE_REL_I386_DIR32:
      69             :     case COFF::IMAGE_REL_I386_DIR32NB:
      70             :     case COFF::IMAGE_REL_I386_SECREL:
      71             :     case COFF::IMAGE_REL_I386_REL32: {
      72          13 :       Addend = readBytesUnaligned(Displacement, 4);
      73          13 :       break;
      74             :     }
      75             :     default:
      76             :       break;
      77             :     }
      78             : 
      79             : #if !defined(NDEBUG)
      80             :     SmallString<32> RelTypeName;
      81             :     RelI->getTypeName(RelTypeName);
      82             : #endif
      83             :     LLVM_DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
      84             :                       << " RelType: " << RelTypeName << " TargetName: "
      85             :                       << TargetName << " Addend " << Addend << "\n");
      86             : 
      87             :     unsigned TargetSectionID = -1;
      88          14 :     if (Section == Obj.section_end()) {
      89           3 :       RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);
      90           3 :       addRelocationForSymbol(RE, TargetName);
      91             :     } else {
      92          11 :       if (auto TargetSectionIDOrErr =
      93          11 :           findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID))
      94          11 :         TargetSectionID = *TargetSectionIDOrErr;
      95             :       else
      96             :         return TargetSectionIDOrErr.takeError();
      97             : 
      98          11 :       switch (RelType) {
      99             :       case COFF::IMAGE_REL_I386_ABSOLUTE:
     100             :         // This relocation is ignored.
     101             :         break;
     102           8 :       case COFF::IMAGE_REL_I386_DIR32:
     103             :       case COFF::IMAGE_REL_I386_DIR32NB:
     104             :       case COFF::IMAGE_REL_I386_REL32: {
     105             :         RelocationEntry RE =
     106             :             RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,
     107           8 :                             getSymbolOffset(*Symbol), 0, 0, false, 0);
     108           8 :         addRelocationForSection(RE, TargetSectionID);
     109             :         break;
     110             :       }
     111           1 :       case COFF::IMAGE_REL_I386_SECTION: {
     112             :         RelocationEntry RE =
     113           1 :             RelocationEntry(TargetSectionID, Offset, RelType, 0);
     114           1 :         addRelocationForSection(RE, TargetSectionID);
     115             :         break;
     116             :       }
     117           2 :       case COFF::IMAGE_REL_I386_SECREL: {
     118             :         RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
     119           2 :                                              getSymbolOffset(*Symbol) + Addend);
     120           2 :         addRelocationForSection(RE, TargetSectionID);
     121             :         break;
     122             :       }
     123           0 :       default:
     124           0 :         llvm_unreachable("unsupported relocation type");
     125             :       }
     126             : 
     127             :     }
     128             : 
     129             :     return ++RelI;
     130             :   }
     131             : 
     132          14 :   void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
     133          28 :     const auto Section = Sections[RE.SectionID];
     134          14 :     uint8_t *Target = Section.getAddressWithOffset(RE.Offset);
     135             : 
     136          14 :     switch (RE.RelType) {
     137             :     case COFF::IMAGE_REL_I386_ABSOLUTE:
     138             :       // This relocation is ignored.
     139             :       break;
     140           7 :     case COFF::IMAGE_REL_I386_DIR32: {
     141             :       // The target's 32-bit VA.
     142             :       uint64_t Result =
     143           7 :           RE.Sections.SectionA == static_cast<uint32_t>(-1)
     144           7 :               ? Value
     145           5 :               : Sections[RE.Sections.SectionA].getLoadAddressWithOffset(
     146           5 :                     RE.Addend);
     147             :       assert(Result <= UINT32_MAX && "relocation overflow");
     148             :       LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     149             :                         << " RelType: IMAGE_REL_I386_DIR32"
     150             :                         << " TargetSection: " << RE.Sections.SectionA
     151             :                         << " Value: " << format("0x%08" PRIx32, Result)
     152             :                         << '\n');
     153           7 :       writeBytesUnaligned(Result, Target, 4);
     154           7 :       break;
     155             :     }
     156           2 :     case COFF::IMAGE_REL_I386_DIR32NB: {
     157             :       // The target's 32-bit RVA.
     158             :       // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase
     159             :       uint64_t Result =
     160           4 :           Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) -
     161           2 :           Sections[0].getLoadAddress();
     162             :       assert(Result <= UINT32_MAX && "relocation overflow");
     163             :       LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     164             :                         << " RelType: IMAGE_REL_I386_DIR32NB"
     165             :                         << " TargetSection: " << RE.Sections.SectionA
     166             :                         << " Value: " << format("0x%08" PRIx32, Result)
     167             :                         << '\n');
     168           2 :       writeBytesUnaligned(Result, Target, 4);
     169           2 :       break;
     170             :     }
     171           2 :     case COFF::IMAGE_REL_I386_REL32: {
     172             :       // 32-bit relative displacement to the target.
     173           2 :       uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1)
     174           2 :                             ? Value
     175           2 :                             : Sections[RE.Sections.SectionA].getLoadAddress();
     176           2 :       Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;
     177             :       assert(static_cast<int64_t>(Result) <= INT32_MAX &&
     178             :              "relocation overflow");
     179             :       assert(static_cast<int64_t>(Result) >= INT32_MIN &&
     180             :              "relocation underflow");
     181             :       LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     182             :                         << " RelType: IMAGE_REL_I386_REL32"
     183             :                         << " TargetSection: " << RE.Sections.SectionA
     184             :                         << " Value: " << format("0x%08" PRIx32, Result)
     185             :                         << '\n');
     186           2 :       writeBytesUnaligned(Result, Target, 4);
     187           2 :       break;
     188             :     }
     189           1 :     case COFF::IMAGE_REL_I386_SECTION:
     190             :       // 16-bit section index of the section that contains the target.
     191             :       assert(static_cast<uint32_t>(RE.SectionID) <= UINT16_MAX &&
     192             :              "relocation overflow");
     193             :       LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     194             :                         << " RelType: IMAGE_REL_I386_SECTION Value: "
     195             :                         << RE.SectionID << '\n');
     196           1 :       writeBytesUnaligned(RE.SectionID, Target, 2);
     197           1 :       break;
     198           2 :     case COFF::IMAGE_REL_I386_SECREL:
     199             :       // 32-bit offset of the target from the beginning of its section.
     200             :       assert(static_cast<uint64_t>(RE.Addend) <= UINT32_MAX &&
     201             :              "relocation overflow");
     202             :       LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     203             :                         << " RelType: IMAGE_REL_I386_SECREL Value: "
     204             :                         << RE.Addend << '\n');
     205           2 :       writeBytesUnaligned(RE.Addend, Target, 4);
     206           2 :       break;
     207           0 :     default:
     208           0 :       llvm_unreachable("unsupported relocation type");
     209             :     }
     210          14 :   }
     211             : 
     212           1 :   void registerEHFrames() override {}
     213             : };
     214             : 
     215             : }
     216             : 
     217             : #endif
     218             : 

Generated by: LCOV version 1.13