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 class ElfImage; 43 class ElfSymbolPatcher; 44 class ElfSymbolPatchGroup; 45 46 // ElfSymbolPatchInfo 47 class ElfSymbolPatchInfo { 48 public: 49 ElfSymbolPatchInfo(); 50 ~ElfSymbolPatchInfo(); 51 52 status_t InitCheck() const; 53 54 const char* GetSymbolName() const; 55 void* GetOriginalAddress() const; 56 image_id GetOriginalAddressImage() const; 57 58 status_t Patch(void* newAddress); 59 status_t Restore(); 60 61 private: 62 class Entry; 63 64 private: 65 void Unset(); 66 status_t SetSymbolName(const char* name); 67 void SetOriginalAddress(void* address, 68 image_id image); 69 status_t CreateEntry(image_id image, BList* targets); 70 bool DeleteEntry(image_id image); 71 Entry* EntryAt(int32 index); 72 Entry* EntryFor(image_id image); 73 74 private: 75 friend class ElfSymbolPatcher; 76 friend class ElfSymbolPatchGroup; 77 78 BString fSymbolName; 79 void* fOriginalAddress; 80 image_id fOriginalAddressImage; 81 BList fEntries; 82 }; 83 84 // ElfSymbolPatcher 85 class ElfSymbolPatcher { 86 public: 87 class UpdateAdapter; 88 89 public: 90 ElfSymbolPatcher(); 91 ~ElfSymbolPatcher(); 92 93 status_t InitCheck() const; 94 status_t Update(UpdateAdapter* updateAdapter = NULL); 95 void Unload(); 96 97 status_t GetSymbolPatchInfo(const char* symbolName, 98 ElfSymbolPatchInfo* info); 99 status_t UpdateSymbolPatchInfo(ElfSymbolPatchInfo* info, 100 ElfImage* image); 101 102 private: 103 status_t _Init(); 104 void _Cleanup(); 105 106 ElfImage* _ImageAt(int32 index) const; 107 ElfImage* _ImageForID(image_id id) const; 108 109 private: 110 BList fImages; 111 status_t fInitStatus; 112 }; 113 114 // UpdateAdapter 115 class ElfSymbolPatcher::UpdateAdapter { 116 public: 117 UpdateAdapter(); 118 virtual ~UpdateAdapter(); 119 120 virtual void ImageAdded(ElfImage* image); 121 virtual void ImageRemoved(ElfImage* image); 122 }; 123 124 125 // ElfSymbolPatchGroup 126 class ElfSymbolPatchGroup : private ElfSymbolPatcher::UpdateAdapter { 127 public: 128 ElfSymbolPatchGroup( 129 ElfSymbolPatcher* patcher = NULL); 130 ~ElfSymbolPatchGroup(); 131 132 ElfSymbolPatcher* GetPatcher() const { return fPatcher; } 133 134 status_t AddPatch(const char* symbolName, 135 void* newAddress, 136 void** originalAddress); 137 138 void RemoveAllPatches(); 139 140 status_t Patch(); 141 status_t Restore(); 142 143 status_t Update(); 144 145 private: 146 class PatchInfo : public ElfSymbolPatchInfo { 147 public: 148 void* fNewAddress; 149 }; 150 151 private: 152 virtual void ImageAdded(ElfImage* image); 153 virtual void ImageRemoved(ElfImage* image); 154 155 private: 156 ElfSymbolPatcher* fPatcher; 157 BList fPatchInfos; 158 bool fOwnsPatcher; 159 bool fPatched; 160 }; 161 162 #endif // ELF_SYMBOL_PATCHER_H 163