#!/usr/bin/env python #===-- armv7_cortex_m_target_definition.py.py ------------------*- C++ -*-===// # # The LLVM Compiler Infrastructure # # 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 # #===----------------------------------------------------------------------===// #---------------------------------------------------------------------- # DESCRIPTION # # This file can be used with the following setting: # plugin.process.gdb-remote.target-definition-file # This setting should be used when you are trying to connect to a # remote GDB server that doesn't support any of the register discovery # packets that LLDB normally uses. # # Why is this necessary? LLDB doesn't require a new build of LLDB that # targets each new architecture you will debug with. Instead, all # architectures are supported and LLDB relies on extra GDB server # packets to discover the target we are connecting to so that is can # show the right registers for each target. This allows the GDB server # to change and add new registers without requiring a new LLDB build # just so we can see new registers. # # This file implements the x86_64 registers for the darwin version of # GDB and allows you to connect to servers that use this register set. # # USAGE # # (lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/armv7_cortex_m_target_defintion.py # (lldb) gdb-remote other.baz.com:1234 # # The target definition file will get used if and only if the # qRegisterInfo packets are not supported when connecting to a remote # GDB server. #---------------------------------------------------------------------- from lldb import * # DWARF register numbers name_to_dwarf_regnum = { 'r0' : 0 , 'r1' : 1 , 'r2' : 2 , 'r3' : 3 , 'r4' : 4 , 'r5' : 5 , 'r6' : 6 , 'r7' : 7 , 'r9' : 8 , 'r10' : 9 , 'r11' : 10, 'r12' : 11, 'sp' : 12, 'lr' : 13, 'pc' : 14, 'r15' : 15, 'xpsr' : 16, }; name_to_generic_regnum = { 'pc' : LLDB_REGNUM_GENERIC_PC, 'sp' : LLDB_REGNUM_GENERIC_SP, 'r7' : LLDB_REGNUM_GENERIC_FP, 'lr' : LLDB_REGNUM_GENERIC_RA, 'r0' : LLDB_REGNUM_GENERIC_ARG1, 'r1' : LLDB_REGNUM_GENERIC_ARG2, 'r2' : LLDB_REGNUM_GENERIC_ARG3, 'r3' : LLDB_REGNUM_GENERIC_ARG4 }; def get_reg_num (reg_num_dict, reg_name): if reg_name in reg_num_dict: return reg_num_dict[reg_name] return LLDB_INVALID_REGNUM def get_reg_num (reg_num_dict, reg_name): if reg_name in reg_num_dict: return reg_num_dict[reg_name] return LLDB_INVALID_REGNUM armv7_register_infos = [ { 'name':'r0' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg1' }, { 'name':'r1' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg2' }, { 'name':'r2' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg3' }, { 'name':'r3' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'arg4' }, { 'name':'r4' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r5' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r6' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r7' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'fp' }, { 'name':'r8' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r9' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r10' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r11' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'r12' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo }, { 'name':'sp' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'r13' }, { 'name':'lr' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'r14' }, { 'name':'pc' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'r15' }, { 'name':'xpsr' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo, 'alt-name':'cpsr' }, ]; g_target_definition = None def get_target_definition (): global g_target_definition if g_target_definition == None: g_target_definition = {} offset = 0 for reg_info in armv7_register_infos: reg_name = reg_info['name'] if 'slice' not in reg_info and 'composite' not in reg_info: reg_info['offset'] = offset offset += reg_info['bitsize'] / 8 # Set the DWARF/eh_frame register number for this register if it has one reg_num = get_reg_num(name_to_dwarf_regnum, reg_name) if reg_num != LLDB_INVALID_REGNUM: reg_info['gcc'] = reg_num reg_info['ehframe'] = reg_num # Set the generic register number for this register if it has one reg_num = get_reg_num(name_to_generic_regnum, reg_name) if reg_num != LLDB_INVALID_REGNUM: reg_info['generic'] = reg_num g_target_definition['sets'] = ['General Purpose Registers'] g_target_definition['registers'] = armv7_register_infos g_target_definition['host-info'] = { 'triple' : 'armv7em--', 'endian': eByteOrderLittle } g_target_definition['g-packet-size'] = offset return g_target_definition def get_dynamic_setting(target, setting_name): if setting_name == 'gdb-server-target-definition': return get_target_definition()