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 43namespace SymbolPatcher { 44 45class ElfImage; 46class ElfSymbolPatcher; 47class ElfSymbolPatchGroup; 48 49// ElfSymbolPatchInfo 50class ElfSymbolPatchInfo { 51public: 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 64private: 65 class Entry; 66 67private: 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 77private: 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 88class ElfSymbolPatcher { 89public: 90 class UpdateAdapter; 91 92public: 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 105private: 106 status_t _Init(); 107 void _Cleanup(); 108 109 ElfImage* _ImageAt(int32 index) const; 110 ElfImage* _ImageForID(image_id id) const; 111 112private: 113 BList fImages; 114 status_t fInitStatus; 115}; 116 117// UpdateAdapter 118class ElfSymbolPatcher::UpdateAdapter { 119public: 120 UpdateAdapter(); 121 virtual ~UpdateAdapter(); 122 123 virtual void ImageAdded(ElfImage* image); 124 virtual void ImageRemoved(ElfImage* image); 125}; 126 127 128// ElfSymbolPatchGroup 129class ElfSymbolPatchGroup : private ElfSymbolPatcher::UpdateAdapter { 130public: 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 148private: 149 class PatchInfo : public ElfSymbolPatchInfo { 150 public: 151 void* fNewAddress; 152 }; 153 154private: 155 virtual void ImageAdded(ElfImage* image); 156 virtual void ImageRemoved(ElfImage* image); 157 158private: 159 ElfSymbolPatcher* fPatcher; 160 BList fPatchInfos; 161 bool fOwnsPatcher; 162 bool fPatched; 163}; 164 165} // namespace SymbolPatcher 166 167using namespace SymbolPatcher; 168 169 170#endif // ELF_SYMBOL_PATCHER_H 171