brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · a07cdd6 Raw
90 lines · cpp
1//===-------- x86.cpp - Generic JITLink x86 edge kinds, utilities ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Generic utilities for graphs representing x86 objects.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/ExecutionEngine/JITLink/x86.h"14 15#define DEBUG_TYPE "jitlink"16 17namespace llvm::jitlink::x86 {18 19const char *getEdgeKindName(Edge::Kind K) {20  switch (K) {21  case Pointer32:22    return "Pointer32";23  case PCRel32:24    return "PCRel32";25  case Pointer16:26    return "Pointer16";27  case PCRel16:28    return "PCRel16";29  case Delta32:30    return "Delta32";31  case Delta32FromGOT:32    return "Delta32FromGOT";33  case RequestGOTAndTransformToDelta32FromGOT:34    return "RequestGOTAndTransformToDelta32FromGOT";35  case BranchPCRel32:36    return "BranchPCRel32";37  case BranchPCRel32ToPtrJumpStub:38    return "BranchPCRel32ToPtrJumpStub";39  case BranchPCRel32ToPtrJumpStubBypassable:40    return "BranchPCRel32ToPtrJumpStubBypassable";41  }42 43  return getGenericEdgeKindName(K);44}45 46const char NullPointerContent[PointerSize] = {0x00, 0x00, 0x00, 0x00};47 48const char PointerJumpStubContent[6] = {49    static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};50 51Error optimizeGOTAndStubAccesses(LinkGraph &G) {52  LLVM_DEBUG(dbgs() << "Optimizing GOT entries and stubs:\n");53 54  for (auto *B : G.blocks())55    for (auto &E : B->edges()) {56      if (E.getKind() == BranchPCRel32ToPtrJumpStubBypassable) {57        auto &StubBlock = E.getTarget().getBlock();58        assert(StubBlock.getSize() == sizeof(PointerJumpStubContent) &&59               "Stub block should be stub sized");60        assert(StubBlock.edges_size() == 1 &&61               "Stub block should only have one outgoing edge");62 63        auto &GOTBlock = StubBlock.edges().begin()->getTarget().getBlock();64        assert(GOTBlock.getSize() == G.getPointerSize() &&65               "GOT block should be pointer sized");66        assert(GOTBlock.edges_size() == 1 &&67               "GOT block should only have one outgoing edge");68 69        auto &GOTTarget = GOTBlock.edges().begin()->getTarget();70        orc::ExecutorAddr EdgeAddr = B->getAddress() + E.getOffset();71        orc::ExecutorAddr TargetAddr = GOTTarget.getAddress();72 73        int64_t Displacement = TargetAddr - EdgeAddr + 4;74        if (isInt<32>(Displacement)) {75          E.setKind(BranchPCRel32);76          E.setTarget(GOTTarget);77          LLVM_DEBUG({78            dbgs() << "  Replaced stub branch with direct branch:\n    ";79            printEdge(dbgs(), *B, E, getEdgeKindName(E.getKind()));80            dbgs() << "\n";81          });82        }83      }84    }85 86  return Error::success();87}88 89} // namespace llvm::jitlink::x8690