llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp

//===-- x86AssemblyInspectionEngine.cpp -----------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "x86AssemblyInspectionEngine.h"

#include <memory>

#include "llvm-c/Disassembler.h"

#include "lldb/Core/Address.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/UnwindAssembly.h"

usingnamespacelldb_private;
usingnamespacelldb;

x86AssemblyInspectionEngine::x86AssemblyInspectionEngine(const ArchSpec &arch)
    :{}

x86AssemblyInspectionEngine::~x86AssemblyInspectionEngine() {}

void x86AssemblyInspectionEngine::Initialize(RegisterContextSP &reg_ctx) {}

void x86AssemblyInspectionEngine::Initialize(
    std::vector<lldb_reg_info> &reg_info) {}

// This function expects an x86 native register number (i.e. the bits stripped
// out of the actual instruction), not an lldb register number.
//
// FIXME: This is ABI dependent, it shouldn't be hardcoded here.

bool x86AssemblyInspectionEngine::nonvolatile_reg_p(int machine_regno) {}

// Macro to detect if this is a REX mode prefix byte.
#define REX_W_PREFIX_P(opcode)

// The high bit which should be added to the source register number (the "R"
// bit)
#define REX_W_SRCREG(opcode)

// The high bit which should be added to the destination register number (the
// "B" bit)
#define REX_W_DSTREG(opcode)

// pushq %rbp [0x55]
bool x86AssemblyInspectionEngine::push_rbp_pattern_p() {}

// pushq $0 ; the first instruction in start() [0x6a 0x00]
bool x86AssemblyInspectionEngine::push_0_pattern_p() {}

// pushq $0
// pushl $0
bool x86AssemblyInspectionEngine::push_imm_pattern_p() {}

// pushl imm8(%esp)
//
// e.g. 0xff 0x74 0x24 0x20 - 'pushl 0x20(%esp)' (same byte pattern for 'pushq
// 0x20(%rsp)' in an x86_64 program)
//
// 0xff (with opcode bits '6' in next byte, PUSH r/m32) 0x74 (ModR/M byte with
// three bits used to specify the opcode)
//      mod == b01, opcode == b110, R/M == b100
//      "+disp8"
// 0x24 (SIB byte - scaled index = 0, r32 == esp) 0x20 imm8 value

bool x86AssemblyInspectionEngine::push_extended_pattern_p() {}

// instructions only valid in 32-bit mode:
// 0x0e - push cs
// 0x16 - push ss
// 0x1e - push ds
// 0x06 - push es
bool x86AssemblyInspectionEngine::push_misc_reg_p() {}

// pushq %rbx
// pushl %ebx
bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {}

// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5] movl %esp, %ebp [0x8b
// 0xec] or [0x89 0xe5]
bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {}

// movq %rsp, %rbx [0x48 0x8b 0xdc] or [0x48 0x89 0xe3]
// movl %esp, %ebx [0x8b 0xdc] or [0x89 0xe3]
bool x86AssemblyInspectionEngine::mov_rsp_rbx_pattern_p() {}

// movq %rbp, %rsp [0x48 0x8b 0xe5] or [0x48 0x89 0xec]
// movl %ebp, %esp [0x8b 0xe5] or [0x89 0xec]
bool x86AssemblyInspectionEngine::mov_rbp_rsp_pattern_p() {}

// movq %rbx, %rsp [0x48 0x8b 0xe3] or [0x48 0x89 0xdc]
// movl %ebx, %esp [0x8b 0xe3] or [0x89 0xdc]
bool x86AssemblyInspectionEngine::mov_rbx_rsp_pattern_p() {}

// subq $0x20, %rsp
bool x86AssemblyInspectionEngine::sub_rsp_pattern_p(int &amount) {}

// addq $0x20, %rsp
bool x86AssemblyInspectionEngine::add_rsp_pattern_p(int &amount) {}

// lea esp, [esp - 0x28]
// lea esp, [esp + 0x28]
bool x86AssemblyInspectionEngine::lea_rsp_pattern_p(int &amount) {}

// lea -0x28(%ebp), %esp
// (32-bit and 64-bit variants, 8-bit and 32-bit displacement)
bool x86AssemblyInspectionEngine::lea_rbp_rsp_pattern_p(int &amount) {}

// lea -0x28(%ebx), %esp
// (32-bit and 64-bit variants, 8-bit and 32-bit displacement)
bool x86AssemblyInspectionEngine::lea_rbx_rsp_pattern_p(int &amount) {}

