summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2015-10-21 17:12:44 -0700
committerMark Wielaard <mjw@redhat.com>2015-11-03 16:30:44 +0100
commitae09ca9af1eefdbc17ed1d2e95c0c244ea27a798 (patch)
treec08169ee350be23b3429f7e8290db1e3a83e5691
parent1ac2041156c3ecda5932069f1e295cc0b9727f7c (diff)
downloadelfutils-ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798.tar.gz
Move nested functions in frame_unwind.c.
* Nested functions 'pop' and 'push' in libdwfl/frame_unwind.c are moved to file scope. Used local variables are passed in struct eval_stack. Signed-off-by: Chih-Hung Hsieh <chh@google.com>
-rw-r--r--libdwfl/ChangeLog5
-rw-r--r--libdwfl/frame_unwind.c163
2 files changed, 95 insertions, 73 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index d30fd3c4..e7c373e1 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,10 @@
2015-10-21 Chih-Hung Hsieh <chh@google.com>
+ * frame_unwind.c (expr_eval): Move nested function 'push' and 'pop'
+ to file scope. Pass used local variables in struct eval_stack.
+
+2015-10-21 Chih-Hung Hsieh <chh@google.com>
+
* dwfl_module.c (dwfl_report_module): Move nested function 'use' to
file scope.
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index bd100b8f..39509b70 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -101,6 +101,49 @@ bra_compar (const void *key_voidp, const void *elem_voidp)
return (offset > op->offset) - (offset < op->offset);
}
+struct eval_stack {
+ Dwarf_Addr *addrs;
+ size_t used;
+ size_t allocated;
+};
+
+static bool
+do_push (struct eval_stack *stack, Dwarf_Addr val)
+{
+ if (stack->used >= DWARF_EXPR_STACK_MAX)
+ {
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ if (stack->used == stack->allocated)
+ {
+ stack->allocated = MAX (stack->allocated * 2, 32);
+ Dwarf_Addr *new_addrs;
+ new_addrs = realloc (stack->addrs,
+ stack->allocated * sizeof (*stack->addrs));
+ if (new_addrs == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return false;
+ }
+ stack->addrs = new_addrs;
+ }
+ stack->addrs[stack->used++] = val;
+ return true;
+}
+
+static bool
+do_pop (struct eval_stack *stack, Dwarf_Addr *val)
+{
+ if (stack->used == 0)
+ {
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ *val = stack->addrs[--stack->used];
+ return true;
+}
+
/* If FRAME is NULL is are computing CFI frame base. In such case another
DW_OP_call_frame_cfa is no longer permitted. */
@@ -114,43 +157,15 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
- Dwarf_Addr *stack = NULL;
- size_t stack_used = 0, stack_allocated = 0;
+ struct eval_stack stack =
+ {
+ .addrs = NULL,
+ .used = 0,
+ .allocated = 0
+ };
- bool
- push (Dwarf_Addr val)
- {
- if (stack_used >= DWARF_EXPR_STACK_MAX)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- if (stack_used == stack_allocated)
- {
- stack_allocated = MAX (stack_allocated * 2, 32);
- Dwarf_Addr *stack_new = realloc (stack, stack_allocated * sizeof (*stack));
- if (stack_new == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return false;
- }
- stack = stack_new;
- }
- stack[stack_used++] = val;
- return true;
- }
-
- bool
- pop (Dwarf_Addr *val)
- {
- if (stack_used == 0)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- *val = stack[--stack_used];
- return true;
- }
+#define pop(x) do_pop(&stack, x)
+#define push(x) do_push(&stack, x)
Dwarf_Addr val1, val2;
bool is_location = false;
@@ -168,14 +183,14 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_lit0 ... DW_OP_lit31:
if (! push (op->atom - DW_OP_lit0))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_addr:
if (! push (op->number + bias))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -195,7 +210,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_consts:
if (! push (op->number))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -203,67 +218,67 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
|| ! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_regx:
if (! state_get_reg (state, op->number, &val1) || ! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_breg0 ... DW_OP_breg31:
if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
val1 += op->number;
if (! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_bregx:
if (! state_get_reg (state, op->number, &val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
val1 += op->number2;
if (! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_dup:
if (! pop (&val1) || ! push (val1) || ! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_drop:
if (! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_pick:
- if (stack_used <= op->number)
+ if (stack.used <= op->number)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
- if (! push (stack[stack_used - 1 - op->number]))
+ if (! push (stack.addrs[stack.used - 1 - op->number]))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -271,14 +286,14 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! pop (&val1) || ! pop (&val2)
|| ! push (val2) || ! push (val1) || ! push (val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_swap:
if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -288,7 +303,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
|| ! push (val1) || ! push (val3) || ! push (val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
}
@@ -297,7 +312,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_deref_size:
if (process->callbacks->memory_read == NULL)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
return false;
}
@@ -305,7 +320,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
|| ! process->callbacks->memory_read (process->dwfl, val1, &val1,
process->callbacks_arg))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (op->atom == DW_OP_deref_size)
@@ -314,7 +329,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
if (op->number > addr_bytes)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
@@ -330,7 +345,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
}
if (! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -338,7 +353,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case atom: \
if (! pop (&val1) || ! push (expr)) \
{ \
- free (stack); \
+ free (stack.addrs); \
return false; \
} \
break;
@@ -349,7 +364,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_plus_uconst:
if (! pop (&val1) || ! push (val1 + op->number))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -357,7 +372,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case atom: \
if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \
{ \
- free (stack); \
+ free (stack.addrs); \
return false; \
} \
break;
@@ -366,7 +381,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! pop (&val2) || ! pop (&val1) \
|| ! push ((int64_t) val1 op (int64_t) val2)) \
{ \
- free (stack); \
+ free (stack.addrs); \
return false; \
} \
break;
@@ -374,18 +389,18 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_div:
if (! pop (&val2) || ! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (val2 == 0)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
if (! push ((int64_t) val1 / (int64_t) val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -393,18 +408,18 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_mod:
if (! pop (&val2) || ! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (val2 == 0)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
if (! push (val1 % val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -426,7 +441,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_bra:
if (! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (val1 == 0)
@@ -438,7 +453,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
sizeof (*ops), bra_compar);
if (found == NULL)
{
- free (stack);
+ free (stack.addrs);
/* PPC32 vDSO has such invalid operations. */
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
@@ -460,7 +475,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
|| ! push (cfa))
{
__libdwfl_seterrno (DWFL_E_LIBDW);
- free (stack);
+ free (stack.addrs);
return false;
}
is_location = true;
@@ -476,10 +491,10 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
}
if (! pop (result))
{
- free (stack);
+ free (stack.addrs);
return false;
}
- free (stack);
+ free (stack.addrs);
if (is_location)
{
if (process->callbacks->memory_read == NULL)
@@ -492,6 +507,8 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
return false;
}
return true;
+#undef push
+#undef pop
}
static void