llvm/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp

//===--------- aarch32.cpp - Generic JITLink arm/thumb utilities ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Generic utilities for graphs representing arm/thumb objects.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/JITLink/aarch32.h"

#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"

#define DEBUG_TYPE

namespace llvm {
namespace jitlink {
namespace aarch32 {

/// Check whether the given target flags are set for this Symbol.
bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags) {}

/// Encode 22-bit immediate value for branch instructions without J1J2 range
/// extension (formats B T4, BL T1 and BLX T2).
///
///   00000:Imm11H:Imm11L:0 -> [ 00000:Imm11H, 00000:Imm11L ]
///                                            J1^ ^J2 will always be 1
///
HalfWords encodeImmBT4BlT1BlxT2(int64_t Value) {}

/// Decode 22-bit immediate value for branch instructions without J1J2 range
/// extension (formats B T4, BL T1 and BLX T2).
///
///   [ 00000:Imm11H, 00000:Imm11L ] -> 00000:Imm11H:Imm11L:0
///                   J1^ ^J2 will always be 1
///
int64_t decodeImmBT4BlT1BlxT2(uint32_t Hi, uint32_t Lo) {}

/// Encode 25-bit immediate value for branch instructions with J1J2 range
/// extension (formats B T4, BL T1 and BLX T2).
///
///   S:I1:I2:Imm10:Imm11:0 -> [ 00000:S:Imm10, 00:J1:0:J2:Imm11 ]
///
HalfWords encodeImmBT4BlT1BlxT2_J1J2(int64_t Value) {}

/// Decode 25-bit immediate value for branch instructions with J1J2 range
/// extension (formats B T4, BL T1 and BLX T2).
///
///   [ 00000:S:Imm10, 00:J1:0:J2:Imm11] -> S:I1:I2:Imm10:Imm11:0
///
int64_t decodeImmBT4BlT1BlxT2_J1J2(uint32_t Hi, uint32_t Lo) {}

/// Encode 26-bit immediate value for branch instructions
/// (formats B A1, BL A1 and BLX A2).
///
///   Imm24:00 ->  00000000:Imm24
///
uint32_t encodeImmBA1BlA1BlxA2(int64_t Value) {}

/// Decode 26-bit immediate value for branch instructions
/// (formats B A1, BL A1 and BLX A2).
///
///   00000000:Imm24 ->  Imm24:00
///
int64_t decodeImmBA1BlA1BlxA2(int64_t Value) {}

/// Encode 16-bit immediate value for move instruction formats MOVT T1 and
/// MOVW T3.
///
///   Imm4:Imm1:Imm3:Imm8 -> [ 00000:i:000000:Imm4, 0:Imm3:0000:Imm8 ]
///
HalfWords encodeImmMovtT1MovwT3(uint16_t Value) {}

/// Decode 16-bit immediate value from move instruction formats MOVT T1 and
/// MOVW T3.
///
///   [ 00000:i:000000:Imm4, 0:Imm3:0000:Imm8 ] -> Imm4:Imm1:Imm3:Imm8
///
uint16_t decodeImmMovtT1MovwT3(uint32_t Hi, uint32_t Lo) {}

/// Encode register ID for instruction formats MOVT T1 and MOVW T3.
///
///   Rd4 -> [0000000000000000, 0000:Rd4:00000000]
///
HalfWords encodeRegMovtT1MovwT3(int64_t Value) {}

/// Decode register ID from instruction formats MOVT T1 and MOVW T3.
///
///   [0000000000000000, 0000:Rd4:00000000] -> Rd4
///
int64_t decodeRegMovtT1MovwT3(uint32_t Hi, uint32_t Lo) {}

/// Encode 16-bit immediate value for move instruction formats MOVT A1 and
/// MOVW A2.
///
///   Imm4:Imm12 -> 000000000000:Imm4:0000:Imm12
///
uint32_t encodeImmMovtA1MovwA2(uint16_t Value) {}

/// Decode 16-bit immediate value for move instruction formats MOVT A1 and
/// MOVW A2.
///
///   000000000000:Imm4:0000:Imm12 -> Imm4:Imm12
///
uint16_t decodeImmMovtA1MovwA2(uint64_t Value) {}

/// Encode register ID for instruction formats MOVT A1 and
/// MOVW A2.
///
///   Rd4 -> 0000000000000000:Rd4:000000000000
///
uint32_t encodeRegMovtA1MovwA2(int64_t Value) {}

/// Decode register ID for instruction formats MOVT A1 and
/// MOVW A2.
///
///   0000000000000000:Rd4:000000000000 -> Rd4
///
int64_t decodeRegMovtA1MovwA2(uint64_t Value) {}

namespace {

/// 32-bit Thumb instructions are stored as two little-endian halfwords.
/// An instruction at address A encodes bytes A+1, A in the first halfword (Hi),
/// followed by bytes A+3, A+2 in the second halfword (Lo).
struct WritableThumbRelocation {};

struct ThumbRelocation {};

struct WritableArmRelocation {};

struct ArmRelocation {};

Error makeUnexpectedOpcodeError(const LinkGraph &G, const ThumbRelocation &R,
                                Edge::Kind Kind) {}

Error makeUnexpectedOpcodeError(const LinkGraph &G, const ArmRelocation &R,
                                Edge::Kind Kind) {}

template <EdgeKind_aarch32 K> constexpr bool isArm() {}
template <EdgeKind_aarch32 K> constexpr bool isThumb() {}

template <EdgeKind_aarch32 K> static bool checkOpcodeArm(uint32_t Wd) {}

template <EdgeKind_aarch32 K>
static bool checkOpcodeThumb(uint16_t Hi, uint16_t Lo) {}

class FixupInfoTable {};

ManagedStatic<FixupInfoTable> DynFixupInfos;

} // namespace

static Error checkOpcode(LinkGraph &G, const ArmRelocation &R,
                         Edge::Kind Kind) {}

static Error checkOpcode(LinkGraph &G, const ThumbRelocation &R,
                         Edge::Kind Kind) {}

const FixupInfoBase *FixupInfoBase::getDynFixupInfo(Edge::Kind K) {}

template <EdgeKind_aarch32 Kind>
bool checkRegister(const ThumbRelocation &R, HalfWords Reg) {}

template <EdgeKind_aarch32 Kind>
bool checkRegister(const ArmRelocation &R, uint32_t Reg) {}

template <EdgeKind_aarch32 Kind>
void writeRegister(WritableThumbRelocation &R, HalfWords Reg) {}

template <EdgeKind_aarch32 Kind>
void writeRegister(WritableArmRelocation &R, uint32_t Reg) {}

template <EdgeKind_aarch32 Kind>
void writeImmediate(WritableThumbRelocation &R, HalfWords Imm) {}

template <EdgeKind_aarch32 Kind>
void writeImmediate(WritableArmRelocation &R, uint32_t Imm) {}

Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
                                 Edge::Kind Kind) {}

Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, Edge::OffsetT Offset,
                                Edge::Kind Kind) {}

Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, Edge::OffsetT Offset,
                                  Edge::Kind Kind, const ArmConfig &ArmCfg) {}

