mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-23 09:16:57 +00:00
dwarf-reader: Support DW_OP_GNU_variable_value
This solves a crash that happened with self-comparing the package 'aws' in Fedora by doing: $ fedabipkgdiff --self-compare -a --from fc37 aws When evaluating a DWARF expression with eval_last_constant_dwarf_sub_expr, indirectly called from die_member_offset, the DW_OP_GNU_variable_value appears not being supported. This patch adds the support for that. To help with figuring that kind of issue in the future, I have added a few asserts in the code of op_is_arith_logic. * src/abg-dwarf-reader.cc (op_pushes_non_constant_value): Support DW_OP_GNU_variable_value. (op_is_arith_logic): Add a number of asserts and guards here. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
eb272db9dc
commit
97d5ae80c0
@ -7952,6 +7952,10 @@ op_pushes_non_constant_value(Dwarf_Op* ops,
|
||||
next_index = index + 1;
|
||||
break;
|
||||
|
||||
case DW_OP_GNU_variable_value:
|
||||
next_index = index + 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -8119,13 +8123,16 @@ op_is_arith_logic(Dwarf_Op* expr,
|
||||
|
||||
Dwarf_Op& op = expr[index];
|
||||
expr_result val1, val2;
|
||||
bool result = false;
|
||||
|
||||
switch (op.atom)
|
||||
{
|
||||
case DW_OP_abs:
|
||||
ABG_ASSERT(ctxt.stack.size() > 0);
|
||||
val1 = ctxt.pop();
|
||||
val1 = val1.abs();
|
||||
ctxt.push(val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_and:
|
||||
@ -8136,87 +8143,114 @@ op_is_arith_logic(Dwarf_Op* expr,
|
||||
break;
|
||||
|
||||
case DW_OP_div:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
if (!val1.is_const())
|
||||
val1 = 1;
|
||||
ctxt.push(val2 / val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_minus:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 - val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_mod:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 % val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_mul:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 * val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_neg:
|
||||
ABG_ASSERT(ctxt.stack.size() > 0);
|
||||
val1 = ctxt.pop();
|
||||
ctxt.push(-val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_not:
|
||||
ABG_ASSERT(ctxt.stack.size() > 0);
|
||||
val1 = ctxt.pop();
|
||||
ctxt.push(~val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_or:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val1 | val2);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_plus:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 + val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_plus_uconst:
|
||||
ABG_ASSERT(ctxt.stack.size() > 0);
|
||||
val1 = ctxt.pop();
|
||||
val1 += op.number;
|
||||
ctxt.push(val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_shl:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 << val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_shr:
|
||||
case DW_OP_shra:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 >> val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case DW_OP_xor:
|
||||
ABG_ASSERT(ctxt.stack.size() > 1);
|
||||
val1 = ctxt.pop();
|
||||
val2 = ctxt.pop();
|
||||
ctxt.push(val2 ^ val1);
|
||||
result = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == true)
|
||||
{
|
||||
if (ctxt.stack.front().is_const())
|
||||
ctxt.accum = ctxt.stack.front();
|
||||
|
||||
next_index = index + 1;
|
||||
return true;
|
||||
}
|
||||
return result;;
|
||||
}
|
||||
|
||||
/// If the current operation in the dwarf expression represents a push
|
||||
|
Loading…
Reference in New Issue
Block a user