| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef LIBRARY_H__ | |
| 6 #define LIBRARY_H__ | |
| 7 | |
| 8 #include <elf.h> | |
| 9 #include <functional> | |
| 10 #include <map> | |
| 11 #include <set> | |
| 12 #include <string> | |
| 13 #include <string.h> | |
| 14 #include <sys/mman.h> | |
| 15 | |
| 16 #include "maps.h" | |
| 17 | |
| 18 #if defined(__x86_64__) | |
| 19 typedef Elf64_Ehdr Elf_Ehdr; | |
| 20 typedef Elf64_Shdr Elf_Shdr; | |
| 21 typedef Elf64_Sym Elf_Sym; | |
| 22 typedef Elf64_Addr Elf_Addr; | |
| 23 #elif defined(__i386__) | |
| 24 typedef Elf32_Ehdr Elf_Ehdr; | |
| 25 typedef Elf32_Shdr Elf_Shdr; | |
| 26 typedef Elf32_Sym Elf_Sym; | |
| 27 typedef Elf32_Addr Elf_Addr; | |
| 28 #else | |
| 29 #error Unsupported target platform | |
| 30 #endif | |
| 31 | |
| 32 struct SyscallTable; | |
| 33 namespace playground { | |
| 34 | |
| 35 class Library { | |
| 36 friend class Maps; | |
| 37 public: | |
| 38 typedef Maps::string string; | |
| 39 | |
| 40 Library() : | |
| 41 valid_(false), | |
| 42 isVDSO_(false), | |
| 43 asr_offset_(0), | |
| 44 vsys_offset_(0), | |
| 45 maps_(0), | |
| 46 image_(0), | |
| 47 image_size_(0) { | |
| 48 } | |
| 49 | |
| 50 ~Library(); | |
| 51 | |
| 52 void setLibraryInfo(Maps* maps) { | |
| 53 if (!maps_) { | |
| 54 maps_ = maps; | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 void addMemoryRange(void* start, void* stop, Elf_Addr offset, | |
| 59 int prot, int isVDSO) { | |
| 60 isVDSO_ = isVDSO; | |
| 61 RangeMap::const_iterator iter = memory_ranges_.find(offset); | |
| 62 if (iter != memory_ranges_.end()) { | |
| 63 // It is possible to have overlapping mappings. This is particularly | |
| 64 // likely to happen with very small programs or libraries. If it does | |
| 65 // happen, we really only care about the text segment. Look for a | |
| 66 // mapping that is mapped executable. | |
| 67 if ((prot & PROT_EXEC) == 0) { | |
| 68 return; | |
| 69 } | |
| 70 } | |
| 71 memory_ranges_.insert(std::make_pair(offset, Range(start, stop, prot))); | |
| 72 } | |
| 73 | |
| 74 char *get(Elf_Addr offset, char *buf, size_t len); | |
| 75 string get(Elf_Addr offset); | |
| 76 char *getOriginal(Elf_Addr offset, char *buf, size_t len); | |
| 77 string getOriginal(Elf_Addr offset); | |
| 78 | |
| 79 template<class T>T* get(Elf_Addr offset, T* t) { | |
| 80 if (!valid_) { | |
| 81 memset(t, 0, sizeof(T)); | |
| 82 return NULL; | |
| 83 } | |
| 84 return reinterpret_cast<T *>(get(offset, reinterpret_cast<char *>(t), | |
| 85 sizeof(T))); | |
| 86 } | |
| 87 | |
| 88 template<class T>T* getOriginal(Elf_Addr offset, T* t) { | |
| 89 if (!valid_) { | |
| 90 memset(t, 0, sizeof(T)); | |
| 91 return NULL; | |
| 92 } | |
| 93 return reinterpret_cast<T *>(getOriginal(offset, | |
| 94 reinterpret_cast<char *>(t), | |
| 95 sizeof(T))); | |
| 96 } | |
| 97 | |
| 98 template<class T>bool set(void *addr, T* value) { | |
| 99 if (!valid_) { | |
| 100 return false; | |
| 101 } | |
| 102 *reinterpret_cast<T *>(addr) = *value; | |
| 103 return true; | |
| 104 } | |
| 105 | |
| 106 template<class T>bool set(Elf_Addr offset, T* value) { | |
| 107 if (!valid_) { | |
| 108 return false; | |
| 109 } | |
| 110 RangeMap::const_iterator iter = memory_ranges_.lower_bound(offset); | |
| 111 if (iter == memory_ranges_.end()) { | |
| 112 return false; | |
| 113 } | |
| 114 offset -= iter->first; | |
| 115 if (offset > | |
| 116 reinterpret_cast<char *>(iter->second.stop) - | |
| 117 reinterpret_cast<char *>(iter->second.start) - | |
| 118 sizeof(T)) { | |
| 119 return false; | |
| 120 } | |
| 121 *reinterpret_cast<T *>( | |
| 122 reinterpret_cast<char *>(iter->second.start) + offset) = *value; | |
| 123 return true; | |
| 124 } | |
| 125 | |
| 126 bool parseElf(); | |
| 127 const Elf_Ehdr* getEhdr(); | |
| 128 const Elf_Shdr* getSection(const string& section); | |
| 129 int getSectionIndex(const string& section); | |
| 130 void makeWritable(bool state) const; | |
| 131 void patchSystemCalls(); | |
| 132 bool isVDSO() const { return isVDSO_; } | |
| 133 | |
| 134 protected: | |
| 135 bool parseSymbols(); | |
| 136 | |
| 137 private: | |
| 138 class GreaterThan : public std::binary_function<Elf_Addr, Elf_Addr, bool> { | |
| 139 // We create the RangeMap with a GreaterThan rather than the default | |
| 140 // comparator, as that allows us to use lower_bound() to find memory | |
| 141 // mappings. | |
| 142 public: | |
| 143 bool operator() (Elf_Addr s1, Elf_Addr s2) const { | |
| 144 return s1 > s2; | |
| 145 } | |
| 146 }; | |
| 147 | |
| 148 struct Range { | |
| 149 Range(void* start, void* stop, int prot) : | |
| 150 start(start), stop(stop), prot(prot) { } | |
| 151 void* start; | |
| 152 void* stop; | |
| 153 int prot; | |
| 154 }; | |
| 155 | |
| 156 typedef std::map<Elf_Addr, Range, GreaterThan, | |
| 157 SystemAllocator<std::pair<const Elf_Addr, | |
| 158 Range> > > RangeMap; | |
| 159 typedef std::map<string, std::pair<int, Elf_Shdr>, std::less<string>, | |
| 160 SystemAllocator<std::pair<const string, | |
| 161 std::pair<int, Elf_Shdr> > > > | |
| 162 SectionTable; | |
| 163 typedef std::map<string, Elf_Sym, std::less<string>, | |
| 164 SystemAllocator<std::pair<const string, | |
| 165 Elf_Sym> > > SymbolTable; | |
| 166 typedef std::map<string, Elf_Addr, std::less<string>, | |
| 167 SystemAllocator<std::pair<const string, | |
| 168 Elf_Addr> > > PltTable; | |
| 169 | |
| 170 char* getBytes(char* dst, const char* src, ssize_t len); | |
| 171 static bool isSafeInsn(unsigned short insn); | |
| 172 static int isSimpleSystemCall(char *start, char *end); | |
| 173 static char* getScratchSpace(const Maps* maps, char* near, int needed, | |
| 174 char** extraSpace, int* extraLength); | |
| 175 void patchSystemCallsInFunction(const Maps* maps, char *start, char *end, | |
| 176 char** extraSpace, int* extraLength); | |
| 177 int patchVSystemCalls(); | |
| 178 void patchVDSO(char** extraSpace, int* extraLength); | |
| 179 | |
| 180 RangeMap memory_ranges_; | |
| 181 bool valid_; | |
| 182 bool isVDSO_; | |
| 183 char* asr_offset_; | |
| 184 int vsys_offset_; | |
| 185 Maps* maps_; | |
| 186 Elf_Ehdr ehdr_; | |
| 187 SectionTable section_table_; | |
| 188 SymbolTable symbols_; | |
| 189 PltTable plt_entries_; | |
| 190 char* image_; | |
| 191 size_t image_size_; | |
| 192 static char* __kernel_vsyscall; | |
| 193 static char* __kernel_sigreturn; | |
| 194 static char* __kernel_rt_sigreturn; | |
| 195 }; | |
| 196 | |
| 197 } // namespace | |
| 198 | |
| 199 #endif // LIBRARY_H__ | |
| OLD | NEW |