Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/i386.cpp
35271 views
//===---- i386.cpp - Generic JITLink i386 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 i386 objects.9//10//===----------------------------------------------------------------------===//1112#include "llvm/ExecutionEngine/JITLink/i386.h"1314#define DEBUG_TYPE "jitlink"1516namespace llvm::jitlink::i386 {1718const char *getEdgeKindName(Edge::Kind K) {19switch (K) {20case None:21return "None";22case Pointer32:23return "Pointer32";24case PCRel32:25return "PCRel32";26case Pointer16:27return "Pointer16";28case PCRel16:29return "PCRel16";30case Delta32:31return "Delta32";32case Delta32FromGOT:33return "Delta32FromGOT";34case RequestGOTAndTransformToDelta32FromGOT:35return "RequestGOTAndTransformToDelta32FromGOT";36case BranchPCRel32:37return "BranchPCRel32";38case BranchPCRel32ToPtrJumpStub:39return "BranchPCRel32ToPtrJumpStub";40case BranchPCRel32ToPtrJumpStubBypassable:41return "BranchPCRel32ToPtrJumpStubBypassable";42}4344return getGenericEdgeKindName(K);45}4647const char NullPointerContent[PointerSize] = {0x00, 0x00, 0x00, 0x00};4849const char PointerJumpStubContent[6] = {50static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};5152Error optimizeGOTAndStubAccesses(LinkGraph &G) {53LLVM_DEBUG(dbgs() << "Optimizing GOT entries and stubs:\n");5455for (auto *B : G.blocks())56for (auto &E : B->edges()) {57if (E.getKind() == i386::BranchPCRel32ToPtrJumpStubBypassable) {58auto &StubBlock = E.getTarget().getBlock();59assert(StubBlock.getSize() == sizeof(PointerJumpStubContent) &&60"Stub block should be stub sized");61assert(StubBlock.edges_size() == 1 &&62"Stub block should only have one outgoing edge");6364auto &GOTBlock = StubBlock.edges().begin()->getTarget().getBlock();65assert(GOTBlock.getSize() == G.getPointerSize() &&66"GOT block should be pointer sized");67assert(GOTBlock.edges_size() == 1 &&68"GOT block should only have one outgoing edge");6970auto &GOTTarget = GOTBlock.edges().begin()->getTarget();71orc::ExecutorAddr EdgeAddr = B->getAddress() + E.getOffset();72orc::ExecutorAddr TargetAddr = GOTTarget.getAddress();7374int64_t Displacement = TargetAddr - EdgeAddr + 4;75if (isInt<32>(Displacement)) {76E.setKind(i386::BranchPCRel32);77E.setTarget(GOTTarget);78LLVM_DEBUG({79dbgs() << " Replaced stub branch with direct branch:\n ";80printEdge(dbgs(), *B, E, getEdgeKindName(E.getKind()));81dbgs() << "\n";82});83}84}85}8687return Error::success();88}8990} // namespace llvm::jitlink::i386919293