@@ -4179,21 +4179,134 @@ 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
+ // For example, hardware may intially release with two states that softwware
4187
+ // can read from a register field:
4188
+ // 0 = startup, 1 = running
4189
+ // If in a future hardware release, the designers added a pre-startup state:
4190
+ // 0 = startup, 1 = running, 2 = pre-startup
4191
+ // Now it makes more sense to list them in this logical order as opposed to
4192
+ // numerical order:
4193
+ // 2 = pre-startup, 1 = startup, 0 = startup
4194
+ // This only matters for "register info" but let's trust what the server
4195
+ // chose regardless.
4196
+ std::map<uint64_t , FieldEnum::Enumerator> enumerators;
4197
+
4198
+ enum_node.ForEachChildElementWithName (
4199
+ " evalue" , [&enumerators, &log](const XMLNode &enumerator_node) {
4200
+ std::optional<llvm::StringRef> name;
4201
+ std::optional<uint64_t > value;
4202
+
4203
+ enumerator_node.ForEachAttribute (
4204
+ [&name, &value, &log](const llvm::StringRef &attr_name,
4205
+ const llvm::StringRef &attr_value) {
4206
+ if (attr_name == " name" ) {
4207
+ if (attr_value.size ())
4208
+ name = attr_value;
4209
+ else
4210
+ LLDB_LOG (log, " ProcessGDBRemote::ParseEnumEvalues "
4211
+ " Ignoring empty name in evalue" );
4212
+ } else if (attr_name == " value" ) {
4213
+ uint64_t parsed_value = 0 ;
4214
+ if (llvm::to_integer (attr_value, parsed_value))
4215
+ value = parsed_value;
4216
+ else
4217
+ LLDB_LOG (log,
4218
+ " ProcessGDBRemote::ParseEnumEvalues "
4219
+ " Invalid value \" {0}\" in "
4220
+ " evalue" ,
4221
+ attr_value.data ());
4222
+ } else
4223
+ LLDB_LOG (log,
4224
+ " ProcessGDBRemote::ParseEnumEvalues Ignoring "
4225
+ " unknown attribute "
4226
+ " \" {0}\" in evalue" ,
4227
+ attr_name.data ());
4228
+
4229
+ // Keep walking attributes.
4230
+ return true ;
4231
+ });
4232
+
4233
+ if (value && name)
4234
+ enumerators.insert_or_assign (
4235
+ *value, FieldEnum::Enumerator (*value, name->str ()));
4236
+
4237
+ // Find all evalue elements.
4238
+ return true ;
4239
+ });
4240
+
4241
+ FieldEnum::Enumerators final_enumerators;
4242
+ for (auto [_, enumerator] : enumerators)
4243
+ final_enumerators.push_back (enumerator);
4244
+
4245
+ return final_enumerators;
4246
+ }
4247
+
4248
+ static void
4249
+ ParseEnums (XMLNode feature_node,
4250
+ llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4251
+ Log *log (GetLog (GDBRLog::Process));
4252
+
4253
+ // The top level element is "<enum...".
4254
+ feature_node.ForEachChildElementWithName (
4255
+ " enum" , [log, ®isters_enum_types](const XMLNode &enum_node) {
4256
+ std::string id;
4257
+
4258
+ enum_node.ForEachAttribute ([&id](const llvm::StringRef &attr_name,
4259
+ const llvm::StringRef &attr_value) {
4260
+ if (attr_name == " id" )
4261
+ id = attr_value;
4262
+
4263
+ // There is also a "size" attribute that is supposed to be the size in
4264
+ // bytes of the register this applies to. However:
4265
+ // * LLDB doesn't need this information.
4266
+ // * It is difficult to verify because you have to wait until the
4267
+ // enum is applied to a field.
4268
+ //
4269
+ // So we will emit this attribute in XML for GDB's sake, but will not
4270
+ // bother ingesting it.
4271
+
4272
+ // Walk all attributes.
4273
+ return true ;
4274
+ });
4275
+
4276
+ if (!id.empty ()) {
4277
+ FieldEnum::Enumerators enumerators = ParseEnumEvalues (enum_node);
4278
+ if (!enumerators.empty ()) {
4279
+ LLDB_LOG (log,
4280
+ " ProcessGDBRemote::ParseEnums Found enum type \" {0}\" " ,
4281
+ id);
4282
+ registers_enum_types.insert_or_assign (
4283
+ id, std::make_unique<FieldEnum>(id, enumerators));
4284
+ }
4285
+ }
4286
+
4287
+ // Find all <enum> elements.
4288
+ return true ;
4289
+ });
4290
+ }
4291
+
4292
+ static std::vector<RegisterFlags::Field> ParseFlagsFields (
4293
+ XMLNode flags_node, unsigned size,
4294
+ const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4184
4295
Log *log (GetLog (GDBRLog::Process));
4185
4296
const unsigned max_start_bit = size * 8 - 1 ;
4186
4297
4187
4298
// Process the fields of this set of flags.
4188
4299
std::vector<RegisterFlags::Field> fields;
4189
- flags_node.ForEachChildElementWithName (" field" , [&fields, max_start_bit,
4190
- &log](const XMLNode
4191
- &field_node) {
4300
+ flags_node.ForEachChildElementWithName (" field" , [&fields, max_start_bit, &log,
4301
+ ®isters_enum_types](
4302
+ const XMLNode
4303
+ &field_node) {
4192
4304
std::optional<llvm::StringRef> name;
4193
4305
std::optional<unsigned > start;
4194
4306
std::optional<unsigned > end;
4307
+ std::optional<llvm::StringRef> type;
4195
4308
4196
- field_node.ForEachAttribute ([&name, &start, &end, max_start_bit,
4309
+ field_node.ForEachAttribute ([&name, &start, &end, &type, max_start_bit,
4197
4310
&log](const llvm::StringRef &attr_name,
4198
4311
const llvm::StringRef &attr_value) {
4199
4312
// Note that XML in general requires that each of these attributes only
@@ -4240,8 +4353,7 @@ static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node,
4240
4353
attr_value.data ());
4241
4354
}
4242
4355
} else if (attr_name == " type" ) {
4243
- // Type is a known attribute but we do not currently use it and it is
4244
- // not required.
4356
+ type = attr_value;
4245
4357
} else {
4246
4358
LLDB_LOG (
4247
4359
log,
@@ -4254,14 +4366,55 @@ static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node,
4254
4366
});
4255
4367
4256
4368
if (name && start && end) {
4257
- if (*start > *end) {
4369
+ if (*start > *end)
4258
4370
LLDB_LOG (
4259
4371
log,
4260
4372
" ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
4261
4373
" \" {2}\" , ignoring" ,
4262
4374
*start, *end, name->data ());
4263
- } else {
4264
- fields.push_back (RegisterFlags::Field (name->str (), *start, *end));
4375
+ else {
4376
+ if (RegisterFlags::Field::GetSizeInBits (*start, *end) > 64 )
4377
+ LLDB_LOG (log,
4378
+ " ProcessGDBRemote::ParseFlagsFields Ignoring field \" {2}\" "
4379
+ " that has "
4380
+ " size > 64 bits, this is not supported" ,
4381
+ name->data ());
4382
+ else {
4383
+ // A field's type may be set to the name of an enum type.
4384
+ const FieldEnum *enum_type = nullptr ;
4385
+ if (type && !type->empty ()) {
4386
+ auto found = registers_enum_types.find (*type);
4387
+ if (found != registers_enum_types.end ()) {
4388
+ enum_type = found->second .get ();
4389
+
4390
+ // No enumerator can exceed the range of the field itself.
4391
+ uint64_t max_value =
4392
+ RegisterFlags::Field::GetMaxValue (*start, *end);
4393
+ for (const auto &enumerator : enum_type->GetEnumerators ()) {
4394
+ if (enumerator.m_value > max_value) {
4395
+ enum_type = nullptr ;
4396
+ LLDB_LOG (
4397
+ log,
4398
+ " ProcessGDBRemote::ParseFlagsFields In enum \" {0}\" "
4399
+ " evalue \" {1}\" with value {2} exceeds the maximum value "
4400
+ " of field \" {3}\" ({4}), ignoring enum" ,
4401
+ type->data (), enumerator.m_name , enumerator.m_value ,
4402
+ name->data (), max_value);
4403
+ break ;
4404
+ }
4405
+ }
4406
+ } else {
4407
+ LLDB_LOG (log,
4408
+ " ProcessGDBRemote::ParseFlagsFields Could not find type "
4409
+ " \" {0}\" "
4410
+ " for field \" {1}\" , ignoring" ,
4411
+ type->data (), name->data ());
4412
+ }
4413
+ }
4414
+
4415
+ fields.push_back (
4416
+ RegisterFlags::Field (name->str (), *start, *end, enum_type));
4417
+ }
4265
4418
}
4266
4419
}
4267
4420
@@ -4272,12 +4425,14 @@ static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node,
4272
4425
4273
4426
void ParseFlags (
4274
4427
XMLNode feature_node,
4275
- llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types) {
4428
+ llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4429
+ const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4276
4430
Log *log (GetLog (GDBRLog::Process));
4277
4431
4278
4432
feature_node.ForEachChildElementWithName (
4279
4433
" flags" ,
4280
- [&log, ®isters_flags_types](const XMLNode &flags_node) -> bool {
4434
+ [&log, ®isters_flags_types,
4435
+ ®isters_enum_types](const XMLNode &flags_node) -> bool {
4281
4436
LLDB_LOG (log, " ProcessGDBRemote::ParseFlags Found flags node \" {0}\" " ,
4282
4437
flags_node.GetAttributeValue (" id" ).c_str ());
4283
4438
@@ -4310,7 +4465,7 @@ void ParseFlags(
4310
4465
if (id && size) {
4311
4466
// Process the fields of this set of flags.
4312
4467
std::vector<RegisterFlags::Field> fields =
4313
- ParseFlagsFields (flags_node, *size);
4468
+ ParseFlagsFields (flags_node, *size, registers_enum_types );
4314
4469
if (fields.size ()) {
4315
4470
// Sort so that the fields with the MSBs are first.
4316
4471
std::sort (fields.rbegin (), fields.rend ());
@@ -4375,13 +4530,19 @@ void ParseFlags(
4375
4530
bool ParseRegisters (
4376
4531
XMLNode feature_node, GdbServerTargetInfo &target_info,
4377
4532
std::vector<DynamicRegisterInfo::Register> ®isters,
4378
- llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types) {
4533
+ llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4534
+ llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4379
4535
if (!feature_node)
4380
4536
return false ;
4381
4537
4382
4538
Log *log (GetLog (GDBRLog::Process));
4383
4539
4384
- ParseFlags (feature_node, registers_flags_types);
4540
+ // Enums first because they are referenced by fields in the flags.
4541
+ ParseEnums (feature_node, registers_enum_types);
4542
+ for (const auto &enum_type : registers_enum_types)
4543
+ enum_type.second ->DumpToLog (log);
4544
+
4545
+ ParseFlags (feature_node, registers_flags_types, registers_enum_types);
4385
4546
for (const auto &flags : registers_flags_types)
4386
4547
flags.second ->DumpToLog (log);
4387
4548
@@ -4643,7 +4804,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
4643
4804
if (arch_to_use.IsValid ()) {
4644
4805
for (auto &feature_node : feature_nodes) {
4645
4806
ParseRegisters (feature_node, target_info, registers,
4646
- m_registers_flags_types);
4807
+ m_registers_flags_types, m_registers_enum_types );
4647
4808
}
4648
4809
4649
4810
for (const auto &include : target_info.includes ) {
@@ -4708,13 +4869,14 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
4708
4869
if (!m_gdb_comm.GetQXferFeaturesReadSupported ())
4709
4870
return false ;
4710
4871
4711
- // This holds register flags information for the whole of target.xml.
4872
+ // These hold register type information for the whole of target.xml.
4712
4873
// target.xml may include further documents that
4713
4874
// GetGDBServerRegisterInfoXMLAndProcess will recurse to fetch and process.
4714
4875
// That's why we clear the cache here, and not in
4715
4876
// GetGDBServerRegisterInfoXMLAndProcess. To prevent it being cleared on every
4716
4877
// include read.
4717
4878
m_registers_flags_types.clear ();
4879
+ m_registers_enum_types.clear ();
4718
4880
std::vector<DynamicRegisterInfo::Register> registers;
4719
4881
if (GetGDBServerRegisterInfoXMLAndProcess (arch_to_use, " target.xml" ,
4720
4882
registers))
0 commit comments