Error applyFixupData(LinkGraph &G, Block &B, const Edge &E) {}

Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E) {}

Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
                      const ArmConfig &ArmCfg) {}

const uint8_t GOTEntryInit[] =;

/// Create a new node in the link-graph for the given pointer value.
template <size_t Size>
static Block &allocPointer(LinkGraph &G, Section &S,
                           const uint8_t (&Content)[Size]) {}

Symbol &GOTBuilder::createEntry(LinkGraph &G, Symbol &Target) {}

bool GOTBuilder::visitEdge(LinkGraph &G, Block *B, Edge &E) {}

const uint8_t ArmThumbv5LdrPc[] =;

const uint8_t Armv7ABS[] =;

const uint8_t Thumbv7ABS[] =;

/// Create a new node in the link-graph for the given stub template.
template <size_t Size>
static Block &allocStub(LinkGraph &G, Section &S, const uint8_t (&Code)[Size]) {}

static Block &createStubPrev7(LinkGraph &G, Section &S, Symbol &Target) {}

static Block &createStubThumbv7(LinkGraph &G, Section &S, Symbol &Target) {}

static Block &createStubArmv7(LinkGraph &G, Section &S, Symbol &Target) {}

static bool needsStub(const Edge &E) {}

// The ArmThumbv5LdrPc stub has 2 entrypoints: Thumb at offset 0 is taken only
// for Thumb B instructions. Thumb BL is rewritten to BLX and takes the Arm
// entrypoint at offset 4. Arm branches always use that one.
Symbol *StubsManager_prev7::getOrCreateSlotEntrypoint(LinkGraph &G,
                                                      StubMapEntry &Slot,
                                                      bool Thumb) {}

bool StubsManager_prev7::visitEdge(LinkGraph &G, Block *B, Edge &E) {}

bool StubsManager_v7::visitEdge(LinkGraph &G, Block *B, Edge &E) {}

const char *getEdgeKindName(Edge::Kind K) {}

const char *getCPUArchName(ARMBuildAttrs::CPUArch K) {}

} // namespace aarch32
} // namespace jitlink
} // namespace llvm