aboutsummaryrefslogtreecommitdiff
path: root/gdb/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/parse.c')
-rw-r--r--gdb/parse.c74
1 files changed, 54 insertions, 20 deletions
diff --git a/gdb/parse.c b/gdb/parse.c
index 4090302..2ce1ea7 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -200,27 +200,62 @@ write_exp_elt_intern (expelt)
}
/* Add a string constant to the end of the expression.
- Follow it by its length in bytes, as a separate exp_element. */
+
+ String constants are stored by first writing an expression element
+ that contains the length of the string, then stuffing the string
+ constant itself into however many expression elements are needed
+ to hold it, and then writing another expression element that contains
+ the length of the string. I.E. an expression element at each end of
+ the string records the string length, so you can skip over the
+ expression elements containing the actual string bytes from either
+ end of the string. Note that this also allows gdb to handle
+ strings with embedded null bytes, as is required for some languages.
+
+ Don't be fooled by the fact that the string is null byte terminated,
+ this is strictly for the convenience of debugging gdb itself. Gdb
+ Gdb does not depend up the string being null terminated, since the
+ actual length is recorded in expression elements at each end of the
+ string. The null byte is taken into consideration when computing how
+ many expression elements are required to hold the string constant, of
+ course. */
+
void
write_exp_string (str)
struct stoken str;
{
register int len = str.length;
- register int lenelt
- = (len + sizeof (union exp_element)) / sizeof (union exp_element);
+ register int lenelt;
+ register char *strdata;
- expout_ptr += lenelt;
+ /* Compute the number of expression elements required to hold the string
+ (including a null byte terminator), along with one expression element
+ at each end to record the actual string length (not including the
+ null byte terminator). */
- if (expout_ptr >= expout_size)
+ lenelt = 2 + (len + sizeof (union exp_element)) / sizeof (union exp_element);
+
+ /* Ensure that we have enough available expression elements to store
+ everything. */
+
+ if ((expout_ptr + lenelt) >= expout_size)
{
- expout_size = max (expout_size * 2, expout_ptr + 10);
+ expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
expout = (struct expression *)
xrealloc ((char *) expout, (sizeof (struct expression)
+ (expout_size * sizeof (union exp_element))));
}
- memcpy ((char *) &expout->elts[expout_ptr - lenelt], str.ptr, len);
- ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0;
+
+ /* Write the leading length expression element (which advances the current
+ expression element index), then write the string constant followed by a
+ terminating null byte, and then write the trailing length expression
+ element. */
+
+ write_exp_elt_longcst ((LONGEST) len);
+ strdata = (char *) &expout->elts[expout_ptr];
+ memcpy (strdata, str.ptr, len);
+ *(strdata + len) = '\0';
+ expout_ptr += lenelt - 2;
write_exp_elt_longcst ((LONGEST) len);
}
@@ -268,7 +303,7 @@ length_of_subexp (expr, endpos)
register int args = 0;
register int i;
- if (endpos < 0)
+ if (endpos < 1)
error ("?error in length_of_subexp");
i = (int) expr->elts[endpos - 1].opcode;
@@ -277,7 +312,7 @@ length_of_subexp (expr, endpos)
{
/* C++ */
case OP_SCOPE:
- oplen = 4 + ((expr->elts[endpos - 2].longconst
+ oplen = 5 + ((longest_to_int (expr->elts[endpos - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
@@ -298,13 +333,12 @@ length_of_subexp (expr, endpos)
case OP_FUNCALL:
oplen = 3;
- args = 1 + expr->elts[endpos - 2].longconst;
+ args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
break;
case UNOP_MAX:
case UNOP_MIN:
oplen = 3;
- args = 0;
break;
case BINOP_VAL:
@@ -329,9 +363,10 @@ length_of_subexp (expr, endpos)
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
+ /* fall through */
case OP_M2_STRING:
case OP_STRING:
- oplen = 3 + ((expr->elts[endpos - 2].longconst
+ oplen = 4 + ((longest_to_int (expr->elts[endpos - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
@@ -343,7 +378,7 @@ length_of_subexp (expr, endpos)
/* Modula-2 */
case BINOP_MULTI_SUBSCRIPT:
oplen=3;
- args = 1 + expr->elts[endpos- 2].longconst;
+ args = 1 + longest_to_int (expr->elts[endpos- 2].longconst);
break;
case BINOP_ASSIGN_MODIFY:
@@ -395,7 +430,7 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
{
/* C++ */
case OP_SCOPE:
- oplen = 4 + ((inexpr->elts[inend - 2].longconst
+ oplen = 5 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
@@ -416,13 +451,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
case OP_FUNCALL:
oplen = 3;
- args = 1 + inexpr->elts[inend - 2].longconst;
+ args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
break;
case UNOP_MIN:
case UNOP_MAX:
oplen = 3;
- args = 0;
break;
case UNOP_CAST:
@@ -446,12 +480,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
+ /* fall through */
case OP_M2_STRING:
case OP_STRING:
- oplen = 3 + ((inexpr->elts[inend - 2].longconst
+ oplen = 4 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
-
break;
case TERNOP_COND:
@@ -466,7 +500,7 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
/* Modula-2 */
case BINOP_MULTI_SUBSCRIPT:
oplen=3;
- args = 1 + inexpr->elts[inend - 2].longconst;
+ args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
break;
/* C++ */