[llvm] r251761 - RuntimeDyld: add COFF i386 support

Aaron Ballman via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 5 05:36:13 PST 2015


On Thu, Nov 5, 2015 at 1:27 AM, Saleem Abdulrasool
<compnerd at compnerd.org> wrote:
>
>
> 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.

Thanks!

~Aaron

>
>>
>> ~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


More information about the llvm-commits mailing list