// and -0xfffffff0, %esp
// (32-bit and 64-bit variants, 8-bit and 32-bit displacement)
bool x86AssemblyInspectionEngine::and_rsp_pattern_p() {}

// popq %rbx
// popl %ebx
bool x86AssemblyInspectionEngine::pop_reg_p(int &regno) {}

// popq %rbp [0x5d]
// popl %ebp [0x5d]
bool x86AssemblyInspectionEngine::pop_rbp_pattern_p() {}

// instructions valid only in 32-bit mode:
// 0x1f - pop ds
// 0x07 - pop es
// 0x17 - pop ss
bool x86AssemblyInspectionEngine::pop_misc_reg_p() {}

// leave [0xc9]
bool x86AssemblyInspectionEngine::leave_pattern_p() {}

// call $0 [0xe8 0x0 0x0 0x0 0x0]
bool x86AssemblyInspectionEngine::call_next_insn_pattern_p() {}

// Look for an instruction sequence storing a nonvolatile register on to the
// stack frame.

//  movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
//  movl %eax, -0xc(%ebp)  [0x89 0x45 0xf4]

// The offset value returned in rbp_offset will be positive -- but it must be
// subtraced from the frame base register to get the actual location.  The
// positive value returned for the offset is a convention used elsewhere for
// CFA offsets et al.

bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(
    int &regno, int &rbp_offset) {}

// Returns true if this is a jmp instruction where we can't
// know the destination address statically. 
//
// ff e0                                   jmpq   *%rax
// ff e1                                   jmpq   *%rcx
// ff 60 28                                jmpq   *0x28(%rax)
// ff 60 60                                jmpq   *0x60(%rax)
bool x86AssemblyInspectionEngine::jmp_to_reg_p() {}

// Detect branches to fixed pc-relative offsets.
// Returns the offset from the address of the next instruction
// that may be branch/jumped to.
//
// Cannot determine the offset of a JMP that jumps to the address in
// a register ("jmpq *%rax") or offset from a register value 
// ("jmpq *0x28(%rax)"), this method will return false on those
// instructions.
//
// These instructions all end in either a relative 8/16/32 bit value
// depending on the instruction and the current execution mode of the
// inferior process.  Once we know the size of the opcode instruction, 
// we can use the total instruction length to determine the size of
// the relative offset without having to compute it correctly.

bool x86AssemblyInspectionEngine::pc_rel_branch_or_jump_p (
    const int instruction_length, int &offset)
{}

// Returns true if this instruction is a intra-function branch or jump -
// a branch/jump within the bounds of this same function.
// Cannot predict where a jump through a register value ("jmpq *%rax")
// will go, so it will return false on that instruction.
bool x86AssemblyInspectionEngine::local_branch_p (
    const addr_t current_func_text_offset,
    const AddressRange &func_range,
    const int instruction_length,
    addr_t &target_insn_offset) {}

// Returns true if this instruction is a inter-function branch or jump - a
// branch/jump to another function.
// Cannot predict where a jump through a register value ("jmpq *%rax")
// will go, so it will return false on that instruction.
bool x86AssemblyInspectionEngine::non_local_branch_p (
    const addr_t current_func_text_offset,
    const AddressRange &func_range,
    const int instruction_length) {}

// ret [0xc3] or [0xcb] or [0xc2 imm16] or [0xca imm16]
bool x86AssemblyInspectionEngine::ret_pattern_p() {}

uint16_t x86AssemblyInspectionEngine::extract_2(uint8_t *b) {}

int16_t x86AssemblyInspectionEngine::extract_2_signed(uint8_t *b) {}

uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) {}

int32_t x86AssemblyInspectionEngine::extract_4_signed(uint8_t *b) {}


bool x86AssemblyInspectionEngine::instruction_length(uint8_t *insn_p,
                                                     int &length, 
                                                     uint32_t buffer_remaining_bytes) {}

bool x86AssemblyInspectionEngine::machine_regno_to_lldb_regno(
    int machine_regno, uint32_t &lldb_regno) {}

bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
    uint8_t *data, size_t size, AddressRange &func_range,
    UnwindPlan &unwind_plan) {}

bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
    uint8_t *data, size_t size, AddressRange &func_range,
    UnwindPlan &unwind_plan, RegisterContextSP &reg_ctx) {}

bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(
    uint8_t *data, size_t size, size_t &offset) {}