LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/RuntimeDyld/Targets - RuntimeDyldCOFFI386.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 64 70 91.4 %
Date: 2018-02-18 16:14:26 Functions: 6 7 85.7 %
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           2 : 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          13 :   processRelocationRef(unsigned SectionID,
      39             :                        relocation_iterator RelI,
      40             :                        const ObjectFile &Obj,
      41             :                        ObjSectionToIDMap &ObjSectionToID,
      42             :                        StubMap &Stubs) override {
      43             : 
      44          13 :     auto Symbol = RelI->getSymbol();
      45          26 :     if (Symbol == Obj.symbol_end())
      46           0 :       report_fatal_error("Unknown symbol in relocation");
      47             : 
      48             :     Expected<StringRef> TargetNameOrErr = Symbol->getName();
      49          13 :     if (!TargetNameOrErr)
      50             :       return TargetNameOrErr.takeError();
      51          13 :     StringRef TargetName = *TargetNameOrErr;
      52             : 
      53             :     auto SectionOrErr = Symbol->getSection();
      54          13 :     if (!SectionOrErr)
      55             :       return SectionOrErr.takeError();
      56          13 :     auto Section = *SectionOrErr;
      57             : 
      58             :     uint64_t RelType = RelI->getType();
      59             :     uint64_t Offset = RelI->getOffset();
      60             : 
      61             :     // Determine the Addend used to adjust the relocation value.
      62             :     uint64_t Addend = 0;
      63          13 :     SectionEntry &AddendSection = Sections[SectionID];
      64          13 :     uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;
      65          13 :     uint8_t *Displacement = (uint8_t *)ObjTarget;
      66             : 
      67             :     switch (RelType) {
      68          12 :     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          12 :       Addend = readBytesUnaligned(Displacement, 4);
      73          12 :       break;
      74             :     }
      75             :     default:
      76             :       break;
      77             :     }
      78             : 
      79             : #if !defined(NDEBUG)
      80             :     SmallString<32> RelTypeName;
      81             :     RelI->getTypeName(RelTypeName);
      82             : #endif
      83             :     DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
      84             :                  << " RelType: " << RelTypeName << " TargetName: " << TargetName
      85             :                  << " Addend " << Addend << "\n");
      86             : 
      87             :     unsigned TargetSectionID = -1;
      88          26 :     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          10 :       if (auto TargetSectionIDOrErr =
      93          20 :           findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID))
      94          10 :         TargetSectionID = *TargetSectionIDOrErr;
      95             :       else
      96             :         return TargetSectionIDOrErr.takeError();
      97             : 
      98          10 :       switch (RelType) {
      99             :       case COFF::IMAGE_REL_I386_ABSOLUTE:
     100             :         // This relocation is ignored.
     101             :         break;
     102           7 :       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           7 :                             getSymbolOffset(*Symbol), 0, 0, false, 0);
     108           7 :         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          13 :   void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
     133          26 :     const auto Section = Sections[RE.SectionID];
     134          13 :     uint8_t *Target = Section.getAddressWithOffset(RE.Offset);
     135             : 
     136          13 :     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             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     149             :                    << " RelType: IMAGE_REL_I386_DIR32"
     150             :                    << " TargetSection: " << RE.Sections.SectionA
     151             :                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
     152           7 :       writeBytesUnaligned(Result, Target, 4);
     153           7 :       break;
     154             :     }
     155           2 :     case COFF::IMAGE_REL_I386_DIR32NB: {
     156             :       // The target's 32-bit RVA.
     157             :       // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase
     158             :       uint64_t Result =
     159           4 :           Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) -
     160           2 :           Sections[0].getLoadAddress();
     161             :       assert(Result <= UINT32_MAX && "relocation overflow");
     162             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     163             :                    << " RelType: IMAGE_REL_I386_DIR32NB"
     164             :                    << " TargetSection: " << RE.Sections.SectionA
     165             :                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
     166           2 :       writeBytesUnaligned(Result, Target, 4);
     167           2 :       break;
     168             :     }
     169           1 :     case COFF::IMAGE_REL_I386_REL32: {
     170             :       // 32-bit relative displacement to the target.
     171           1 :       uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1)
     172           1 :                             ? Value
     173           0 :                             : Sections[RE.Sections.SectionA].getLoadAddress();
     174           1 :       Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;
     175             :       assert(static_cast<int64_t>(Result) <= INT32_MAX &&
     176             :              "relocation overflow");
     177             :       assert(static_cast<int64_t>(Result) >= INT32_MIN &&
     178             :              "relocation underflow");
     179             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     180             :                    << " RelType: IMAGE_REL_I386_REL32"
     181             :                    << " TargetSection: " << RE.Sections.SectionA
     182             :                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
     183           1 :       writeBytesUnaligned(Result, Target, 4);
     184           1 :       break;
     185             :     }
     186           1 :     case COFF::IMAGE_REL_I386_SECTION:
     187             :       // 16-bit section index of the section that contains the target.
     188             :       assert(static_cast<uint32_t>(RE.SectionID) <= UINT16_MAX &&
     189             :              "relocation overflow");
     190             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     191             :                    << " RelType: IMAGE_REL_I386_SECTION Value: " << RE.SectionID
     192             :                    << '\n');
     193           1 :       writeBytesUnaligned(RE.SectionID, Target, 2);
     194           1 :       break;
     195           2 :     case COFF::IMAGE_REL_I386_SECREL:
     196             :       // 32-bit offset of the target from the beginning of its section.
     197             :       assert(static_cast<uint64_t>(RE.Addend) <= UINT32_MAX &&
     198             :              "relocation overflow");
     199             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     200             :                    << " RelType: IMAGE_REL_I386_SECREL Value: " << RE.Addend
     201             :                    << '\n');
     202           2 :       writeBytesUnaligned(RE.Addend, Target, 4);
     203           2 :       break;
     204           0 :     default:
     205           0 :       llvm_unreachable("unsupported relocation type");
     206             :     }
     207          13 :   }
     208             : 
     209           1 :   void registerEHFrames() override {}
     210             : };
     211             : 
     212             : }
     213             : 
     214             : #endif
     215             : 

Generated by: LCOV version 1.13