[llvm] r251761 - RuntimeDyld: add COFF i386 support

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 4 22:27:32 PST 2015


On Wed, Nov 4, 2015 at 8:01 AM, Aaron Ballman <aaron at aaronballman.com>
wrote:

> On Sat, Oct 31, 2015 at 9:26 PM, Saleem Abdulrasool via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> > Author: compnerd
> > Date: Sat Oct 31 20:26:15 2015
> > New Revision: 251761
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=251761&view=rev
> > Log:
> > RuntimeDyld: add COFF i386 support
> >
> > This adds support for COFF I386.  This is sufficient for code execution
> in a
> > 32-bit JIT, though, imported symbols need to custom lowered for the
> redirection.
> >
> > Added:
> >
>  llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
> >     llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s
> > Modified:
> >     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
> >
> > Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp?rev=251761&r1=251760&r2=251761&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
> (original)
> > +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp Sat
> Oct 31 20:26:15 2015
> > @@ -12,6 +12,7 @@
> >
> //===----------------------------------------------------------------------===//
> >
> >  #include "RuntimeDyldCOFF.h"
> > +#include "Targets/RuntimeDyldCOFFI386.h"
> >  #include "Targets/RuntimeDyldCOFFX86_64.h"
> >  #include "llvm/ADT/STLExtras.h"
> >  #include "llvm/ADT/Triple.h"
> > @@ -47,6 +48,8 @@ llvm::RuntimeDyldCOFF::create(Triple::Ar
> >    default:
> >      llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");
> >      break;
> > +  case Triple::x86:
> > +    return make_unique<RuntimeDyldCOFFI386>(MemMgr, Resolver);
> >    case Triple::x86_64:
> >      return make_unique<RuntimeDyldCOFFX86_64>(MemMgr, Resolver);
> >    }
> >
> > Added:
> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h?rev=251761&view=auto
> >
> ==============================================================================
> > ---
> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
> (added)
> > +++
> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
> Sat Oct 31 20:26:15 2015
> > @@ -0,0 +1,199 @@
> > +//===--- RuntimeDyldCOFFI386.h --- COFF/X86_64 specific code ---*- C++
> --*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// COFF x86 support for MC-JIT runtime dynamic linker.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef
> LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H
> > +#define
> LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H
> > +
> > +#include "llvm/Object/COFF.h"
> > +#include "llvm/Support/COFF.h"
> > +#include "../RuntimeDyldCOFF.h"
> > +
> > +#define DEBUG_TYPE "dyld"
> > +
> > +namespace llvm {
> > +
> > +class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
> > +public:
> > +  RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM,
> > +                      RuntimeDyld::SymbolResolver &Resolver)
> > +      : RuntimeDyldCOFF(MM, Resolver) {}
> > +
> > +  unsigned getMaxStubSize() override {
> > +    return 8; // 2-byte jmp instruction + 32-bit relative address + 2
> byte pad
> > +  }
> > +
> > +  unsigned getStubAlignment() override { return 1; }
> > +
> > +  relocation_iterator processRelocationRef(unsigned SectionID,
> > +                                           relocation_iterator RelI,
> > +                                           const ObjectFile &Obj,
> > +                                           ObjSectionToIDMap
> &ObjSectionToID,
> > +                                           StubMap &Stubs) override {
> > +    auto Symbol = RelI->getSymbol();
> > +    if (Symbol == Obj.symbol_end())
> > +      report_fatal_error("Unknown symbol in relocation");
> > +
> > +    ErrorOr<StringRef> TargetNameOrErr = Symbol->getName();
> > +    if (auto EC = TargetNameOrErr.getError())
> > +      report_fatal_error(EC.message());
> > +    StringRef TargetName = *TargetNameOrErr;
> > +
> > +    auto Section = *Symbol->getSection();
> > +
> > +    uint64_t RelType = RelI->getType();
> > +    uint64_t Offset = RelI->getOffset();
> > +
> > +#if !defined(NDEBUG)
> > +    SmallString<32> RelTypeName;
> > +    RelI->getTypeName(RelTypeName);
> > +#endif
> > +    DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " <<
> Offset
> > +                 << " RelType: " << RelTypeName << " TargetName: " <<
> TargetName
> > +                 << "\n");
> > +
> > +    unsigned TargetSectionID = -1;
> > +    if (Section == Obj.section_end()) {
> > +      RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0,
> false, 0);
> > +      addRelocationForSymbol(RE, TargetName);
> > +    } else {
> > +      TargetSectionID =
> > +          findOrEmitSection(Obj, *Section, Section->isText(),
> ObjSectionToID);
> > +
> > +      switch (RelType) {
> > +      case COFF::IMAGE_REL_I386_ABSOLUTE:
> > +        // This relocation is ignored.
> > +        break;
> > +      case COFF::IMAGE_REL_I386_DIR32:
> > +      case COFF::IMAGE_REL_I386_DIR32NB:
> > +      case COFF::IMAGE_REL_I386_REL32: {
> > +        RelocationEntry RE =
> > +            RelocationEntry(SectionID, Offset, RelType, 0,
> TargetSectionID,
> > +                            getSymbolOffset(*Symbol), 0, 0, false, 0);
> > +        addRelocationForSection(RE, TargetSectionID);
> > +        break;
> > +      }
> > +      case COFF::IMAGE_REL_I386_SECTION: {
> > +        RelocationEntry RE =
> > +            RelocationEntry(TargetSectionID, Offset, RelType, 0);
> > +        addRelocationForSection(RE, TargetSectionID);
> > +        break;
> > +      }
> > +      case COFF::IMAGE_REL_I386_SECREL: {
> > +        RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
> > +                                             getSymbolOffset(*Symbol));
> > +        addRelocationForSection(RE, TargetSectionID);
> > +        break;
> > +      }
> > +      default:
> > +        llvm_unreachable("unsupported relocation type");
> > +      }
> > +
> > +    }
> > +
> > +    return ++RelI;
> > +  }
> > +
> > +  void resolveRelocation(const RelocationEntry &RE, uint64_t Value)
> override {
> > +    const auto Section = Sections[RE.SectionID];
> > +    uint8_t *Target = Section.Address + RE.Offset;
> > +
> > +    switch (RE.RelType) {
> > +    case COFF::IMAGE_REL_I386_ABSOLUTE:
> > +      // This relocation is ignored.
> > +      break;
> > +    case COFF::IMAGE_REL_I386_DIR32: {
> > +      // The target's 32-bit VA.
> > +      uint64_t Result =
> > +          RE.Sections.SectionA == static_cast<uint32_t>(-1)
> > +              ? Value
> > +              : Sections[RE.Sections.SectionA].LoadAddress + RE.Addend;
> > +      assert(static_cast<int32_t>(Result) <= INT32_MAX &&
> > +             "relocation overflow");
> > +      assert(static_cast<int32_t>(Result) >= INT32_MIN &&
> > +             "relocation underflow");
> > +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
> > +                   << " RelType: IMAGE_REL_I386_DIR32"
> > +                   << " TargetSection: " << RE.Sections.SectionA
> > +                   << " Value: " << format("0x%08" PRIx32, Result) <<
> '\n');
> > +      writeBytesUnaligned(Result, Target, 4);
> > +      break;
> > +    }
> > +    case COFF::IMAGE_REL_I386_DIR32NB: {
> > +      // The target's 32-bit RVA.
> > +      // NOTE: use Section[0].LoadAddress as an approximation of
> ImageBase
> > +      uint64_t Result = Sections[RE.Sections.SectionA].LoadAddress +
> RE.Addend -
> > +                        Sections[0].LoadAddress;
> > +      assert(static_cast<int32_t>(Result) <= INT32_MAX &&
> > +             "relocation overflow");
> > +      assert(static_cast<int32_t>(Result) >= INT32_MIN &&
> > +             "relocation underflow");
> > +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
> > +                   << " RelType: IMAGE_REL_I386_DIR32NB"
> > +                   << " TargetSection: " << RE.Sections.SectionA
> > +                   << " Value: " << format("0x%08" PRIx32, Result) <<
> '\n');
> > +      writeBytesUnaligned(Result, Target, 4);
> > +      break;
> > +    }
> > +    case COFF::IMAGE_REL_I386_REL32: {
> > +      // 32-bit relative displacement to the target.
> > +      uint64_t Result = Sections[RE.Sections.SectionA].LoadAddress -
> > +                        Section.LoadAddress + RE.Addend - 4 - RE.Offset;
> > +      assert(static_cast<int32_t>(Result) <= INT32_MAX &&
> > +             "relocation overflow");
> > +      assert(static_cast<int32_t>(Result) >= INT32_MIN &&
> > +             "relocation underflow");
> > +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
> > +                   << " RelType: IMAGE_REL_I386_REL32"
> > +                   << " TargetSection: " << RE.Sections.SectionA
> > +                   << " Value: " << format("0x%08" PRIx32, Result) <<
> '\n');
> > +      writeBytesUnaligned(Result, Target, 4);
> > +      break;
> > +    }
> > +    case COFF::IMAGE_REL_I386_SECTION:
> > +      // 16-bit section index of the section that contains the target.
> > +      assert(static_cast<int16_t>(RE.SectionID) <= INT16_MAX &&
> > +             "relocation overflow");
> > +      assert(static_cast<int16_t>(RE.SectionID) >= INT16_MIN &&
> > +             "relocation underflow");
>
> These asserts are triggering a -Wtype-limits warning.
>
> In file included from
>
> /opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp:15:0:
>
> /opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h:
> In member function ‘virtual void
> llvm::RuntimeDyldCOFFI386::resolveRelocation(const
> llvm::RelocationEntry&, uint64_t)’:
>
> /opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h:164:7:
> warning: comparison is always true due to limited range of data type
> [-Wtype-limits]
>
> /opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h:166:7:
> warning: comparison is always true due to limited range of data type
> [-Wtype-limits]
>
>
Sorry about that.  Should be fixed with SVN r252150.


