LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/RuntimeDyld/Targets - RuntimeDyldCOFFI386.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 71 80 88.8 %
Date: 2017-09-14 15:23:50 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           2 :       : 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          26 :     auto Symbol = RelI->getSymbol();
      45          26 :     if (Symbol == Obj.symbol_end())
      46           0 :       report_fatal_error("Unknown symbol in relocation");
      47             : 
      48          39 :     Expected<StringRef> TargetNameOrErr = Symbol->getName();
      49          13 :     if (!TargetNameOrErr)
      50           0 :       return TargetNameOrErr.takeError();
      51          13 :     StringRef TargetName = *TargetNameOrErr;
      52             : 
      53          26 :     auto SectionOrErr = Symbol->getSection();
      54          13 :     if (!SectionOrErr)
      55           0 :       return SectionOrErr.takeError();
      56          13 :     auto Section = *SectionOrErr;
      57             : 
      58          26 :     uint64_t RelType = RelI->getType();
      59          26 :     uint64_t Offset = RelI->getOffset();
      60             : 
      61             :     // Determine the Addend used to adjust the relocation value.
      62          13 :     uint64_t Addend = 0;
      63          26 :     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          13 :     unsigned TargetSectionID = -1;
      88          26 :     if (Section == Obj.section_end()) {
      89           6 :       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          40 :           findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID))
      94          10 :         TargetSectionID = *TargetSectionIDOrErr;
      95             :       else
      96           0 :         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          21 :                             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           2 :             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           6 :                                              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          13 :     return ++RelI;
     130             :   }
     131             : 
     132          13 :   void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
     133          39 :     const auto Section = Sections[RE.SectionID];
     134          26 :     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          17 :               ? Value
     145          10 :               : Sections[RE.Sections.SectionA].getLoadAddressWithOffset(
     146          12 :                     RE.Addend);
     147             :       assert(static_cast<int32_t>(Result) <= INT32_MAX &&
     148             :              "relocation overflow");
     149             :       assert(static_cast<int32_t>(Result) >= INT32_MIN &&
     150             :              "relocation underflow");
     151             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     152             :                    << " RelType: IMAGE_REL_I386_DIR32"
     153             :                    << " TargetSection: " << RE.Sections.SectionA
     154             :                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
     155           7 :       writeBytesUnaligned(Result, Target, 4);
     156           7 :       break;
     157             :     }
     158           2 :     case COFF::IMAGE_REL_I386_DIR32NB: {
     159             :       // The target's 32-bit RVA.
     160             :       // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase
     161             :       uint64_t Result =
     162           6 :           Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) -
     163           4 :           Sections[0].getLoadAddress();
     164             :       assert(static_cast<int32_t>(Result) <= INT32_MAX &&
     165             :              "relocation overflow");
     166             :       assert(static_cast<int32_t>(Result) >= INT32_MIN &&
     167             :              "relocation underflow");
     168             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     169             :                    << " RelType: IMAGE_REL_I386_DIR32NB"
     170             :                    << " TargetSection: " << RE.Sections.SectionA
     171             :                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
     172           2 :       writeBytesUnaligned(Result, Target, 4);
     173           2 :       break;
     174             :     }
     175           1 :     case COFF::IMAGE_REL_I386_REL32: {
     176             :       // 32-bit relative displacement to the target.
     177           1 :       uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1)
     178           1 :                             ? Value
     179           0 :                             : Sections[RE.Sections.SectionA].getLoadAddress();
     180           1 :       Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;
     181             :       assert(static_cast<int32_t>(Result) <= INT32_MAX &&
     182             :              "relocation overflow");
     183             :       assert(static_cast<int32_t>(Result) >= INT32_MIN &&
     184             :              "relocation underflow");
     185             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     186             :                    << " RelType: IMAGE_REL_I386_REL32"
     187             :                    << " TargetSection: " << RE.Sections.SectionA
     188             :                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
     189           1 :       writeBytesUnaligned(Result, Target, 4);
     190           1 :       break;
     191             :     }
     192           1 :     case COFF::IMAGE_REL_I386_SECTION:
     193             :       // 16-bit section index of the section that contains the target.
     194             :       assert(static_cast<int32_t>(RE.SectionID) <= INT16_MAX &&
     195             :              "relocation overflow");
     196             :       assert(static_cast<int32_t>(RE.SectionID) >= INT16_MIN &&
     197             :              "relocation underflow");
     198             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     199             :                    << " RelType: IMAGE_REL_I386_SECTION Value: " << RE.SectionID
     200             :                    << '\n');
     201           1 :       writeBytesUnaligned(RE.SectionID, Target, 2);
     202           1 :       break;
     203           2 :     case COFF::IMAGE_REL_I386_SECREL:
     204             :       // 32-bit offset of the target from the beginning of its section.
     205             :       assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX &&
     206             :              "relocation overflow");
     207             :       assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN &&
     208             :              "relocation underflow");
     209             :       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
     210             :                    << " RelType: IMAGE_REL_I386_SECREL Value: " << RE.Addend
     211             :                    << '\n');
     212           2 :       writeBytesUnaligned(RE.Addend, Target, 2);
     213           2 :       break;
     214           0 :     default:
     215           0 :       llvm_unreachable("unsupported relocation type");
     216             :     }
     217          13 :   }
     218             : 
     219           1 :   void registerEHFrames() override {}
     220             : };
     221             : 
     222             : }
     223             : 
     224             : #endif
     225             : 

Generated by: LCOV version 1.13