| // 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_ |