<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 4, 2015 at 8:01 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">On Sat, Oct 31, 2015 at 9:26 PM, Saleem Abdulrasool via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: compnerd<br>
> Date: Sat Oct 31 20:26:15 2015<br>
> New Revision: 251761<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=251761&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=251761&view=rev</a><br>
> Log:<br>
> RuntimeDyld: add COFF i386 support<br>
><br>
> This adds support for COFF I386.  This is sufficient for code execution in a<br>
> 32-bit JIT, though, imported symbols need to custom lowered for the redirection.<br>
><br>
> Added:<br>
>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h<br>
>     llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s<br>
> Modified:<br>
>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp<br>
><br>
> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp?rev=251761&r1=251760&r2=251761&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp?rev=251761&r1=251760&r2=251761&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp (original)<br>
> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp Sat Oct 31 20:26:15 2015<br>
> @@ -12,6 +12,7 @@<br>
>  //===----------------------------------------------------------------------===//<br>
><br>
>  #include "RuntimeDyldCOFF.h"<br>
> +#include "Targets/RuntimeDyldCOFFI386.h"<br>
>  #include "Targets/RuntimeDyldCOFFX86_64.h"<br>
>  #include "llvm/ADT/STLExtras.h"<br>
>  #include "llvm/ADT/Triple.h"<br>
> @@ -47,6 +48,8 @@ llvm::RuntimeDyldCOFF::create(Triple::Ar<br>
>    default:<br>
>      llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");<br>
>      break;<br>
> +  case Triple::x86:<br>
> +    return make_unique<RuntimeDyldCOFFI386>(MemMgr, Resolver);<br>
>    case Triple::x86_64:<br>
>      return make_unique<RuntimeDyldCOFFX86_64>(MemMgr, Resolver);<br>
>    }<br>
><br>
> Added: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h?rev=251761&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h?rev=251761&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h (added)<br>
> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h Sat Oct 31 20:26:15 2015<br>
> @@ -0,0 +1,199 @@<br>
> +//===--- RuntimeDyldCOFFI386.h --- COFF/X86_64 specific code ---*- C++ --*-===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// COFF x86 support for MC-JIT runtime dynamic linker.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H<br>
> +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H<br>
> +<br>
> +#include "llvm/Object/COFF.h"<br>
> +#include "llvm/Support/COFF.h"<br>
> +#include "../RuntimeDyldCOFF.h"<br>
> +<br>
> +#define DEBUG_TYPE "dyld"<br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {<br>
> +public:<br>
> +  RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM,<br>
> +                      RuntimeDyld::SymbolResolver &Resolver)<br>
> +      : RuntimeDyldCOFF(MM, Resolver) {}<br>
> +<br>
> +  unsigned getMaxStubSize() override {<br>
> +    return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad<br>
> +  }<br>
> +<br>
> +  unsigned getStubAlignment() override { return 1; }<br>
> +<br>
> +  relocation_iterator processRelocationRef(unsigned SectionID,<br>
> +                                           relocation_iterator RelI,<br>
> +                                           const ObjectFile &Obj,<br>
> +                                           ObjSectionToIDMap &ObjSectionToID,<br>
> +                                           StubMap &Stubs) override {<br>
> +    auto Symbol = RelI->getSymbol();<br>
> +    if (Symbol == Obj.symbol_end())<br>
> +      report_fatal_error("Unknown symbol in relocation");<br>
> +<br>
> +    ErrorOr<StringRef> TargetNameOrErr = Symbol->getName();<br>
> +    if (auto EC = TargetNameOrErr.getError())<br>
> +      report_fatal_error(EC.message());<br>
> +    StringRef TargetName = *TargetNameOrErr;<br>
> +<br>
> +    auto Section = *Symbol->getSection();<br>
> +<br>
> +    uint64_t RelType = RelI->getType();<br>
> +    uint64_t Offset = RelI->getOffset();<br>
> +<br>
> +#if !defined(NDEBUG)<br>
> +    SmallString<32> RelTypeName;<br>
> +    RelI->getTypeName(RelTypeName);<br>
> +#endif<br>
> +    DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset<br>
> +                 << " RelType: " << RelTypeName << " TargetName: " << TargetName<br>
> +                 << "\n");<br>
> +<br>
> +    unsigned TargetSectionID = -1;<br>
> +    if (Section == Obj.section_end()) {<br>
> +      RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);<br>
> +      addRelocationForSymbol(RE, TargetName);<br>
> +    } else {<br>
> +      TargetSectionID =<br>
> +          findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID);<br>
> +<br>
> +      switch (RelType) {<br>
> +      case COFF::IMAGE_REL_I386_ABSOLUTE:<br>
> +        // This relocation is ignored.<br>
> +        break;<br>
> +      case COFF::IMAGE_REL_I386_DIR32:<br>
> +      case COFF::IMAGE_REL_I386_DIR32NB:<br>
> +      case COFF::IMAGE_REL_I386_REL32: {<br>
> +        RelocationEntry RE =<br>
> +            RelocationEntry(SectionID, Offset, RelType, 0, TargetSectionID,<br>
> +                            getSymbolOffset(*Symbol), 0, 0, false, 0);<br>
> +        addRelocationForSection(RE, TargetSectionID);<br>
> +        break;<br>
> +      }<br>
> +      case COFF::IMAGE_REL_I386_SECTION: {<br>
> +        RelocationEntry RE =<br>
> +            RelocationEntry(TargetSectionID, Offset, RelType, 0);<br>
> +        addRelocationForSection(RE, TargetSectionID);<br>
> +        break;<br>
> +      }<br>
> +      case COFF::IMAGE_REL_I386_SECREL: {<br>
> +        RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,<br>
> +                                             getSymbolOffset(*Symbol));<br>
> +        addRelocationForSection(RE, TargetSectionID);<br>
> +        break;<br>
> +      }<br>
> +      default:<br>
> +        llvm_unreachable("unsupported relocation type");<br>
> +      }<br>
> +<br>
> +    }<br>
> +<br>
> +    return ++RelI;<br>
> +  }<br>
> +<br>
> +  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {<br>
> +    const auto Section = Sections[RE.SectionID];<br>
> +    uint8_t *Target = Section.Address + RE.Offset;<br>
> +<br>
> +    switch (RE.RelType) {<br>
> +    case COFF::IMAGE_REL_I386_ABSOLUTE:<br>
> +      // This relocation is ignored.<br>
> +      break;<br>
> +    case COFF::IMAGE_REL_I386_DIR32: {<br>
> +      // The target's 32-bit VA.<br>
> +      uint64_t Result =<br>
> +          RE.Sections.SectionA == static_cast<uint32_t>(-1)<br>
> +              ? Value<br>
> +              : Sections[RE.Sections.SectionA].LoadAddress + RE.Addend;<br>
> +      assert(static_cast<int32_t>(Result) <= INT32_MAX &&<br>
> +             "relocation overflow");<br>
> +      assert(static_cast<int32_t>(Result) >= INT32_MIN &&<br>
> +             "relocation underflow");<br>
> +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset<br>
> +                   << " RelType: IMAGE_REL_I386_DIR32"<br>
> +                   << " TargetSection: " << RE.Sections.SectionA<br>
> +                   << " Value: " << format("0x%08" PRIx32, Result) << '\n');<br>
> +      writeBytesUnaligned(Result, Target, 4);<br>
> +      break;<br>
> +    }<br>
> +    case COFF::IMAGE_REL_I386_DIR32NB: {<br>
> +      // The target's 32-bit RVA.<br>
> +      // NOTE: use Section[0].LoadAddress as an approximation of ImageBase<br>
> +      uint64_t Result = Sections[RE.Sections.SectionA].LoadAddress + RE.Addend -<br>
> +                        Sections[0].LoadAddress;<br>
> +      assert(static_cast<int32_t>(Result) <= INT32_MAX &&<br>
> +             "relocation overflow");<br>
> +      assert(static_cast<int32_t>(Result) >= INT32_MIN &&<br>
> +             "relocation underflow");<br>
> +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset<br>
> +                   << " RelType: IMAGE_REL_I386_DIR32NB"<br>
> +                   << " TargetSection: " << RE.Sections.SectionA<br>
> +                   << " Value: " << format("0x%08" PRIx32, Result) << '\n');<br>
> +      writeBytesUnaligned(Result, Target, 4);<br>
> +      break;<br>
> +    }<br>
> +    case COFF::IMAGE_REL_I386_REL32: {<br>
> +      // 32-bit relative displacement to the target.<br>
> +      uint64_t Result = Sections[RE.Sections.SectionA].LoadAddress -<br>
> +                        Section.LoadAddress + RE.Addend - 4 - RE.Offset;<br>
> +      assert(static_cast<int32_t>(Result) <= INT32_MAX &&<br>
> +             "relocation overflow");<br>
> +      assert(static_cast<int32_t>(Result) >= INT32_MIN &&<br>
> +             "relocation underflow");<br>
> +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset<br>
> +                   << " RelType: IMAGE_REL_I386_REL32"<br>
> +                   << " TargetSection: " << RE.Sections.SectionA<br>
> +                   << " Value: " << format("0x%08" PRIx32, Result) << '\n');<br>
> +      writeBytesUnaligned(Result, Target, 4);<br>
> +      break;<br>
> +    }<br>
> +    case COFF::IMAGE_REL_I386_SECTION:<br>
> +      // 16-bit section index of the section that contains the target.<br>
> +      assert(static_cast<int16_t>(RE.SectionID) <= INT16_MAX &&<br>
> +             "relocation overflow");<br>
> +      assert(static_cast<int16_t>(RE.SectionID) >= INT16_MIN &&<br>
> +             "relocation underflow");<br>
<br>
</div></div>These asserts are triggering a -Wtype-limits warning.<br>
<br>
In file included from<br>
/opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp:15:0:<br>
/opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h:<br>
In member function ‘virtual void<br>
llvm::RuntimeDyldCOFFI386::resolveRelocation(const<br>
llvm::RelocationEntry&, uint64_t)’:<br>
/opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h:164:7:<br>
warning: comparison is always true due to limited range of data type<br>
[-Wtype-limits]<br>
/opt/llvm/build-llvm/src/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h:166:7:<br>
warning: comparison is always true due to limited range of data type<br>
[-Wtype-limits]<br>
<span class=""><font color="#888888"><br></font></span></blockquote><div> </div><div>Sorry about that.  Should be fixed with SVN r252150.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class=""><font color="#888888">
~Aaron<br>
</font></span><div class=""><div class="h5"><br>
> +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset<br>
> +                   << " RelType: IMAGE_REL_I386_SECTION Value: " << RE.SectionID<br>
> +                   << '\n');<br>
> +      writeBytesUnaligned(RE.SectionID, Target, 2);<br>
> +      break;<br>
> +    case COFF::IMAGE_REL_I386_SECREL:<br>
> +      // 32-bit offset of the target from the beginning of its section.<br>
> +      assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX &&<br>
> +             "relocation overflow");<br>
> +      assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN &&<br>
> +             "relocation underflow");<br>
> +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset<br>
> +                   << " RelType: IMAGE_REL_I386_SECREL Value: " << RE.Addend<br>
> +                   << '\n');<br>
> +      writeBytesUnaligned(RE.Addend, Target, 2);<br>
> +      break;<br>
> +    default:<br>
> +      llvm_unreachable("unsupported relocation type");<br>
> +    }<br>
> +  }<br>
> +<br>
> +  void registerEHFrames() override {}<br>
> +  void deregisterEHFrames() override {}<br>
> +<br>
> +  void finalizeLoad(const ObjectFile &Obj,<br>
> +                    ObjSectionToIDMap &SectionMap) override {}<br>
> +};<br>
> +<br>
> +}<br>
> +<br>
> +#endif<br>
> +<br>
><br>
> Added: llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s?rev=251761&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s?rev=251761&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s (added)<br>
> +++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s Sat Oct 31 20:26:15 2015<br>
> @@ -0,0 +1,66 @@<br>
> +// RUN: llvm-mc -triple i686-windows -filetype obj -o %t.obj %s<br>
> +// RUN: llvm-rtdyld -triple i686-windows -dummy-extern _OutputDebugStringA@4=0xfffffffe -dummy-extern _ExitProcess@4=0xffffffff -verify -check=%s %t.obj<br>
> +<br>
> +       .text<br>
> +<br>
> +       .def _main<br>
> +               .scl 2<br>
> +               .type 32<br>
> +       .endef<br>
> +       .global _main<br>
> +_main:<br>
> +rel1:<br>
> +       call _function                          // IMAGE_REL_I386_REL32<br>
> +# rtdyld-check: decode_operand(rel1, 0) = (_function-_main-4-1)<br>
> +       xorl %eax, %eax<br>
> +       retl<br>
> +<br>
> +       .def _function<br>
> +               .scl 2<br>
> +               .type 32<br>
> +       .endef<br>
> +_function:<br>
> +rel2:<br>
> +       pushl string<br>
> +rel3:<br>
> +       calll *__imp__OutputDebugStringA        // IMAGE_REL_I386_DIR32<br>
> +# rtdyld-check: decode_operand(rel3, 3) = __imp__OutputDebugStringA<br>
> +       addl  $4, %esp<br>
> +       pushl $0<br>
> +rel4:<br>
> +       calll *__imp__ExitProcess               // IMAGE_REL_I386_DIR32<br>
> +# rtdyld-check: decode_operand(rel4, 3) = __imp__ExitProcess<br>
> +       addl  $4, %esp<br>
> +       retl<br>
> +<br>
> +       .data<br>
> +<br>
> +       .global __imp__OutputDebugStringA<br>
> +       .align 4<br>
> +__imp__OutputDebugStringA:<br>
> +       .long "_OutputDebugStringA@4"           // IMAGE_REL_I386_DIR32<br>
> +# rtdyld-check: *{4}__imp__OutputDebugStringA = 0xfffffffe<br>
> +<br>
> +       .global __imp__ExitProcess<br>
> +       .align 4<br>
> +__imp__ExitProcess:<br>
> +       .long "_ExitProcess@4"                  // IMAGE_REL_I386_DIR32<br>
> +# rtdyld-check: *{4}__imp__ExitProcess = 0xffffffff<br>
> +<br>
> +       .global string<br>
> +       .align 1<br>
> +string:<br>
> +       .asciz "Hello World!\n"<br>
> +<br>
> +       .global relocations<br>
> +relocations:<br>
> +rel5:<br>
> +       .long _function@imgrel                  // IMAGE_REL_I386_DIR32NB<br>
> +# rtdyld-check: *{4}rel5 = _function - section_addr(COFF_i386.s.tmp.obj, .text)<br>
> +rel6:<br>
> +# rtdyld-check: *{2}rel6 = 1<br>
> +       .secidx __imp__OutputDebugStringA       // IMAGE_REL_I386_SECTION<br>
> +rel7:<br>
> +# rtdyld-check: *{4}rel7 = relocations - section_addr(COFF_i386.s.tmp.obj, .data)<br>
> +       .secrel32 relocations                   // IMAGE_REL_I386_SECREL<br>
> +<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Saleem Abdulrasool<br>compnerd (at) compnerd (dot) org</div>
</div></div>