Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 1 | // Copyright 2018 The Abseil Authors. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | // This file contains internal parts of the Abseil symbolizer. |
| 16 | // Do not depend on the anything in this file, it may change at anytime. |
| 17 | |
| 18 | #ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ |
| 19 | #define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ |
| 20 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 21 | #ifdef __cplusplus |
| 22 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 23 | #include <cstddef> |
| 24 | #include <cstdint> |
| 25 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 26 | #include "absl/base/config.h" |
| 27 | #include "absl/strings/string_view.h" |
| 28 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 29 | #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE |
| 30 | #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set |
| 31 | #elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ |
| 32 | !defined(__asmjs__) && !defined(__wasm__) |
| 33 | #define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1 |
| 34 | |
| 35 | #include <elf.h> |
| 36 | #include <link.h> // For ElfW() macro. |
| 37 | #include <functional> |
| 38 | #include <string> |
| 39 | |
| 40 | namespace absl { |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 41 | ABSL_NAMESPACE_BEGIN |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 42 | namespace debugging_internal { |
| 43 | |
| 44 | // Iterates over all sections, invoking callback on each with the section name |
| 45 | // and the section header. |
| 46 | // |
| 47 | // Returns true on success; otherwise returns false in case of errors. |
| 48 | // |
| 49 | // This is not async-signal-safe. |
| 50 | bool ForEachSection(int fd, |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 51 | const std::function<bool(absl::string_view name, |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 52 | const ElfW(Shdr) &)>& callback); |
| 53 | |
| 54 | // Gets the section header for the given name, if it exists. Returns true on |
| 55 | // success. Otherwise, returns false. |
| 56 | bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, |
| 57 | ElfW(Shdr) *out); |
| 58 | |
| 59 | } // namespace debugging_internal |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 60 | ABSL_NAMESPACE_END |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 61 | } // namespace absl |
| 62 | |
| 63 | #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE |
| 64 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 65 | #ifdef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE |
| 66 | #error ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE cannot be directly set |
| 67 | #elif defined(__APPLE__) |
| 68 | #define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1 |
| 69 | #endif |
| 70 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 71 | namespace absl { |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 72 | ABSL_NAMESPACE_BEGIN |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 73 | namespace debugging_internal { |
| 74 | |
| 75 | struct SymbolDecoratorArgs { |
| 76 | // The program counter we are getting symbolic name for. |
| 77 | const void *pc; |
| 78 | // 0 for main executable, load address for shared libraries. |
| 79 | ptrdiff_t relocation; |
| 80 | // Read-only file descriptor for ELF image covering "pc", |
| 81 | // or -1 if no such ELF image exists in /proc/self/maps. |
| 82 | int fd; |
| 83 | // Output buffer, size. |
| 84 | // Note: the buffer may not be empty -- default symbolizer may have already |
| 85 | // produced some output, and earlier decorators may have adorned it in |
| 86 | // some way. You are free to replace or augment the contents (within the |
| 87 | // symbol_buf_size limit). |
| 88 | char *const symbol_buf; |
| 89 | size_t symbol_buf_size; |
| 90 | // Temporary scratch space, size. |
| 91 | // Use that space in preference to allocating your own stack buffer to |
| 92 | // conserve stack. |
| 93 | char *const tmp_buf; |
| 94 | size_t tmp_buf_size; |
| 95 | // User-provided argument |
| 96 | void* arg; |
| 97 | }; |
| 98 | using SymbolDecorator = void (*)(const SymbolDecoratorArgs *); |
| 99 | |
| 100 | // Installs a function-pointer as a decorator. Returns a value less than zero |
| 101 | // if the system cannot install the decorator. Otherwise, returns a unique |
| 102 | // identifier corresponding to the decorator. This identifier can be used to |
| 103 | // uninstall the decorator - See RemoveSymbolDecorator() below. |
| 104 | int InstallSymbolDecorator(SymbolDecorator decorator, void* arg); |
| 105 | |
| 106 | // Removes a previously installed function-pointer decorator. Parameter "ticket" |
| 107 | // is the return-value from calling InstallSymbolDecorator(). |
| 108 | bool RemoveSymbolDecorator(int ticket); |
| 109 | |
| 110 | // Remove all installed decorators. Returns true if successful, false if |
| 111 | // symbolization is currently in progress. |
| 112 | bool RemoveAllSymbolDecorators(void); |
| 113 | |
| 114 | // Registers an address range to a file mapping. |
| 115 | // |
| 116 | // Preconditions: |
| 117 | // start <= end |
| 118 | // filename != nullptr |
| 119 | // |
| 120 | // Returns true if the file was successfully registered. |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 121 | bool RegisterFileMappingHint(const void* start, const void* end, |
| 122 | uint64_t offset, const char* filename); |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 123 | |
| 124 | // Looks up the file mapping registered by RegisterFileMappingHint for an |
| 125 | // address range. If there is one, the file name is stored in *filename and |
| 126 | // *start and *end are modified to reflect the registered mapping. Returns |
| 127 | // whether any hint was found. |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 128 | bool GetFileMappingHint(const void** start, const void** end, uint64_t* offset, |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 129 | const char** filename); |
| 130 | |
| 131 | } // namespace debugging_internal |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 132 | ABSL_NAMESPACE_END |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 133 | } // namespace absl |
| 134 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 135 | #endif // __cplusplus |
| 136 | |
| 137 | #include <stdbool.h> |
| 138 | |
| 139 | #ifdef __cplusplus |
| 140 | extern "C" |
| 141 | #endif // __cplusplus |
| 142 | |
| 143 | bool |
| 144 | AbslInternalGetFileMappingHint(const void** start, const void** end, |
| 145 | uint64_t* offset, const char** filename); |
| 146 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 147 | #endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ |