diff options
author | Chih-Hung Hsieh <chh@google.com> | 2015-10-21 17:12:44 -0700 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2015-11-03 16:30:44 +0100 |
commit | ae09ca9af1eefdbc17ed1d2e95c0c244ea27a798 (patch) | |
tree | c08169ee350be23b3429f7e8290db1e3a83e5691 | |
parent | 1ac2041156c3ecda5932069f1e295cc0b9727f7c (diff) | |
download | elfutils-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/ChangeLog | 5 | ||||
-rw-r--r-- | libdwfl/frame_unwind.c | 163 |
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 |