[Lldb-commits] [lldb] 86cd236 - [lldb] [DynamicRegisterInfo] Refactor SetRegisterInfo()
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 28 07:48:07 PDT 2021
Author: Michał Górny
Date: 2021-09-28T16:47:58+02:00
New Revision: 86cd2369b6cd7eb17374fb31bccac7895fe34658
URL: https://github.com/llvm/llvm-project/commit/86cd2369b6cd7eb17374fb31bccac7895fe34658
DIFF: https://github.com/llvm/llvm-project/commit/86cd2369b6cd7eb17374fb31bccac7895fe34658.diff
LOG: [lldb] [DynamicRegisterInfo] Refactor SetRegisterInfo()
Move the "slice" and "composite" handling into separate methods to avoid
if/else hell. Use more LLVM types whenever possible. Replace printf()s
with llvm::Error combined with LLDB logging.
Differential Revision: https://reviews.llvm.org/D110619
Added:
Modified:
lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 6535df20de11d..a5f4b8c7d7f3e 100644
--- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -12,6 +12,7 @@
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StructuredData.h"
@@ -56,9 +57,144 @@ void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) {
info.Clear();
}
+llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromSlice(
+ uint32_t index, llvm::StringRef slice_str, lldb::ByteOrder byte_order) {
+ // Slices use the following format:
+ // REGNAME[MSBIT:LSBIT]
+ // REGNAME - name of the register to grab a slice of
+ // MSBIT - the most significant bit at which the current register value
+ // starts at
+ // LSBIT - the least significant bit at which the current register value
+ // ends at
+ static llvm::Regex g_bitfield_regex(
+ "([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (!g_bitfield_regex.match(slice_str, &matches))
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to match against register bitfield regex (slice: %s)",
+ slice_str.str().c_str());
+
+ llvm::StringRef reg_name_str = matches[1];
+ llvm::StringRef msbit_str = matches[2];
+ llvm::StringRef lsbit_str = matches[3];
+ uint32_t msbit;
+ uint32_t lsbit;
+ if (!llvm::to_integer(msbit_str, msbit) ||
+ !llvm::to_integer(lsbit_str, lsbit))
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(), "msbit (%s) or lsbit (%s) are invalid",
+ msbit_str.str().c_str(), lsbit_str.str().c_str());
+
+ if (msbit <= lsbit)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "msbit (%u) must be greater than lsbit (%u)",
+ msbit, lsbit);
+
+ const uint32_t msbyte = msbit / 8;
+ const uint32_t lsbyte = lsbit / 8;
+
+ const RegisterInfo *containing_reg_info = GetRegisterInfo(reg_name_str);
+ if (!containing_reg_info)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid concrete register \"%s\"",
+ reg_name_str.str().c_str());
+
+ const uint32_t max_bit = containing_reg_info->byte_size * 8;
+
+ if (msbit > max_bit)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "msbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
+ msbit, reg_name_str.str().c_str(), max_bit);
+ if (lsbit > max_bit)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "lsbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
+ lsbit, reg_name_str.str().c_str(), max_bit);
+
+ m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]]
+ .push_back(index);
+ m_value_regs_map[index].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[index].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+
+ if (byte_order == eByteOrderLittle)
+ return containing_reg_info->byte_offset + lsbyte;
+ if (byte_order == eByteOrderBig)
+ return containing_reg_info->byte_offset + msbyte;
+ llvm_unreachable("Invalid byte order");
+}
+
+llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromComposite(
+ uint32_t index, StructuredData::Array &composite_reg_list,
+ lldb::ByteOrder byte_order) {
+ const size_t num_composite_regs = composite_reg_list.GetSize();
+ if (num_composite_regs == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "\"composite\" list is empty");
+
+ uint32_t composite_offset = UINT32_MAX;
+ for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
+ ++composite_idx) {
+ ConstString composite_reg_name;
+ if (!composite_reg_list.GetItemAtIndexAsString(composite_idx,
+ composite_reg_name, nullptr))
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "\"composite\" list value is not a Python string at index %d",
+ composite_idx);
+
+ const RegisterInfo *composite_reg_info =
+ GetRegisterInfo(composite_reg_name.GetStringRef());
+ if (!composite_reg_info)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to find composite register by name: \"%s\"",
+ composite_reg_name.GetCString());
+
+ composite_offset =
+ std::min(composite_offset, composite_reg_info->byte_offset);
+ m_value_regs_map[index].push_back(
+ composite_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]]
+ .push_back(index);
+ m_invalidate_regs_map[index].push_back(
+ composite_reg_info->kinds[eRegisterKindLLDB]);
+ }
+
+ return composite_offset;
+}
+
+llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromRegInfoDict(
+ uint32_t index, StructuredData::Dictionary ®_info_dict,
+ lldb::ByteOrder byte_order) {
+ uint32_t byte_offset;
+ if (reg_info_dict.GetValueForKeyAsInteger("offset", byte_offset))
+ return byte_offset;
+
+ // No offset for this register, see if the register has a value
+ // expression which indicates this register is part of another register.
+ // Value expressions are things like "rax[31:0]" which state that the
+ // current register's value is in a concrete register "rax" in bits 31:0.
+ // If there is a value expression we can calculate the offset
+ llvm::StringRef slice_str;
+ if (reg_info_dict.GetValueForKeyAsString("slice", slice_str, nullptr))
+ return ByteOffsetFromSlice(index, slice_str, byte_order);
+
+ StructuredData::Array *composite_reg_list;
+ if (reg_info_dict.GetValueForKeyAsArray("composite", composite_reg_list))
+ return ByteOffsetFromComposite(index, *composite_reg_list, byte_order);
+
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "insufficient data to calculate byte offset");
+}
+
size_t
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
const ArchSpec &arch) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT);
assert(!m_finalized);
StructuredData::Array *sets = nullptr;
if (dict.GetValueForKeyAsArray("sets", sets)) {
@@ -80,6 +216,8 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
if (!dict.GetValueForKeyAsArray("registers", regs))
return 0;
+ const ByteOrder byte_order = arch.GetByteOrder();
+
const uint32_t num_regs = regs->GetSize();
// typedef std::map<std::string, std::vector<std::string> >
// InvalidateNameMap;
@@ -113,147 +251,16 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
reg_info.alt_name = alt_name_val.GetCString();
- reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset,
- UINT32_MAX);
-
- const ByteOrder byte_order = arch.GetByteOrder();
-
- if (reg_info.byte_offset == UINT32_MAX) {
- // No offset for this register, see if the register has a value
- // expression which indicates this register is part of another register.
- // Value expressions are things like "rax[31:0]" which state that the
- // current register's value is in a concrete register "rax" in bits 31:0.
- // If there is a value expression we can calculate the offset
- bool success = false;
- llvm::StringRef slice_str;
- if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) {
- // Slices use the following format:
- // REGNAME[MSBIT:LSBIT]
- // REGNAME - name of the register to grab a slice of
- // MSBIT - the most significant bit at which the current register value
- // starts at
- // LSBIT - the least significant bit at which the current register value
- // ends at
- static RegularExpression g_bitfield_regex(
- llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
- llvm::SmallVector<llvm::StringRef, 4> matches;
- if (g_bitfield_regex.Execute(slice_str, &matches)) {
- std::string reg_name_str = matches[1].str();
- std::string msbit_str = matches[2].str();
- std::string lsbit_str = matches[3].str();
- uint32_t msbit = 0;
- uint32_t lsbit = 0;
- if (llvm::to_integer(msbit_str, msbit) &&
- llvm::to_integer(lsbit_str, lsbit)) {
- if (msbit > lsbit) {
- const uint32_t msbyte = msbit / 8;
- const uint32_t lsbyte = lsbit / 8;
-
- const RegisterInfo *containing_reg_info =
- GetRegisterInfo(reg_name_str);
- if (containing_reg_info) {
- const uint32_t max_bit = containing_reg_info->byte_size * 8;
- if (msbit < max_bit && lsbit < max_bit) {
- m_invalidate_regs_map[containing_reg_info
- ->kinds[eRegisterKindLLDB]]
- .push_back(i);
- m_value_regs_map[i].push_back(
- containing_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[i].push_back(
- containing_reg_info->kinds[eRegisterKindLLDB]);
-
- if (byte_order == eByteOrderLittle) {
- success = true;
- reg_info.byte_offset =
- containing_reg_info->byte_offset + lsbyte;
- } else if (byte_order == eByteOrderBig) {
- success = true;
- reg_info.byte_offset =
- containing_reg_info->byte_offset + msbyte;
- } else {
- llvm_unreachable("Invalid byte order");
- }
- } else {
- if (msbit > max_bit)
- printf("error: msbit (%u) must be less than the bitsize "
- "of the register (%u)\n",
- msbit, max_bit);
- else
- printf("error: lsbit (%u) must be less than the bitsize "
- "of the register (%u)\n",
- lsbit, max_bit);
- }
- } else {
- printf("error: invalid concrete register \"%s\"\n",
- reg_name_str.c_str());
- }
- } else {
- printf("error: msbit (%u) must be greater than lsbit (%u)\n",
- msbit, lsbit);
- }
- } else {
- printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
- lsbit);
- }
- } else {
- // TODO: print error invalid slice string that doesn't follow the
- // format
- printf("error: failed to match against register bitfield regex\n");
- }
- } else {
- StructuredData::Array *composite_reg_list = nullptr;
- if (reg_info_dict->GetValueForKeyAsArray("composite",
- composite_reg_list)) {
- const size_t num_composite_regs = composite_reg_list->GetSize();
- if (num_composite_regs > 0) {
- uint32_t composite_offset = UINT32_MAX;
- for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
- ++composite_idx) {
- ConstString composite_reg_name;
- if (composite_reg_list->GetItemAtIndexAsString(
- composite_idx, composite_reg_name, nullptr)) {
- const RegisterInfo *composite_reg_info =
- GetRegisterInfo(composite_reg_name.GetStringRef());
- if (composite_reg_info) {
- composite_offset = std::min(composite_offset,
- composite_reg_info->byte_offset);
- m_value_regs_map[i].push_back(
- composite_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[composite_reg_info
- ->kinds[eRegisterKindLLDB]]
- .push_back(i);
- m_invalidate_regs_map[i].push_back(
- composite_reg_info->kinds[eRegisterKindLLDB]);
- } else {
- // TODO: print error invalid slice string that doesn't follow
- // the format
- printf("error: failed to find composite register by name: "
- "\"%s\"\n",
- composite_reg_name.GetCString());
- }
- } else {
- printf(
- "error: 'composite' list value wasn't a python string\n");
- }
- }
- if (composite_offset != UINT32_MAX) {
- reg_info.byte_offset = composite_offset;
- success = m_value_regs_map.find(i) != m_value_regs_map.end();
- } else {
- printf("error: 'composite' registers must specify at least one "
- "real register\n");
- }
- } else {
- printf("error: 'composite' list was empty\n");
- }
- }
- }
-
- if (!success) {
- Clear();
- reg_info_dict->DumpToStdout();
- return 0;
- }
+ llvm::Expected<uint32_t> byte_offset =
+ ByteOffsetFromRegInfoDict(i, *reg_info_dict, byte_order);
+ if (byte_offset)
+ reg_info.byte_offset = byte_offset.get();
+ else {
+ LLDB_LOG_ERROR(log, byte_offset.takeError(),
+ "error while parsing register {1}: {0}", reg_info.name);
+ Clear();
+ reg_info_dict->DumpToStdout();
+ return 0;
}
int64_t bitsize = 0;
diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index 44030c8132d8d..286c8bc1020d7 100644
--- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -86,6 +86,16 @@ class DynamicRegisterInfo {
typedef std::vector<uint8_t> dwarf_opcode;
typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
+ llvm::Expected<uint32_t> ByteOffsetFromSlice(uint32_t index,
+ llvm::StringRef slice_str,
+ lldb::ByteOrder byte_order);
+ llvm::Expected<uint32_t> ByteOffsetFromComposite(
+ uint32_t index, lldb_private::StructuredData::Array &composite_reg_list,
+ lldb::ByteOrder byte_order);
+ llvm::Expected<uint32_t> ByteOffsetFromRegInfoDict(
+ uint32_t index, lldb_private::StructuredData::Dictionary ®_info_dict,
+ lldb::ByteOrder byte_order);
+
void MoveFrom(DynamicRegisterInfo &&info);
void ConfigureOffsets();
@@ -102,4 +112,5 @@ class DynamicRegisterInfo {
bool m_finalized = false;
bool m_is_reconfigurable = false;
};
+
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H
More information about the lldb-commits
mailing list