[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