1#!/usr/bin/env python
2#===-- armv7_cortex_m_target_definition.py.py ------------------*- C++ -*-===//
3#
4#                     The LLVM Compiler Infrastructure
5#
6# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7# See https://llvm.org/LICENSE.txt for license information.
8# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9#
10#===----------------------------------------------------------------------===//
11
12#----------------------------------------------------------------------
13# DESCRIPTION
14#
15# This file can be used with the following setting:
16#   plugin.process.gdb-remote.target-definition-file
17# This setting should be used when you are trying to connect to a
18# remote GDB server that doesn't support any of the register discovery
19# packets that LLDB normally uses.
20#
21# Why is this necessary? LLDB doesn't require a new build of LLDB that
22# targets each new architecture you will debug with. Instead, all
23# architectures are supported and LLDB relies on extra GDB server
24# packets to discover the target we are connecting to so that is can
25# show the right registers for each target. This allows the GDB server
26# to change and add new registers without requiring a new LLDB build
27# just so we can see new registers.
28#
29# This file implements the x86_64 registers for the darwin version of
30# GDB and allows you to connect to servers that use this register set.
31#
32# USAGE
33#
34# (lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/armv7_cortex_m_target_defintion.py
35# (lldb) gdb-remote other.baz.com:1234
36#
37# The target definition file will get used if and only if the
38# qRegisterInfo packets are not supported when connecting to a remote
39# GDB server.
40#----------------------------------------------------------------------
41
42from lldb import *
43
44# DWARF register numbers
45name_to_dwarf_regnum = {
46    'r0'   : 0 ,
47    'r1'   : 1 ,
48    'r2'   : 2 ,
49    'r3'   : 3 ,
50    'r4'   : 4 ,
51    'r5'   : 5 ,
52    'r6'   : 6 ,
53    'r7'   : 7 ,
54    'r9'   : 8 ,
55    'r10'  : 9 ,
56    'r11'  : 10,
57    'r12'  : 11,
58    'sp'   : 12,
59    'lr'   : 13,
60    'pc'   : 14,
61    'r15'  : 15,
62    'xpsr' : 16,
63};
64
65name_to_generic_regnum = {
66    'pc' : LLDB_REGNUM_GENERIC_PC,
67    'sp' : LLDB_REGNUM_GENERIC_SP,
68    'r7' : LLDB_REGNUM_GENERIC_FP,
69    'lr' : LLDB_REGNUM_GENERIC_RA,
70    'r0' : LLDB_REGNUM_GENERIC_ARG1,
71    'r1' : LLDB_REGNUM_GENERIC_ARG2,
72    'r2' : LLDB_REGNUM_GENERIC_ARG3,
73    'r3' : LLDB_REGNUM_GENERIC_ARG4
74};
75
76
77def get_reg_num (reg_num_dict, reg_name):
78    if reg_name in reg_num_dict:
79        return reg_num_dict[reg_name]
80    return LLDB_INVALID_REGNUM
81
82def get_reg_num (reg_num_dict, reg_name):
83    if reg_name in reg_num_dict:
84        return reg_num_dict[reg_name]
85    return LLDB_INVALID_REGNUM
86
87armv7_register_infos = [
88{ 'name':'r0'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'arg1' },
89{ 'name':'r1'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'arg2' },
90{ 'name':'r2'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'arg3' },
91{ 'name':'r3'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'arg4' },
92{ 'name':'r4'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
93{ 'name':'r5'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
94{ 'name':'r6'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
95{ 'name':'r7'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'fp'  },
96{ 'name':'r8'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
97{ 'name':'r9'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
98{ 'name':'r10'  , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
99{ 'name':'r11'  , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
100{ 'name':'r12'  , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo   },
101{ 'name':'sp'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'r13'  },
102{ 'name':'lr'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'r14'  },
103{ 'name':'pc'   , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'r15'  },
104{ 'name':'xpsr' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint  , 'format':eFormatAddressInfo, 'alt-name':'cpsr' },
105];
106
107g_target_definition = None
108
109def get_target_definition ():
110    global g_target_definition
111    if g_target_definition == None:
112        g_target_definition = {}
113        offset = 0
114        for reg_info in armv7_register_infos:
115            reg_name = reg_info['name']
116
117            if 'slice' not in reg_info and 'composite' not in reg_info:
118                reg_info['offset'] = offset
119                offset += reg_info['bitsize'] / 8
120
121            # Set the DWARF/eh_frame register number for this register if it has one
122            reg_num = get_reg_num(name_to_dwarf_regnum, reg_name)
123            if reg_num != LLDB_INVALID_REGNUM:
124                reg_info['gcc'] = reg_num
125                reg_info['ehframe'] = reg_num
126
127            # Set the generic register number for this register if it has one
128            reg_num = get_reg_num(name_to_generic_regnum, reg_name)
129            if reg_num != LLDB_INVALID_REGNUM:
130                reg_info['generic'] = reg_num
131
132        g_target_definition['sets'] = ['General Purpose Registers']
133        g_target_definition['registers'] = armv7_register_infos
134        g_target_definition['host-info'] = { 'triple'   : 'armv7em--', 'endian': eByteOrderLittle }
135        g_target_definition['g-packet-size'] = offset
136    return g_target_definition
137
138def get_dynamic_setting(target, setting_name):
139    if setting_name == 'gdb-server-target-definition':
140        return get_target_definition()
141