Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:16

0001 /*
0002  * Copyright 2017 The Abseil Authors.
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *      https://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  */
0016 
0017 // Allow dynamic symbol lookup for in-memory Elf images.
0018 
0019 #ifndef ABSL_DEBUGGING_INTERNAL_ELF_MEM_IMAGE_H_
0020 #define ABSL_DEBUGGING_INTERNAL_ELF_MEM_IMAGE_H_
0021 
0022 // Including this will define the __GLIBC__ macro if glibc is being
0023 // used.
0024 #include <climits>
0025 #include <cstdint>
0026 
0027 #include "absl/base/config.h"
0028 
0029 // Maybe one day we can rewrite this file not to require the elf
0030 // symbol extensions in glibc, but for right now we need them.
0031 #ifdef ABSL_HAVE_ELF_MEM_IMAGE
0032 #error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set
0033 #endif
0034 
0035 #if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) && \
0036     !defined(__native_client__) && !defined(__asmjs__) &&             \
0037     !defined(__wasm__) && !defined(__HAIKU__) && !defined(__sun) &&   \
0038     !defined(__VXWORKS__) && !defined(__hexagon__)
0039 #define ABSL_HAVE_ELF_MEM_IMAGE 1
0040 #endif
0041 
0042 #ifdef ABSL_HAVE_ELF_MEM_IMAGE
0043 
0044 #include <link.h>  // for ElfW
0045 
0046 #if defined(__FreeBSD__) && !defined(ElfW)
0047 #define ElfW(x) __ElfN(x)
0048 #endif
0049 
0050 namespace absl {
0051 ABSL_NAMESPACE_BEGIN
0052 namespace debugging_internal {
0053 
0054 // An in-memory ELF image (may not exist on disk).
0055 class ElfMemImage {
0056  private:
0057   // Sentinel: there could never be an elf image at &kInvalidBaseSentinel.
0058   static const int kInvalidBaseSentinel;
0059 
0060  public:
0061   // Sentinel: there could never be an elf image at this address.
0062   static constexpr const void *const kInvalidBase =
0063     static_cast<const void*>(&kInvalidBaseSentinel);
0064 
0065   // Information about a single vdso symbol.
0066   // All pointers are into .dynsym, .dynstr, or .text of the VDSO.
0067   // Do not free() them or modify through them.
0068   struct SymbolInfo {
0069     const char      *name;      // E.g. "__vdso_getcpu"
0070     const char      *version;   // E.g. "LINUX_2.6", could be ""
0071                                 // for unversioned symbol.
0072     const void      *address;   // Relocated symbol address.
0073     const ElfW(Sym) *symbol;    // Symbol in the dynamic symbol table.
0074   };
0075 
0076   // Supports iteration over all dynamic symbols.
0077   class SymbolIterator {
0078    public:
0079     friend class ElfMemImage;
0080     const SymbolInfo *operator->() const;
0081     const SymbolInfo &operator*() const;
0082     SymbolIterator& operator++();
0083     bool operator!=(const SymbolIterator &rhs) const;
0084     bool operator==(const SymbolIterator &rhs) const;
0085    private:
0086     SymbolIterator(const void *const image, uint32_t index);
0087     void Update(uint32_t incr);
0088     SymbolInfo info_;
0089     uint32_t index_;
0090     const void *const image_;
0091   };
0092 
0093 
0094   explicit ElfMemImage(const void *base);
0095   void                 Init(const void *base);
0096   bool                 IsPresent() const { return ehdr_ != nullptr; }
0097   const ElfW(Phdr)*    GetPhdr(int index) const;
0098   const ElfW(Sym) * GetDynsym(uint32_t index) const;
0099   const ElfW(Versym)*  GetVersym(uint32_t index) const;
0100   const ElfW(Verdef)*  GetVerdef(int index) const;
0101   const ElfW(Verdaux)* GetVerdefAux(const ElfW(Verdef) *verdef) const;
0102   const char*          GetDynstr(ElfW(Word) offset) const;
0103   const void*          GetSymAddr(const ElfW(Sym) *sym) const;
0104   const char*          GetVerstr(ElfW(Word) offset) const;
0105   uint32_t GetNumSymbols() const;
0106 
0107   SymbolIterator begin() const;
0108   SymbolIterator end() const;
0109 
0110   // Look up versioned dynamic symbol in the image.
0111   // Returns false if image is not present, or doesn't contain given
0112   // symbol/version/type combination.
0113   // If info_out is non-null, additional details are filled in.
0114   bool LookupSymbol(const char *name, const char *version,
0115                     int symbol_type, SymbolInfo *info_out) const;
0116 
0117   // Find info about symbol (if any) which overlaps given address.
0118   // Returns true if symbol was found; false if image isn't present
0119   // or doesn't have a symbol overlapping given address.
0120   // If info_out is non-null, additional details are filled in.
0121   bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
0122 
0123  private:
0124   const ElfW(Ehdr) *ehdr_;
0125   const ElfW(Sym) *dynsym_;
0126   const ElfW(Versym) *versym_;
0127   const ElfW(Verdef) *verdef_;
0128   const char *dynstr_;
0129   uint32_t num_syms_;
0130   size_t strsize_;
0131   size_t verdefnum_;
0132   ElfW(Addr) link_base_;     // Link-time base (p_vaddr of first PT_LOAD).
0133 };
0134 
0135 }  // namespace debugging_internal
0136 ABSL_NAMESPACE_END
0137 }  // namespace absl
0138 
0139 #endif  // ABSL_HAVE_ELF_MEM_IMAGE
0140 
0141 #endif  // ABSL_DEBUGGING_INTERNAL_ELF_MEM_IMAGE_H_