robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 1 | /* |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 2 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 3 | * honggfuzz - architecture dependent code (LINUX/UNWIND) |
| 4 | * ----------------------------------------- |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 5 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 6 | * Author: Robert Swiecki <swiecki@google.com> |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 7 | * |
Robert Swiecki | 46288f7 | 2018-02-27 17:28:47 +0100 | [diff] [blame] | 8 | * Copyright 2010-2018 by Google Inc. All Rights Reserved. |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 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 |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 12 | * a copy of the License at |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 13 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 15 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 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. |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 21 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 22 | */ |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 23 | |
Robert Swiecki | 38ce20c | 2018-08-21 21:20:48 +0200 | [diff] [blame] | 24 | #include "linux/unwind.h" |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 25 | |
Robert Swiecki | d0fa62c | 2017-09-28 18:11:05 +0200 | [diff] [blame] | 26 | #include <endian.h> |
| 27 | #include <libunwind-ptrace.h> |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 28 | #include <stdio.h> |
| 29 | #include <stdlib.h> |
| 30 | #include <string.h> |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 31 | |
Robert Swiecki | fafed7d | 2017-11-16 23:15:10 +0100 | [diff] [blame] | 32 | #include "honggfuzz.h" |
Robert Swiecki | 246af3e | 2018-01-05 14:56:32 +0100 | [diff] [blame] | 33 | #include "libhfcommon/common.h" |
| 34 | #include "libhfcommon/log.h" |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 35 | |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 36 | /* |
| 37 | * WARNING: Ensure that _UPT-info structs are not shared between threads |
| 38 | * http://www.nongnu.org/libunwind/man/libunwind-ptrace(3).html |
| 39 | */ |
| 40 | |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 41 | // libunwind error codes used for debugging |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 42 | static const char* UNW_ER[] = { |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 43 | "UNW_ESUCCESS", /* no error */ |
| 44 | "UNW_EUNSPEC", /* unspecified (general) error */ |
| 45 | "UNW_ENOMEM", /* out of memory */ |
| 46 | "UNW_EBADREG", /* bad register number */ |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 47 | "UNW_EREADONLYREG", /* attempt to write read-only register */ |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 48 | "UNW_ESTOPUNWIND", /* stop unwinding */ |
| 49 | "UNW_EINVALIDIP", /* invalid IP */ |
| 50 | "UNW_EBADFRAME", /* bad frame */ |
| 51 | "UNW_EINVAL", /* unsupported operation or bad value */ |
| 52 | "UNW_EBADVERSION", /* unwind info has unsupported version */ |
| 53 | "UNW_ENOINFO" /* no unwind info found */ |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 54 | }; |
| 55 | |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 56 | typedef struct { |
| 57 | unsigned long start; |
| 58 | unsigned long end; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 59 | char perms[6]; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 60 | unsigned long offset; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 61 | char dev[8]; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 62 | unsigned long inode; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 63 | char name[PATH_MAX]; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 64 | } procMap_t; |
| 65 | |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 66 | static procMap_t* arch_parsePidMaps(pid_t pid, size_t* mapsCount) { |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 67 | FILE* f = NULL; |
| 68 | char fProcMaps[PATH_MAX] = {0}; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 69 | snprintf(fProcMaps, PATH_MAX, "/proc/%d/maps", pid); |
| 70 | |
| 71 | if ((f = fopen(fProcMaps, "rb")) == NULL) { |
| 72 | PLOG_E("Couldn't open '%s' - R/O mode", fProcMaps); |
| 73 | return 0; |
| 74 | } |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 75 | defer { |
| 76 | fclose(f); |
| 77 | }; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 78 | |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 79 | *mapsCount = 0; |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 80 | procMap_t* mapsList = malloc(sizeof(procMap_t)); |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 81 | if (mapsList == NULL) { |
| 82 | PLOG_W("malloc(size='%zu')", sizeof(procMap_t)); |
| 83 | return NULL; |
| 84 | } |
| 85 | |
| 86 | while (!feof(f)) { |
| 87 | char buf[sizeof(procMap_t) + 1]; |
| 88 | if (fgets(buf, sizeof(buf), f) == 0) { |
| 89 | break; |
| 90 | } |
| 91 | |
| 92 | mapsList[*mapsCount].name[0] = '\0'; |
| 93 | sscanf(buf, "%lx-%lx %5s %lx %7s %ld %s", &mapsList[*mapsCount].start, |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 94 | &mapsList[*mapsCount].end, mapsList[*mapsCount].perms, &mapsList[*mapsCount].offset, |
| 95 | mapsList[*mapsCount].dev, &mapsList[*mapsCount].inode, mapsList[*mapsCount].name); |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 96 | |
| 97 | *mapsCount += 1; |
| 98 | if ((mapsList = realloc(mapsList, (*mapsCount + 1) * sizeof(procMap_t))) == NULL) { |
| 99 | PLOG_W("realloc failed (sz=%zu)", (*mapsCount + 1) * sizeof(procMap_t)); |
| 100 | free(mapsList); |
| 101 | return NULL; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | return mapsList; |
| 106 | } |
| 107 | |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 108 | static char* arch_searchMaps(unsigned long addr, size_t mapsCnt, procMap_t* mapsList) { |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 109 | for (size_t i = 0; i < mapsCnt; i++) { |
| 110 | if (addr >= mapsList[i].start && addr <= mapsList[i].end) { |
| 111 | return mapsList[i].name; |
| 112 | } |
| 113 | |
| 114 | /* Benefit from maps being sorted by address */ |
| 115 | if (addr < mapsList[i].start) { |
| 116 | break; |
| 117 | } |
| 118 | } |
| 119 | return NULL; |
| 120 | } |
| 121 | |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 122 | #ifndef __ANDROID__ |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 123 | size_t arch_unwindStack(pid_t pid, funcs_t* funcs) { |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 124 | size_t num_frames = 0, mapsCnt = 0; |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 125 | procMap_t* mapsList = arch_parsePidMaps(pid, &mapsCnt); |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 126 | defer { |
| 127 | free(mapsList); |
| 128 | }; |
robert.swiecki@gmail.com | d712370 | 2015-02-16 14:50:50 +0000 | [diff] [blame] | 129 | |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 130 | unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER); |
| 131 | if (!as) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 132 | LOG_E("[pid='%d'] unw_create_addr_space failed", pid); |
Jagger | 8e2979b | 2016-03-22 12:29:24 +0100 | [diff] [blame] | 133 | return num_frames; |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 134 | } |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 135 | defer { |
| 136 | unw_destroy_addr_space(as); |
| 137 | }; |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 138 | |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 139 | void* ui = _UPT_create(pid); |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 140 | if (ui == NULL) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 141 | LOG_E("[pid='%d'] _UPT_create failed", pid); |
Jagger | 8e2979b | 2016-03-22 12:29:24 +0100 | [diff] [blame] | 142 | return num_frames; |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 143 | } |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 144 | defer { |
| 145 | _UPT_destroy(ui); |
| 146 | }; |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 147 | |
| 148 | unw_cursor_t c; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 149 | int ret = unw_init_remote(&c, as, ui); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 150 | if (ret < 0) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 151 | LOG_E("[pid='%d'] unw_init_remote failed (%s)", pid, UNW_ER[-ret]); |
Jagger | 8e2979b | 2016-03-22 12:29:24 +0100 | [diff] [blame] | 152 | return num_frames; |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 153 | } |
| 154 | |
Anestis Bechtsoudis | 236ef46 | 2015-08-08 03:46:51 +0300 | [diff] [blame] | 155 | for (num_frames = 0; unw_step(&c) > 0 && num_frames < _HF_MAX_FUNCS; num_frames++) { |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 156 | unw_word_t ip; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 157 | char* module = NULL; |
| 158 | ret = unw_get_reg(&c, UNW_REG_IP, &ip); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 159 | if (ret < 0) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 160 | LOG_E("[pid='%d'] [%zd] failed to read IP (%s)", pid, num_frames, UNW_ER[-ret]); |
Anestis Bechtsoudis | 236ef46 | 2015-08-08 03:46:51 +0300 | [diff] [blame] | 161 | funcs[num_frames].pc = 0; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 162 | } else { |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 163 | funcs[num_frames].pc = (void*)(uintptr_t)ip; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 164 | } |
Robert Swiecki | 9eafcc6 | 2019-12-05 15:53:39 +0100 | [diff] [blame] | 165 | if (mapsCnt > 0 && (module = arch_searchMaps(ip, mapsCnt, mapsList)) != NULL) { |
| 166 | memcpy(funcs[num_frames].module, module, sizeof(funcs[num_frames].module)); |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 167 | } else { |
Robert Swiecki | 9eafcc6 | 2019-12-05 15:53:39 +0100 | [diff] [blame] | 168 | strncpy(funcs[num_frames].module, "UNKNOWN", sizeof(funcs[num_frames].module)); |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 169 | } |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 170 | } |
| 171 | |
Anestis Bechtsoudis | 236ef46 | 2015-08-08 03:46:51 +0300 | [diff] [blame] | 172 | return num_frames; |
robert.swiecki@gmail.com | a0d8714 | 2015-02-14 13:11:18 +0000 | [diff] [blame] | 173 | } |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 174 | |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 175 | #else /* !defined(__ANDROID__) */ |
| 176 | size_t arch_unwindStack(pid_t pid, funcs_t* funcs) { |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 177 | size_t num_frames = 0, mapsCnt = 0; |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 178 | procMap_t* mapsList = arch_parsePidMaps(pid, &mapsCnt); |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 179 | defer { |
| 180 | free(mapsList); |
| 181 | }; |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 182 | |
Jagger | 79e82d1 | 2016-03-22 12:27:03 +0100 | [diff] [blame] | 183 | unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 184 | if (!as) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 185 | LOG_E("[pid='%d'] unw_create_addr_space failed", pid); |
Jagger | 79e82d1 | 2016-03-22 12:27:03 +0100 | [diff] [blame] | 186 | return num_frames; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 187 | } |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 188 | defer { |
| 189 | unw_destroy_addr_space(as); |
| 190 | }; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 191 | |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 192 | struct UPT_info* ui = (struct UPT_info*)_UPT_create(pid); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 193 | if (ui == NULL) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 194 | LOG_E("[pid='%d'] _UPT_create failed", pid); |
Jagger | 79e82d1 | 2016-03-22 12:27:03 +0100 | [diff] [blame] | 195 | return num_frames; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 196 | } |
Robert Swiecki | 3ab1664 | 2018-01-12 18:08:37 +0100 | [diff] [blame] | 197 | defer { |
| 198 | _UPT_destroy(ui); |
| 199 | }; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 200 | |
| 201 | unw_cursor_t cursor; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 202 | int ret = unw_init_remote(&cursor, as, ui); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 203 | if (ret < 0) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 204 | LOG_E("[pid='%d'] unw_init_remote failed (%s)", pid, UNW_ER[-ret]); |
Jagger | 79e82d1 | 2016-03-22 12:27:03 +0100 | [diff] [blame] | 205 | return num_frames; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 206 | } |
| 207 | |
| 208 | do { |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 209 | char* module = NULL; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 210 | unw_word_t pc = 0, offset = 0; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 211 | char buf[_HF_FUNC_NAME_SZ] = {0}; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 212 | |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 213 | ret = unw_get_reg(&cursor, UNW_REG_IP, &pc); |
| 214 | if (ret < 0) { |
Anestis Bechtsoudis | b48b474 | 2015-10-11 20:12:57 -0700 | [diff] [blame] | 215 | LOG_E("[pid='%d'] [%zd] failed to read IP (%s)", pid, num_frames, UNW_ER[-ret]); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 216 | // We don't want to try to extract info from an arbitrary IP |
| 217 | // TODO: Maybe abort completely (goto out)) |
| 218 | goto skip_frame_info; |
| 219 | } |
| 220 | |
Anestis Bechtsoudis | ffe48dc | 2015-09-12 14:25:19 +0300 | [diff] [blame] | 221 | unw_proc_info_t frameInfo; |
| 222 | ret = unw_get_proc_info(&cursor, &frameInfo); |
| 223 | if (ret < 0) { |
Anestis Bechtsoudis | b48b474 | 2015-10-11 20:12:57 -0700 | [diff] [blame] | 224 | LOG_D("[pid='%d'] [%zd] unw_get_proc_info (%s)", pid, num_frames, UNW_ER[-ret]); |
Anestis Bechtsoudis | ffe48dc | 2015-09-12 14:25:19 +0300 | [diff] [blame] | 225 | // Not safe to keep parsing frameInfo |
| 226 | goto skip_frame_info; |
| 227 | } |
| 228 | |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 229 | ret = unw_get_proc_name(&cursor, buf, sizeof(buf), &offset); |
| 230 | if (ret < 0) { |
Robert Swiecki | 0b56611 | 2017-10-17 17:39:07 +0200 | [diff] [blame] | 231 | LOG_D( |
| 232 | "[pid='%d'] [%zd] unw_get_proc_name() failed (%s)", pid, num_frames, UNW_ER[-ret]); |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 233 | buf[0] = '\0'; |
| 234 | } |
| 235 | |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 236 | skip_frame_info: |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 237 | // Compared to bfd, line var plays the role of offset from func_name |
| 238 | // Reports format is adjusted accordingly to reflect in saved file |
| 239 | funcs[num_frames].line = offset; |
Robert Swiecki | bbb476e | 2020-04-29 15:57:06 +0200 | [diff] [blame] | 240 | funcs[num_frames].pc = (void*)pc; |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 241 | memcpy(funcs[num_frames].func, buf, sizeof(funcs[num_frames].func)); |
Robert Swiecki | 9eafcc6 | 2019-12-05 15:53:39 +0100 | [diff] [blame] | 242 | if (mapsCnt > 0 && (module = arch_searchMaps(pc, mapsCnt, mapsList)) != NULL) { |
| 243 | memcpy(funcs[num_frames].module, module, sizeof(funcs[num_frames].module)); |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 244 | } else { |
Robert Swiecki | 9eafcc6 | 2019-12-05 15:53:39 +0100 | [diff] [blame] | 245 | strncpy(funcs[num_frames].module, "UNKNOWN", sizeof(funcs[num_frames].module)); |
Anestis Bechtsoudis | 3b8d47e | 2016-10-30 12:04:20 +0200 | [diff] [blame] | 246 | } |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 247 | |
| 248 | num_frames++; |
| 249 | |
| 250 | ret = unw_step(&cursor); |
| 251 | } while (ret > 0 && num_frames < _HF_MAX_FUNCS); |
| 252 | |
Anestis Bechtsoudis | cfc39fb | 2015-08-06 10:31:36 +0300 | [diff] [blame] | 253 | return num_frames; |
| 254 | } |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 255 | #endif /* defined(__ANDROID__) */ |
Anestis Bechtsoudis | ba68b38 | 2016-10-29 20:44:15 +0300 | [diff] [blame] | 256 | |
| 257 | /* |
| 258 | * Nested loop not most efficient approach, although it's assumed that list is |
| 259 | * usually target specific and thus small. |
| 260 | */ |
Robert Swiecki | 0b56611 | 2017-10-17 17:39:07 +0200 | [diff] [blame] | 261 | char* arch_btContainsSymbol( |
Robert Swiecki | d50ed42 | 2017-11-13 23:32:26 +0100 | [diff] [blame] | 262 | size_t symbolsListSz, char** symbolsList, size_t num_frames, funcs_t* funcs) { |
Anestis Bechtsoudis | ba68b38 | 2016-10-29 20:44:15 +0300 | [diff] [blame] | 263 | for (size_t frame = 0; frame < num_frames; frame++) { |
| 264 | size_t len = strlen(funcs[frame].func); |
| 265 | |
| 266 | /* Try only for frames that have symbol name from backtrace */ |
| 267 | if (strlen(funcs[frame].func) > 0) { |
| 268 | for (size_t i = 0; i < symbolsListSz; i++) { |
| 269 | /* Wildcard symbol string special case */ |
Robert Swiecki | 4e595fb | 2017-10-11 17:26:51 +0200 | [diff] [blame] | 270 | char* wOff = strchr(symbolsList[i], '*'); |
Anestis Bechtsoudis | ba68b38 | 2016-10-29 20:44:15 +0300 | [diff] [blame] | 271 | if (wOff) { |
| 272 | /* Length always > 3 as checked at input file parsing step */ |
| 273 | len = wOff - symbolsList[i] - 1; |
| 274 | } |
| 275 | |
| 276 | if (strncmp(funcs[frame].func, symbolsList[i], len) == 0) { |
| 277 | return funcs[frame].func; |
| 278 | } |
| 279 | } |
| 280 | } |
| 281 | } |
| 282 | return NULL; |
| 283 | } |