@@ -4179,21 +4179,124 @@ struct GdbServerTargetInfo {
4179
4179
RegisterSetMap reg_set_map;
4180
4180
};
4181
4181
4182
- static std::vector<RegisterFlags::Field> ParseFlagsFields (XMLNode flags_node,
4183
- unsigned size) {
4182
+ static FieldEnum::Enumerators ParseEnumEvalues (const XMLNode &enum_node) {
4183
+ Log *log (GetLog (GDBRLog::Process));
4184
+ // We will use the last instance of each value. Also we preserve the order
4185
+ // of declaration in the XML, as it may not be numerical.
4186
+ std::map<uint64_t , FieldEnum::Enumerator> enumerators;
4187
+
4188
+ enum_node.ForEachChildElementWithName (
4189
+ " evalue" , [&enumerators, &log](const XMLNode &enumerator_node) {
4190
+ std::optional<llvm::StringRef> name;
4191
+ std::optional<uint64_t > value;
4192
+
4193
+ enumerator_node.ForEachAttribute (
4194
+ [&name, &value, &log](const llvm::StringRef &attr_name,
4195
+ const llvm::StringRef &attr_value) {
4196
+ if (attr_name == " name" ) {
4197
+ if (attr_value.size ())
4198
+ name = attr_value;
4199
+ else
4200
+ LLDB_LOG (log, " ProcessGDBRemote::ParseEnumEvalues "
4201
+ " Ignoring empty name in evalue" );
4202
+ } else if (attr_name == " value" ) {
4203
+ uint64_t parsed_value = 0 ;
4204
+ if (llvm::to_integer (attr_value, parsed_value))
4205
+ value = parsed_value;
4206
+ else
4207
+ LLDB_LOG (log,
4208
+ " ProcessGDBRemote::ParseEnumEvalues "
4209
+ " Invalid value \" {0}\" in "
4210
+ " evalue" ,
4211
+ attr_value.data ());
4212
+ } else
4213
+ LLDB_LOG (log,
4214
+ " ProcessGDBRemote::ParseEnumEvalues Ignoring "
4215
+ " unknown attribute "
4216
+ " \" {0}\" in evalue" ,
4217
+ attr_name.data ());
4218
+
4219
+ // Keep walking attributes.
4220
+ return true ;
4221
+ });
4222
+
4223
+ if (value && name)
4224
+ enumerators.insert_or_assign (
4225
+ *value, FieldEnum::Enumerator (*value, name->str ()));
4226
+
4227
+ // Find all evalue elements.
4228
+ return true ;
4229
+ });
4230
+
4231
+ FieldEnum::Enumerators final_enumerators;
4232
+ for (auto [_, enumerator] : enumerators)
4233
+ final_enumerators.push_back (enumerator);
4234
+
4235
+ return final_enumerators;
4236
+ }
4237
+
4238
+ static void
4239
+ ParseEnums (XMLNode feature_node,
4240
+ llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4241
+ Log *log (GetLog (GDBRLog::Process));
4242
+
4243
+ // The top level element is "<enum...".
4244
+ feature_node.ForEachChildElementWithName (
4245
+ " enum" , [log, ®isters_enum_types](const XMLNode &enum_node) {
4246
+ std::string id;
4247
+
4248
+ enum_node.ForEachAttribute ([&id](const llvm::StringRef &attr_name,
4249
+ const llvm::StringRef &attr_value) {
4250
+ if (attr_name == " id" )
4251
+ id = attr_value;
4252
+
4253
+ // There is also a "size" attribute that is supposed to be the size in
4254
+ // bytes of the register this applies to. However:
4255
+ // * LLDB doesn't need this information.
4256
+ // * It is difficult to verify because you have to wait until the
4257
+ // enum is applied to a field.
4258
+ //
4259
+ // So we will emit this attribute in XML for GDB's sake, but will not
4260
+ // bother ingesting it.
4261
+
4262
+ // Walk all attributes.
4263
+ return true ;
4264
+ });
4265
+
4266
+ if (!id.empty ()) {
4267
+ FieldEnum::Enumerators enumerators = ParseEnumEvalues (enum_node);
4268
+ if (!enumerators.empty ()) {
4269
+ LLDB_LOG (log,
4270
+ " ProcessGDBRemote::ParseEnums Found enum type \" {0}\" " ,
4271
+ id);
4272
+ registers_enum_types.insert_or_assign (
4273
+ id, std::make_unique<FieldEnum>(id, enumerators));
4274
+ }
4275
+ }
4276
+
4277
+ // Find all <enum> elements.
4278
+ return true ;
4279
+ });
4280
+ }
4281
+
4282
+ static std::vector<RegisterFlags::Field> ParseFlagsFields (
4283
+ XMLNode flags_node, unsigned size,
4284
+ const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4184
4285
Log *log (GetLog (GDBRLog::Process));
4185
4286
const unsigned max_start_bit = size * 8 - 1 ;
4186
4287
4187
4288
// Process the fields of this set of flags.
4188
4289
std::vector<RegisterFlags::Field> fields;
4189
- flags_node.ForEachChildElementWithName (" field" , [&fields, max_start_bit,
4190
- &log](const XMLNode
4191
- &field_node) {
4290
+ flags_node.ForEachChildElementWithName (" field" , [&fields, max_start_bit, &log,
4291
+ ®isters_enum_types](
4292
+ const XMLNode
4293
+ &field_node) {
4192
4294
std::optional<llvm::StringRef> name;
4193
4295
std::optional<unsigned > start;
4194
4296
std::optional<unsigned > end;
4297
+ std::optional<llvm::StringRef> type;
4195
4298
4196
- field_node.ForEachAttribute ([&name, &start, &end, max_start_bit,
4299
+ field_node.ForEachAttribute ([&name, &start, &end, &type, max_start_bit,
4197
4300
&log](const llvm::StringRef &attr_name,
4198
4301
const llvm::StringRef &attr_value) {
4199
4302
// Note that XML in general requires that each of these attributes only
@@ -4240,8 +4343,7 @@ static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node,
4240
4343
attr_value.data ());
4241
4344
}
4242
4345
} else if (attr_name == " type" ) {
4243
- // Type is a known attribute but we do not currently use it and it is
4244
- // not required.
4346
+ type = attr_value;
4245
4347
} else {
4246
4348
LLDB_LOG (
4247
4349
log,
@@ -4254,14 +4356,55 @@ static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node,
4254
4356
});
4255
4357
4256
4358
if (name && start && end) {
4257
- if (*start > *end) {
4359
+ if (*start > *end)
4258
4360
LLDB_LOG (
4259
4361
log,
4260
4362
" ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
4261
4363
" \" {2}\" , ignoring" ,
4262
4364
*start, *end, name->data ());
4263
- } else {
4264
- fields.push_back (RegisterFlags::Field (name->str (), *start, *end));
4365
+ else {
4366
+ if (RegisterFlags::Field::GetSizeInBits (*start, *end) > 64 )
4367
+ LLDB_LOG (log,
4368
+ " ProcessGDBRemote::ParseFlagsFields Ignoring field \" {2}\" "
4369
+ " that has "
4370
+ " size > 64 bits, this is not supported" ,
4371
+ name->data ());
4372
+ else {
4373
+ // A field's type may be set to the name of an enum type.
4374
+ const FieldEnum *enum_type = nullptr ;
4375
+ if (type && !type->empty ()) {
4376
+ auto found = registers_enum_types.find (*type);
4377
+ if (found != registers_enum_types.end ()) {
4378
+ enum_type = found->second .get ();
4379
+
4380
+ // No enumerator can exceed the range of the field itself.
4381
+ uint64_t max_value =
4382
+ RegisterFlags::Field::GetMaxValue (*start, *end);
4383
+ for (const auto &enumerator : enum_type->GetEnumerators ()) {
4384
+ if (enumerator.m_value > max_value) {
4385
+ enum_type = nullptr ;
4386
+ LLDB_LOG (
4387
+ log,
4388
+ " ProcessGDBRemote::ParseFlagsFields In enum \" {0}\" "
4389
+ " evalue \" {1}\" with value {2} exceeds the maximum value "
4390
+ " of field \" {3}\" ({4}), ignoring enum" ,
4391
+ type->data (), enumerator.m_name , enumerator.m_value ,
4392
+ name->data (), max_value);
4393
+ break ;
4394
+ }
4395
+ }
4396
+ } else {
4397
+ LLDB_LOG (log,
4398
+ " ProcessGDBRemote::ParseFlagsFields Could not find type "
4399
+ " \" {0}\" "
4400
+ " for field \" {1}\" , ignoring" ,
4401
+ type->data (), name->data ());
4402
+ }
4403
+ }
4404
+
4405
+ fields.push_back (
4406
+ RegisterFlags::Field (name->str (), *start, *end, enum_type));
4407
+ }
4265
4408
}
4266
4409
}
4267
4410
@@ -4272,12 +4415,14 @@ static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node,
4272
4415
4273
4416
void ParseFlags (
4274
4417
XMLNode feature_node,
4275
- llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types) {
4418
+ llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4419
+ const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4276
4420
Log *log (GetLog (GDBRLog::Process));
4277
4421
4278
4422
feature_node.ForEachChildElementWithName (
4279
4423
" flags" ,
4280
- [&log, ®isters_flags_types](const XMLNode &flags_node) -> bool {
4424
+ [&log, ®isters_flags_types,
4425
+ ®isters_enum_types](const XMLNode &flags_node) -> bool {
4281
4426
LLDB_LOG (log, " ProcessGDBRemote::ParseFlags Found flags node \" {0}\" " ,
4282
4427
flags_node.GetAttributeValue (" id" ).c_str ());
4283
4428
@@ -4310,7 +4455,7 @@ void ParseFlags(
4310
4455
if (id && size) {
4311
4456
// Process the fields of this set of flags.
4312
4457
std::vector<RegisterFlags::Field> fields =
4313
- ParseFlagsFields (flags_node, *size);
4458
+ ParseFlagsFields (flags_node, *size, registers_enum_types );
4314
4459
if (fields.size ()) {
4315
4460
// Sort so that the fields with the MSBs are first.
4316
4461
std::sort (fields.rbegin (), fields.rend ());
@@ -4375,13 +4520,19 @@ void ParseFlags(
4375
4520
bool ParseRegisters (
4376
4521
XMLNode feature_node, GdbServerTargetInfo &target_info,
4377
4522
std::vector<DynamicRegisterInfo::Register> ®isters,
4378
- llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types) {
4523
+ llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4524
+ llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4379
4525
if (!feature_node)
4380
4526
return false ;
4381
4527
4382
4528
Log *log (GetLog (GDBRLog::Process));
4383
4529
4384
- ParseFlags (feature_node, registers_flags_types);
4530
+ // Enums first because they are referenced by fields in the flags.
4531
+ ParseEnums (feature_node, registers_enum_types);
4532
+ for (const auto &enum_type : registers_enum_types)
4533
+ enum_type.second ->log (log);
4534
+
4535
+ ParseFlags (feature_node, registers_flags_types, registers_enum_types);
4385
4536
for (const auto &flags : registers_flags_types)
4386
4537
flags.second ->log (log);
4387
4538
@@ -4643,7 +4794,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
4643
4794
if (arch_to_use.IsValid ()) {
4644
4795
for (auto &feature_node : feature_nodes) {
4645
4796
ParseRegisters (feature_node, target_info, registers,
4646
- m_registers_flags_types);
4797
+ m_registers_flags_types, m_registers_enum_types );
4647
4798
}
4648
4799
4649
4800
for (const auto &include : target_info.includes ) {
@@ -4708,13 +4859,14 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
4708
4859
if (!m_gdb_comm.GetQXferFeaturesReadSupported ())
4709
4860
return false ;
4710
4861
4711
- // This holds register flags information for the whole of target.xml.
4862
+ // These hold register type information for the whole of target.xml.
4712
4863
// target.xml may include further documents that
4713
4864
// GetGDBServerRegisterInfoXMLAndProcess will recurse to fetch and process.
4714
4865
// That's why we clear the cache here, and not in
4715
4866
// GetGDBServerRegisterInfoXMLAndProcess. To prevent it being cleared on every
4716
4867
// include read.
4717
4868
m_registers_flags_types.clear ();
4869
+ m_registers_enum_types.clear ();
4718
4870
std::vector<DynamicRegisterInfo::Register> registers;
4719
4871
if (GetGDBServerRegisterInfoXMLAndProcess (arch_to_use, " target.xml" ,
4720
4872
registers))
0 commit comments