> ~Aaron
>
> > +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
> > +                   << " RelType: IMAGE_REL_I386_SECTION Value: " <<
> RE.SectionID
> > +                   << '\n');
> > +      writeBytesUnaligned(RE.SectionID, Target, 2);
> > +      break;
> > +    case COFF::IMAGE_REL_I386_SECREL:
> > +      // 32-bit offset of the target from the beginning of its section.
> > +      assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX &&
> > +             "relocation overflow");
> > +      assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN &&
> > +             "relocation underflow");
> > +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
> > +                   << " RelType: IMAGE_REL_I386_SECREL Value: " <<
> RE.Addend
> > +                   << '\n');
> > +      writeBytesUnaligned(RE.Addend, Target, 2);
> > +      break;
> > +    default:
> > +      llvm_unreachable("unsupported relocation type");
> > +    }
> > +  }
> > +
> > +  void registerEHFrames() override {}
> > +  void deregisterEHFrames() override {}
> > +
> > +  void finalizeLoad(const ObjectFile &Obj,
> > +                    ObjSectionToIDMap &SectionMap) override {}
> > +};
> > +
> > +}
> > +
> > +#endif
> > +
> >
> > Added: llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s?rev=251761&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s (added)
> > +++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s Sat Oct
> 31 20:26:15 2015
> > @@ -0,0 +1,66 @@
> > +// RUN: llvm-mc -triple i686-windows -filetype obj -o %t.obj %s
> > +// RUN: llvm-rtdyld -triple i686-windows -dummy-extern
> _OutputDebugStringA at 4=0xfffffffe -dummy-extern _ExitProcess at 4=0xffffffff
> -verify -check=%s %t.obj
> > +
> > +       .text
> > +
> > +       .def _main
> > +               .scl 2
> > +               .type 32
> > +       .endef
> > +       .global _main
> > +_main:
> > +rel1:
> > +       call _function                          // IMAGE_REL_I386_REL32
> > +# rtdyld-check: decode_operand(rel1, 0) = (_function-_main-4-1)
> > +       xorl %eax, %eax
> > +       retl
> > +
> > +       .def _function
> > +               .scl 2
> > +               .type 32
> > +       .endef
> > +_function:
> > +rel2:
> > +       pushl string
> > +rel3:
> > +       calll *__imp__OutputDebugStringA        // IMAGE_REL_I386_DIR32
> > +# rtdyld-check: decode_operand(rel3, 3) = __imp__OutputDebugStringA
> > +       addl  $4, %esp
> > +       pushl $0
> > +rel4:
> > +       calll *__imp__ExitProcess               // IMAGE_REL_I386_DIR32
> > +# rtdyld-check: decode_operand(rel4, 3) = __imp__ExitProcess
> > +       addl  $4, %esp
> > +       retl
> > +
> > +       .data
> > +
> > +       .global __imp__OutputDebugStringA
> > +       .align 4
> > +__imp__OutputDebugStringA:
> > +       .long "_OutputDebugStringA at 4"           // IMAGE_REL_I386_DIR32
> > +# rtdyld-check: *{4}__imp__OutputDebugStringA = 0xfffffffe
> > +
> > +       .global __imp__ExitProcess
> > +       .align 4
> > +__imp__ExitProcess:
> > +       .long "_ExitProcess at 4"                  // IMAGE_REL_I386_DIR32
> > +# rtdyld-check: *{4}__imp__ExitProcess = 0xffffffff
> > +
> > +       .global string
> > +       .align 1
> > +string:
> > +       .asciz "Hello World!\n"
> > +
> > +       .global relocations
> > +relocations:
> > +rel5:
> > +       .long _function at imgrel                  //
> IMAGE_REL_I386_DIR32NB
> > +# rtdyld-check: *{4}rel5 = _function -
> section_addr(COFF_i386.s.tmp.obj, .text)
> > +rel6:
> > +# rtdyld-check: *{2}rel6 = 1
> > +       .secidx __imp__OutputDebugStringA       // IMAGE_REL_I386_SECTION
> > +rel7:
> > +# rtdyld-check: *{4}rel7 = relocations -
> section_addr(COFF_i386.s.tmp.obj, .data)
> > +       .secrel32 relocations                   // IMAGE_REL_I386_SECREL
> > +
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>



-- 
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151104/cd6b6823/attachment-0001.html>


More information about the llvm-commits mailing list