Skip to content

Commit 8186cfb

Browse files
xusheng6claude
andauthored
Fix GDB MI register value parsing for vector/SIMD registers and unavailable values (#1022)
ParseGdbValue now handles three additional cases from GDB's -data-list-register-values output: - <unavailable> markers (returned for inaccessible registers) - XMM composite structs (extracts uint128 field) - YMM composite structs (combines v2_int128 high/low fields) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 19e457d commit 8186cfb

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

core/adapters/gdbmiadapter.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,73 @@ GdbMiAdapter::~GdbMiAdapter() {
2121
intx::uint512 GdbMiAdapter::ParseGdbValue(const std::string& valueStr)
2222
{
2323
if (valueStr.empty()) return 0;
24+
25+
// Handle <unavailable> and other angle-bracket GDB markers
26+
if (valueStr.front() == '<')
27+
return 0;
28+
29+
// Handle composite struct values from vector/SIMD registers
30+
// e.g. XMM: "{... uint128 = 0x...}"
31+
// e.g. YMM: "{... v2_int128 = {0xHIGH, 0xLOW}}"
32+
if (valueStr.front() == '{')
33+
{
34+
// Try v2_int128 first (YMM 256-bit registers)
35+
auto v2pos = valueStr.find("v2_int128 = {");
36+
if (v2pos != std::string::npos)
37+
{
38+
auto braceStart = valueStr.find('{', v2pos);
39+
auto braceEnd = valueStr.find('}', braceStart);
40+
if (braceStart != std::string::npos && braceEnd != std::string::npos)
41+
{
42+
std::string inner = valueStr.substr(braceStart + 1, braceEnd - braceStart - 1);
43+
// Extract two hex values: "0xHIGH, 0xLOW"
44+
auto commaPos = inner.find(',');
45+
if (commaPos != std::string::npos)
46+
{
47+
// Trim whitespace around each value
48+
std::string highStr = inner.substr(0, commaPos);
49+
std::string lowStr = inner.substr(commaPos + 1);
50+
// Trim leading/trailing spaces
51+
auto trimWs = [](std::string& s) {
52+
while (!s.empty() && s.front() == ' ') s.erase(s.begin());
53+
while (!s.empty() && s.back() == ' ') s.pop_back();
54+
};
55+
trimWs(highStr);
56+
trimWs(lowStr);
57+
try {
58+
auto high = intx::from_string<intx::uint256>(highStr);
59+
auto low = intx::from_string<intx::uint256>(lowStr);
60+
intx::uint512 result = intx::uint512(high) << 128 | intx::uint512(low);
61+
return result;
62+
} catch (...) {}
63+
}
64+
}
65+
}
66+
67+
// Try uint128 (XMM 128-bit registers)
68+
auto u128pos = valueStr.find("uint128 = ");
69+
if (u128pos != std::string::npos)
70+
{
71+
auto hexStart = valueStr.find("0x", u128pos);
72+
if (hexStart != std::string::npos)
73+
{
74+
// Find the end of the hex string (next non-hex char)
75+
auto hexEnd = hexStart + 2;
76+
while (hexEnd < valueStr.size() &&
77+
std::isxdigit(static_cast<unsigned char>(valueStr[hexEnd])))
78+
hexEnd++;
79+
std::string hexStr = valueStr.substr(hexStart, hexEnd - hexStart);
80+
try {
81+
return intx::from_string<intx::uint512>(hexStr);
82+
} catch (...) {}
83+
}
84+
}
85+
86+
// Composite value we couldn't extract from - return 0 silently
87+
LogDebug("Skipping unparseable composite register value");
88+
return 0;
89+
}
90+
2491
try {
2592
return intx::from_string<intx::uint512>(valueStr);
2693
} catch(...) {

0 commit comments

Comments
 (0)