unwind.c revision 3b630b47e7d39e7b36c749290385e284bc5eb950
1/*
2 *
3 * honggfuzz - architecture dependent code (LINUX/UNWIND)
4 * -----------------------------------------
5 *
6 * Author: Robert Swiecki <swiecki@google.com>
7 *
8 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
11 * not use this file except in compliance with the License. You may obtain
12 * a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
19 * implied. See the License for the specific language governing
20 * permissions and limitations under the License.
21 *
22 */
23
24#include "common.h"
25#include "linux/unwind.h"
26
27#include <libunwind-ptrace.h>
28
29#include "log.h"
30
31size_t arch_unwindStack(pid_t pid, funcs_t * funcs)
32{
33    unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER);
34    if (!as) {
35        LOGMSG(l_ERROR, "unw_create_addr_space() failed");
36        return 0U;
37    }
38
39    void *ui = _UPT_create(pid);
40    if (ui == NULL) {
41        LOGMSG(l_ERROR, "_UPT_create(%d) failed", pid);
42        return 0U;
43    }
44
45    unw_cursor_t c;
46    if (unw_init_remote(&c, as, ui) != 0) {
47        LOGMSG(l_ERROR, "unw_init_remote() failed");
48        return 0U;
49    }
50
51    size_t ret = 0;
52    for (ret = 0; unw_step(&c) > 0 && ret < _HF_MAX_FUNCS; ret++) {
53        unw_word_t ip;
54        unw_get_reg(&c, UNW_REG_IP, &ip);
55        funcs[ret].pc = (void *)ip;
56    }
57
58    unw_destroy_addr_space(as);
59    _UPT_destroy(ui);
60
61    return ret;
62}
63