| // Copyright 2018 The Abseil Authors. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // This file contains internal parts of the Abseil symbolizer. | |
| // Do not depend on the anything in this file, it may change at anytime. | |
| #ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ | |
| #define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include "absl/base/port.h" // Needed for string vs std::string | |
| #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE | |
| #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set | |
| #elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ | |
| !defined(__asmjs__) && !defined(__wasm__) | |
| #define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1 | |
| #include <elf.h> | |
| #include <link.h> // For ElfW() macro. | |
| #include <functional> | |
| #include <string> | |
| namespace absl { | |
| namespace debugging_internal { | |
| // Iterates over all sections, invoking callback on each with the section name | |
| // and the section header. | |
| // | |
| // Returns true on success; otherwise returns false in case of errors. | |
| // | |
| // This is not async-signal-safe. | |
| bool ForEachSection( | |
| int fd, const std::function<bool(const std::string& name, const ElfW(Shdr) &)>& | |
| callback); | |
| // Gets the section header for the given name, if it exists. Returns true on | |
| // success. Otherwise, returns false. | |
| bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, | |
| ElfW(Shdr) *out); | |
| } // namespace debugging_internal | |
| } // namespace absl | |
| #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE | |
| namespace absl { | |
| namespace debugging_internal { | |
| struct SymbolDecoratorArgs { | |
| // The program counter we are getting symbolic name for. | |
| const void *pc; | |
| // 0 for main executable, load address for shared libraries. | |
| ptrdiff_t relocation; | |
| // Read-only file descriptor for ELF image covering "pc", | |
| // or -1 if no such ELF image exists in /proc/self/maps. | |
| int fd; | |
| // Output buffer, size. | |
| // Note: the buffer may not be empty -- default symbolizer may have already | |
| // produced some output, and earlier decorators may have adorned it in | |
| // some way. You are free to replace or augment the contents (within the | |
| // symbol_buf_size limit). | |
| char *const symbol_buf; | |
| size_t symbol_buf_size; | |
| // Temporary scratch space, size. | |
| // Use that space in preference to allocating your own stack buffer to | |
| // conserve stack. | |
| char *const tmp_buf; | |
| size_t tmp_buf_size; | |
| // User-provided argument | |
| void* arg; | |
| }; | |
| using SymbolDecorator = void (*)(const SymbolDecoratorArgs *); | |
| // Installs a function-pointer as a decorator. Returns a value less than zero | |
| // if the system cannot install the decorator. Otherwise, returns a unique | |
| // identifier corresponding to the decorator. This identifier can be used to | |
| // uninstall the decorator - See RemoveSymbolDecorator() below. | |
| int InstallSymbolDecorator(SymbolDecorator decorator, void* arg); | |
| // Removes a previously installed function-pointer decorator. Parameter "ticket" | |
| // is the return-value from calling InstallSymbolDecorator(). | |
| bool RemoveSymbolDecorator(int ticket); | |
| // Remove all installed decorators. Returns true if successful, false if | |
| // symbolization is currently in progress. | |
| bool RemoveAllSymbolDecorators(void); | |
| // Registers an address range to a file mapping. | |
| // | |
| // Preconditions: | |
| // start <= end | |
| // filename != nullptr | |
| // | |
| // Returns true if the file was successfully registered. | |
| bool RegisterFileMappingHint( | |
| const void* start, const void* end, uint64_t offset, const char* filename); | |
| // Looks up the file mapping registered by RegisterFileMappingHint for an | |
| // address range. If there is one, the file name is stored in *filename and | |
| // *start and *end are modified to reflect the registered mapping. Returns | |
| // whether any hint was found. | |
| bool GetFileMappingHint(const void** start, | |
| const void** end, | |
| uint64_t * offset, | |
| const char** filename); | |
| } // namespace debugging_internal | |
| } // namespace absl | |
| #endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ |