2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #ifndef FOLLY_EXPERIMENTAL_SYMBOLIZER_ELF_H_
20 #define FOLLY_EXPERIMENTAL_SYMBOLIZER_ELF_H_
24 #include <link.h> // For ElfW()
27 #include <system_error>
29 #include "folly/Likely.h"
30 #include "folly/Range.h"
31 #include "folly/Conv.h"
34 namespace symbolizer {
39 * We handle native files only (32-bit files on a 32-bit platform, 64-bit files
40 * on a 64-bit platform), and only executables (ET_EXEC) and shared objects
46 explicit ElfFile(const char* name);
49 ElfFile(ElfFile&& other);
50 ElfFile& operator=(ElfFile&& other);
52 /** Retrieve the ELF header */
53 const ElfW(Ehdr)& elfHeader() const {
54 return at<ElfW(Ehdr)>(0);
58 * Get the base address, the address where the file should be loaded if
59 * no relocations happened.
61 uintptr_t getBaseAddress() const {
65 /** Find a section given its name */
66 const ElfW(Shdr)* getSectionByName(const char* name) const;
68 /** Find a section given its index in the section header table */
69 const ElfW(Shdr)* getSectionByIndex(size_t idx) const;
71 /** Retrieve the name of a section */
72 const char* getSectionName(const ElfW(Shdr)& section) const;
74 /** Get the actual section body */
75 folly::StringPiece getSectionBody(const ElfW(Shdr)& section) const;
77 /** Retrieve a string from a string table section */
78 const char* getString(const ElfW(Shdr)& stringTable, size_t offset) const;
81 * Iterate over all strings in a string table section for as long as
82 * fn(str) returns false.
83 * Returns the current ("found") string when fn returned true, or nullptr
84 * if fn returned false for all strings in the table.
87 const char* iterateStrings(const ElfW(Shdr)& stringTable, Fn fn) const;
90 * Iterate over all sections for as long as fn(section) returns false.
91 * Returns a pointer to the current ("found") section when fn returned
92 * true, or nullptr if fn returned false for all sections.
95 const ElfW(Shdr)* iterateSections(Fn fn) const;
98 * Iterate over all sections with a given type. Similar to
99 * iterateSections(), but filtered only for sections with the given type.
102 const ElfW(Shdr)* iterateSectionsWithType(uint32_t type, Fn fn) const;
105 * Find symbol definition by address.
106 * Note that this is the file virtual address, so you need to undo
107 * any relocation that might have happened.
109 typedef std::pair<const ElfW(Shdr)*, const ElfW(Sym)*> Symbol;
110 Symbol getDefinitionByAddress(uintptr_t address) const;
113 * Retrieve symbol name.
115 const char* getSymbolName(Symbol symbol) const;
120 ElfFile(const ElfFile&) = delete;
121 ElfFile& operator=(const ElfFile&) = delete;
123 void validateStringTable(const ElfW(Shdr)& stringTable) const;
126 const T& at(off_t offset) const {
127 return *reinterpret_cast<T*>(file_ + offset);
131 char* file_; // mmap() location
132 size_t length_; // mmap() length
134 uintptr_t baseAddress_;
137 template <class... Args>
138 void systemError(Args... args) __attribute__((noreturn));
140 template <class... Args>
141 void systemError(Args... args) {
142 throw std::system_error(errno, std::system_category(),
143 folly::to<std::string>(args...));
146 template <class... Args>
147 inline void enforce(bool v, Args... args) {
149 throw std::runtime_error(folly::to<std::string>(args...));
153 } // namespace symbolizer
156 #include "folly/experimental/symbolizer/Elf-inl.h"
158 #endif /* FOLLY_EXPERIMENTAL_SYMBOLIZER_ELF_H_ */