[llvm] r251761 - RuntimeDyld: add COFF i386 support
Aaron Ballman via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 4 08:01:11 PST 2015
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]
~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
More information about the llvm-commits
mailing list