Added unary "*" operator for dereferencing addresses to the

debugger expression language. By default it reads a uint32 value.
Another target size (1, 2, 4, or 8 bytes) can be specified in braces
after the "*" (e.g. "*{2}address" for uint16).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23551 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-01-16 03:55:19 +00:00
parent 267428a36a
commit 5c62817c6f
+63 -6
View File
@@ -28,7 +28,7 @@
term := sum
sum := product ( ( "+" | "-" ) product )*
product := unary ( ( "*" | "/" | "%" ) unary )*
unary := [ "-" ] atom
unary := atom | ( ( "-" | "*" [ "{" expression "}" ] ) unary )
atom := variable | ( "(" expression ")" ) | ( "[" command "]" )
variable := identifier
identifier := ( "_" | "a" - "z" | "A" - "Z" )
@@ -84,6 +84,8 @@ enum {
TOKEN_CLOSING_PARENTHESIS = ')',
TOKEN_OPENING_BRACKET = '[',
TOKEN_CLOSING_BRACKET = ']',
TOKEN_OPENING_BRACE = '{',
TOKEN_CLOSING_BRACE = '}',
TOKEN_STRING = '"',
TOKEN_UNKNOWN = '?',
@@ -227,6 +229,11 @@ public:
return (fCommandMode ? _NextTokenCommand() : _NextTokenExpression());
}
const Token& CurrentToken() const
{
return fCurrentToken;
}
void RewindToken()
{
fReuseToken = true;
@@ -298,6 +305,8 @@ public:
case ')':
case '[':
case ']':
case '{':
case '}':
{
int32 length = fCurrentChar - begin;
fCurrentToken.SetTo(begin, length, _CurrentPos() - length,
@@ -409,6 +418,8 @@ public:
case '"':
return true;
case '{':
case '}':
case '=':
case '+':
case '-':
@@ -775,14 +786,60 @@ ExpressionParser::_ParseProduct()
uint64
ExpressionParser::_ParseUnary()
{
const Token& token = fTokenizer.NextToken();
if (token.type == TOKEN_END_OF_LINE)
parse_exception("unexpected end of expression", token.position);
switch (token.type) {
switch (fTokenizer.NextToken().type) {
case TOKEN_MINUS:
return -_ParseUnary();
case TOKEN_STAR:
{
int32 starPosition = fTokenizer.CurrentToken().position;
// optional "{ ... }" specifying the size to read
uint64 size = 4;
if (fTokenizer.NextToken().type == TOKEN_OPENING_BRACE) {
int32 position = fTokenizer.CurrentToken().position;
size = _ParseExpression();
if (size != 1 && size != 2 && size != 4 && size != 8) {
snprintf(sTempBuffer, sizeof(sTempBuffer),
"invalid size (%llu) for unary * operator", size);
parse_exception(sTempBuffer, position);
}
_EatToken(TOKEN_CLOSING_BRACE);
} else
fTokenizer.RewindToken();
const void* address = (const void*)(addr_t)_ParseUnary();
// read bytes from address into a tempory buffer
uint64 buffer;
if (user_memcpy(&buffer, address, size) != B_OK) {
snprintf(sTempBuffer, sizeof(sTempBuffer),
"failed to dereference address %p", address);
parse_exception(sTempBuffer, starPosition);
}
// convert the value to uint64
uint64 value = 0;
switch (size) {
case 1:
value = *(uint8*)&buffer;
break;
case 2:
value = *(uint16*)&buffer;
break;
case 4:
value = *(uint32*)&buffer;
break;
case 8:
value = buffer;
break;
}
return value;
}
default:
fTokenizer.RewindToken();
return _ParseAtom();