1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2003, Ingo Weinhold 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: ElfSymbolPatcher.h 23 // Author: Ingo Weinhold (bonefish@users.sf.net) 24 // Description: Interface declaration of classes used for patching ELF 25 // symbols. Central class is ElfSymbolPatcher. It is a kind of 26 // roster, managing all necessary infos (loaded images) and 27 // being able to fill ElfSymbolPatchInfos with life. 28 // An ElfSymbolPatchInfo represents a symbol and is able to 29 // patch/restore it. An ElfSymbolPatchGroup bundles several 30 // ElfSymbolPatchInfos and can update their data, e.g. 31 // when images are loaded/unloaded. It uses a 32 // ElfSymbolPatcher internally and provides a more convenient 33 // API for the user. 34 //------------------------------------------------------------------------------ 35 36 #ifndef ELF_SYMBOL_PATCHER_H 37 #define ELF_SYMBOL_PATCHER_H 38 39 #include <List.h> 40 #include <String.h> 41 42 43 namespace SymbolPatcher { 44 45 class ElfImage; 46 class ElfSymbolPatcher; 47 class ElfSymbolPatchGroup; 48 49 // ElfSymbolPatchInfo 50 class ElfSymbolPatchInfo { 51 public: 52 ElfSymbolPatchInfo(); 53 ~ElfSymbolPatchInfo(); 54 55 status_t InitCheck() const; 56 57 const char* GetSymbolName() const; 58 void* GetOriginalAddress() const; 59 image_id GetOriginalAddressImage() const; 60 61 status_t Patch(void* newAddress); 62 status_t Restore(); 63 64 private: 65 class Entry; 66 67 private: 68 void Unset(); 69 status_t SetSymbolName(const char* name); 70 void SetOriginalAddress(void* address, 71 image_id image); 72 status_t CreateEntry(image_id image, BList* targets); 73 bool DeleteEntry(image_id image); 74 Entry* EntryAt(int32 index); 75 Entry* EntryFor(image_id image); 76 77 private: 78 friend class ElfSymbolPatcher; 79 friend class ElfSymbolPatchGroup; 80 81 BString fSymbolName; 82 void* fOriginalAddress; 83 image_id fOriginalAddressImage; 84 BList fEntries; 85 }; 86 87 // ElfSymbolPatcher 88 class ElfSymbolPatcher { 89 public: 90 class UpdateAdapter; 91 92 public: 93 ElfSymbolPatcher(); 94 ~ElfSymbolPatcher(); 95 96 status_t InitCheck() const; 97 status_t Update(UpdateAdapter* updateAdapter = NULL); 98 void Unload(); 99 100 status_t GetSymbolPatchInfo(const char* symbolName, 101 ElfSymbolPatchInfo* info); 102 status_t UpdateSymbolPatchInfo(ElfSymbolPatchInfo* info, 103 ElfImage* image); 104 105 private: 106 status_t _Init(); 107 void _Cleanup(); 108 109 ElfImage* _ImageAt(int32 index) const; 110 ElfImage* _ImageForID(image_id id) const; 111 112 private: 113 BList fImages; 114 status_t fInitStatus; 115 }; 116 117 // UpdateAdapter 118 class ElfSymbolPatcher::UpdateAdapter { 119 public: 120 UpdateAdapter(); 121 virtual ~UpdateAdapter(); 122 123 virtual void ImageAdded(ElfImage* image); 124 virtual void ImageRemoved(ElfImage* image); 125 }; 126 127 128 // ElfSymbolPatchGroup 129 class ElfSymbolPatchGroup : private ElfSymbolPatcher::UpdateAdapter { 130 public: 131 ElfSymbolPatchGroup( 132 ElfSymbolPatcher* patcher = NULL); 133 ~ElfSymbolPatchGroup(); 134 135 ElfSymbolPatcher* GetPatcher() const { return fPatcher; } 136 137 status_t AddPatch(const char* symbolName, 138 void* newAddress, 139 void** originalAddress); 140 141 void RemoveAllPatches(); 142 143 status_t Patch(); 144 status_t Restore(); 145 146 status_t Update(); 147 148 private: 149 class PatchInfo : public ElfSymbolPatchInfo { 150 public: 151 void* fNewAddress; 152 }; 153 154 private: 155 virtual void ImageAdded(ElfImage* image); 156 virtual void ImageRemoved(ElfImage* image); 157 158 private: 159 ElfSymbolPatcher* fPatcher; 160 BList fPatchInfos; 161 bool fOwnsPatcher; 162 bool fPatched; 163 }; 164 165 } // namespace SymbolPatcher 166 167 using namespace SymbolPatcher; 168 169 170 #endif // ELF_SYMBOL_PATCHER_H 171