Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/x86.cpp
213799 views
//===-------- x86.cpp - Generic JITLink x86 edge kinds, utilities ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Generic utilities for graphs representing x86 objects.9//10//===----------------------------------------------------------------------===//1112#include "llvm/ExecutionEngine/JITLink/x86.h"1314#define DEBUG_TYPE "jitlink"1516namespace llvm::jitlink::x86 {1718const char *getEdgeKindName(Edge::Kind K) {19switch (K) {20case Pointer32:21return "Pointer32";22case PCRel32:23return "PCRel32";24case Pointer16:25return "Pointer16";26case PCRel16:27return "PCRel16";28case Delta32:29return "Delta32";30case Delta32FromGOT:31return "Delta32FromGOT";32case RequestGOTAndTransformToDelta32FromGOT:33return "RequestGOTAndTransformToDelta32FromGOT";34case BranchPCRel32:35return "BranchPCRel32";36case BranchPCRel32ToPtrJumpStub:37return "BranchPCRel32ToPtrJumpStub";38case BranchPCRel32ToPtrJumpStubBypassable:39return "BranchPCRel32ToPtrJumpStubBypassable";40}4142return getGenericEdgeKindName(K);43}4445const char NullPointerContent[PointerSize] = {0x00, 0x00, 0x00, 0x00};4647const char PointerJumpStubContent[6] = {48static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};4950Error optimizeGOTAndStubAccesses(LinkGraph &G) {51LLVM_DEBUG(dbgs() << "Optimizing GOT entries and stubs:\n");5253for (auto *B : G.blocks())54for (auto &E : B->edges()) {55if (E.getKind() == BranchPCRel32ToPtrJumpStubBypassable) {56auto &StubBlock = E.getTarget().getBlock();57assert(StubBlock.getSize() == sizeof(PointerJumpStubContent) &&58"Stub block should be stub sized");59assert(StubBlock.edges_size() == 1 &&60"Stub block should only have one outgoing edge");6162auto &GOTBlock = StubBlock.edges().begin()->getTarget().getBlock();63assert(GOTBlock.getSize() == G.getPointerSize() &&64"GOT block should be pointer sized");65assert(GOTBlock.edges_size() == 1 &&66"GOT block should only have one outgoing edge");6768auto &GOTTarget = GOTBlock.edges().begin()->getTarget();69orc::ExecutorAddr EdgeAddr = B->getAddress() + E.getOffset();70orc::ExecutorAddr TargetAddr = GOTTarget.getAddress();7172int64_t Displacement = TargetAddr - EdgeAddr + 4;73if (isInt<32>(Displacement)) {74E.setKind(BranchPCRel32);75E.setTarget(GOTTarget);76LLVM_DEBUG({77dbgs() << " Replaced stub branch with direct branch:\n ";78printEdge(dbgs(), *B, E, getEdgeKindName(E.getKind()));79dbgs() << "\n";80});81}82}83}8485return Error::success();86}8788} // namespace llvm::jitlink::x86899091