Commit f51f9f1d authored by Tom de Vries's avatar Tom de Vries
Browse files

[gdb/ada] Handle shrink resize in replace_operator_with_call

In replace_operator_with_call, we resize the elts array like this:
...
  exp->nelts = exp->nelts + 7 - oplen;
  exp->resize (exp->nelts);
...

Although all the current callers ensure that the new size is bigger, it could
also be smaller, in which case the following memmove possibly reads out of
bounds:
...
   memmove (exp->elts + pc + 7, exp->elts + pc + oplen,
           EXP_ELEM_TO_BYTES (save_nelts - pc - oplen));
...

Fix this by doing the resize after the memmove in case the new size is
smaller.

Tested on x86_64-linux.

gdb/ChangeLog:

2020-12-07  Tom de Vries  <tdevries@suse.de>

	* ada-lang.c (replace_operator_with_call): Handle shrink resize.
parent 00158a68
2020-12-07 Tom de Vries <tdevries@suse.de>
* ada-lang.c (replace_operator_with_call): Handle shrink resize.
2020-12-06 Tom Tromey <tom@tromey.com>
PR ada/26999
......
......@@ -4005,11 +4005,15 @@ replace_operator_with_call (expression_up *expp, int pc, int nargs,
expression. */
struct expression *exp = expp->get ();
int save_nelts = exp->nelts;
exp->nelts = exp->nelts + 7 - oplen;
exp->resize (exp->nelts);
int extra_elts = 7 - oplen;
exp->nelts += extra_elts;
if (extra_elts > 0)
exp->resize (exp->nelts);
memmove (exp->elts + pc + 7, exp->elts + pc + oplen,
EXP_ELEM_TO_BYTES (save_nelts - pc - oplen));
if (extra_elts < 0)
exp->resize (exp->nelts);
exp->elts[pc].opcode = exp->elts[pc + 2].opcode = OP_FUNCALL;
exp->elts[pc + 1].longconst = (LONGEST) nargs;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment