6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
- #include " ABIX86.h"
10
9
#include " ABIMacOSX_i386.h"
11
10
#include " ABISysV_i386.h"
12
11
#include " ABISysV_x86_64.h"
13
12
#include " ABIWindows_x86_64.h"
13
+ #include " ABIX86.h"
14
14
#include " lldb/Core/PluginManager.h"
15
+ #include " lldb/Target/Process.h"
16
+
17
+ using namespace lldb ;
18
+ using namespace lldb_private ;
15
19
16
20
LLDB_PLUGIN_DEFINE (ABIX86)
17
21
@@ -28,3 +32,142 @@ void ABIX86::Terminate() {
28
32
ABISysV_x86_64::Terminate ();
29
33
ABIWindows_x86_64::Terminate ();
30
34
}
35
+
36
+ enum class RegKind {
37
+ GPR32 = 0 ,
38
+ GPR16,
39
+ GPR8h,
40
+ GPR8,
41
+
42
+ MM = 0 ,
43
+ };
44
+
45
+ typedef llvm::SmallDenseMap<llvm::StringRef,
46
+ llvm::SmallVector<llvm::StringRef, 4 >, 16 >
47
+ RegisterMap;
48
+
49
+ static void addPartialRegisters (
50
+ std::vector<DynamicRegisterInfo::Register> ®s,
51
+ llvm::ArrayRef<uint32_t > base_reg_indices, const RegisterMap ®_names,
52
+ uint32_t base_size, RegKind name_index, lldb::Encoding encoding,
53
+ lldb::Format format, uint32_t subreg_size, uint32_t subreg_offset = 0 ) {
54
+ for (uint32_t base_index : base_reg_indices) {
55
+ if (base_index == LLDB_INVALID_REGNUM)
56
+ break ;
57
+ assert (base_index < regs.size ());
58
+ DynamicRegisterInfo::Register &full_reg = regs[base_index];
59
+ llvm::StringRef subreg_name = reg_names.lookup (
60
+ full_reg.name .GetStringRef ())[static_cast <int >(name_index)];
61
+ if (subreg_name.empty () || full_reg.byte_size != base_size)
62
+ continue ;
63
+
64
+ lldb_private::DynamicRegisterInfo::Register subreg{
65
+ lldb_private::ConstString (subreg_name),
66
+ lldb_private::ConstString (),
67
+ lldb_private::ConstString (" supplementary registers" ),
68
+ subreg_size,
69
+ LLDB_INVALID_INDEX32,
70
+ encoding,
71
+ format,
72
+ LLDB_INVALID_REGNUM,
73
+ LLDB_INVALID_REGNUM,
74
+ LLDB_INVALID_REGNUM,
75
+ LLDB_INVALID_REGNUM,
76
+ {base_index},
77
+ {},
78
+ subreg_offset};
79
+
80
+ addSupplementaryRegister (regs, subreg);
81
+ }
82
+ }
83
+
84
+ void ABIX86::AugmentRegisterInfo (
85
+ std::vector<DynamicRegisterInfo::Register> ®s) {
86
+ MCBasedABI::AugmentRegisterInfo (regs);
87
+
88
+ ProcessSP process_sp = GetProcessSP ();
89
+ if (!process_sp)
90
+ return ;
91
+
92
+ uint32_t gpr_base_size =
93
+ process_sp->GetTarget ().GetArchitecture ().GetAddressByteSize ();
94
+ bool is64bit = gpr_base_size == 8 ;
95
+
96
+ typedef RegisterMap::value_type RegPair;
97
+ #define GPR_BASE (basename ) (is64bit ? " r" basename : " e" basename)
98
+ RegisterMap gpr_regs{{
99
+ RegPair (GPR_BASE (" ax" ), {" eax" , " ax" , " ah" , " al" }),
100
+ RegPair (GPR_BASE (" bx" ), {" ebx" , " bx" , " bh" , " bl" }),
101
+ RegPair (GPR_BASE (" cx" ), {" ecx" , " cx" , " ch" , " cl" }),
102
+ RegPair (GPR_BASE (" dx" ), {" edx" , " dx" , " dh" , " dl" }),
103
+ RegPair (GPR_BASE (" si" ), {" esi" , " si" , " " , " sil" }),
104
+ RegPair (GPR_BASE (" di" ), {" edi" , " di" , " " , " dil" }),
105
+ RegPair (GPR_BASE (" bp" ), {" ebp" , " bp" , " " , " bpl" }),
106
+ RegPair (GPR_BASE (" sp" ), {" esp" , " sp" , " " , " spl" }),
107
+ }};
108
+ #undef GPR_BASE
109
+ if (is64bit) {
110
+ #define R (base ) RegPair(base, {base " d" , base " w" , " " , base " l" })
111
+ RegisterMap amd64_regs{{
112
+ R (" r8" ),
113
+ R (" r9" ),
114
+ R (" r10" ),
115
+ R (" r11" ),
116
+ R (" r12" ),
117
+ R (" r13" ),
118
+ R (" r14" ),
119
+ R (" r15" ),
120
+ }};
121
+ #undef R
122
+ gpr_regs.insert (amd64_regs.begin (), amd64_regs.end ());
123
+ }
124
+
125
+ RegisterMap st_regs{{
126
+ RegPair (" st0" , {" mm0" }),
127
+ RegPair (" st1" , {" mm1" }),
128
+ RegPair (" st2" , {" mm2" }),
129
+ RegPair (" st3" , {" mm3" }),
130
+ RegPair (" st4" , {" mm4" }),
131
+ RegPair (" st5" , {" mm5" }),
132
+ RegPair (" st6" , {" mm6" }),
133
+ RegPair (" st7" , {" mm7" }),
134
+ }};
135
+
136
+ // regs from gpr_basenames, in list order
137
+ std::vector<uint32_t > gpr_base_reg_indices;
138
+ // st0..st7, in list order
139
+ std::vector<uint32_t > st_reg_indices;
140
+ // map used for fast register lookups
141
+ llvm::SmallDenseSet<llvm::StringRef, 64 > subreg_name_set;
142
+
143
+ // put all subreg names into the lookup set
144
+ for (const RegisterMap ®set : {gpr_regs, st_regs}) {
145
+ for (const RegPair &kv : regset)
146
+ subreg_name_set.insert (kv.second .begin (), kv.second .end ());
147
+ }
148
+
149
+ for (const auto &x : llvm::enumerate (regs)) {
150
+ llvm::StringRef reg_name = x.value ().name .GetStringRef ();
151
+ // find expected base registers
152
+ if (gpr_regs.find (reg_name) != gpr_regs.end ())
153
+ gpr_base_reg_indices.push_back (x.index ());
154
+ else if (st_regs.find (reg_name) != st_regs.end ())
155
+ st_reg_indices.push_back (x.index ());
156
+ // abort if at least one sub-register is already present
157
+ else if (llvm::is_contained (subreg_name_set, reg_name))
158
+ return ;
159
+ }
160
+
161
+ if (is64bit)
162
+ addPartialRegisters (regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
163
+ RegKind::GPR32, eEncodingUint, eFormatHex, 4 );
164
+ addPartialRegisters (regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
165
+ RegKind::GPR16, eEncodingUint, eFormatHex, 2 );
166
+ addPartialRegisters (regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
167
+ RegKind::GPR8h, eEncodingUint, eFormatHex, 1 , 1 );
168
+ addPartialRegisters (regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
169
+ RegKind::GPR8, eEncodingUint, eFormatHex, 1 );
170
+
171
+ addPartialRegisters (regs, st_reg_indices, st_regs, 10 , RegKind::MM,
172
+ eEncodingUint, eFormatHex, 8 );
173
+ }
0 commit comments