| 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 (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_ | 
|---|
| 123 |  | 
|---|