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 | |
| 21 | #include <cstddef> |
| 22 | #include <cstdint> |
| 23 | |
| 24 | #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE |
| 25 | #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set |
| 26 | #elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ |
| 27 | !defined(__asmjs__) && !defined(__wasm__) |
| 28 | #define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1 |
| 29 | |
| 30 | #include <elf.h> |
| 31 | #include <link.h> // For ElfW() macro. |
| 32 | #include <functional> |
| 33 | #include <string> |
| 34 | |
| 35 | namespace absl { |
| 36 | namespace debugging_internal { |
| 37 | |
| 38 | // Iterates over all sections, invoking callback on each with the section name |
| 39 | // and the section header. |
| 40 | // |
| 41 | // Returns true on success; otherwise returns false in case of errors. |
| 42 | // |
| 43 | // This is not async-signal-safe. |
| 44 | bool ForEachSection(int fd, |
| 45 | const std::function<bool(const std::string& name, |
| 46 | const ElfW(Shdr) &)>& callback); |
| 47 | |
| 48 | // Gets the section header for the given name, if it exists. Returns true on |
| 49 | // success. Otherwise, returns false. |
| 50 | bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, |
| 51 | ElfW(Shdr) *out); |
| 52 | |
| 53 | } // namespace debugging_internal |
| 54 | } // namespace absl |
| 55 | |
| 56 | #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE |
| 57 | |
| 58 | namespace absl { |
| 59 | namespace debugging_internal { |
| 60 | |
| 61 | struct SymbolDecoratorArgs { |
| 62 | // The program counter we are getting symbolic name for. |
| 63 | const void *pc; |
| 64 | // 0 for main executable, load address for shared libraries. |
| 65 | ptrdiff_t relocation; |
| 66 | // Read-only file descriptor for ELF image covering "pc", |
| 67 | // or -1 if no such ELF image exists in /proc/self/maps. |
| 68 | int fd; |
| 69 | // Output buffer, size. |
| 70 | // Note: the buffer may not be empty -- default symbolizer may have already |
| 71 | // produced some output, and earlier decorators may have adorned it in |
| 72 | // some way. You are free to replace or augment the contents (within the |
| 73 | // symbol_buf_size limit). |
| 74 | char *const symbol_buf; |
| 75 | size_t symbol_buf_size; |
| 76 | // Temporary scratch space, size. |
| 77 | // Use that space in preference to allocating your own stack buffer to |
| 78 | // conserve stack. |
| 79 | char *const tmp_buf; |
| 80 | size_t tmp_buf_size; |
| 81 | // User-provided argument |
| 82 | void* arg; |
| 83 | }; |
| 84 | using SymbolDecorator = void (*)(const SymbolDecoratorArgs *); |
| 85 | |
| 86 | // Installs a function-pointer as a decorator. Returns a value less than zero |
| 87 | // if the system cannot install the decorator. Otherwise, returns a unique |
| 88 | // identifier corresponding to the decorator. This identifier can be used to |
| 89 | // uninstall the decorator - See RemoveSymbolDecorator() below. |
| 90 | int InstallSymbolDecorator(SymbolDecorator decorator, void* arg); |
| 91 | |
| 92 | // Removes a previously installed function-pointer decorator. Parameter "ticket" |
| 93 | // is the return-value from calling InstallSymbolDecorator(). |
| 94 | bool RemoveSymbolDecorator(int ticket); |
| 95 | |
| 96 | // Remove all installed decorators. Returns true if successful, false if |
| 97 | // symbolization is currently in progress. |
| 98 | bool RemoveAllSymbolDecorators(void); |
| 99 | |
| 100 | // Registers an address range to a file mapping. |
| 101 | // |
| 102 | // Preconditions: |
| 103 | // start <= end |
| 104 | // filename != nullptr |
| 105 | // |
| 106 | // Returns true if the file was successfully registered. |
| 107 | bool RegisterFileMappingHint( |
| 108 | const void* start, const void* end, uint64_t offset, const char* filename); |
| 109 | |
| 110 | // Looks up the file mapping registered by RegisterFileMappingHint for an |
| 111 | // address range. If there is one, the file name is stored in *filename and |
| 112 | // *start and *end are modified to reflect the registered mapping. Returns |
| 113 | // whether any hint was found. |
| 114 | bool GetFileMappingHint(const void** start, |
| 115 | const void** end, |
| 116 | uint64_t * offset, |
| 117 | const char** filename); |
| 118 | |
| 119 | } // namespace debugging_internal |
| 120 | } // namespace absl |
| 121 | |
| 122 | #endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ |