//------------------------------------------------------------------------------ // Copyright (c) 2003, Ingo Weinhold // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // File Name: ElfSymbolPatcher.h // Author: Ingo Weinhold (bonefish@users.sf.net) // Description: Interface declaration of classes used for patching ELF // symbols. Central class is ElfSymbolPatcher. It is a kind of // roster, managing all necessary infos (loaded images) and // being able to fill ElfSymbolPatchInfos with life. // An ElfSymbolPatchInfo represents a symbol and is able to // patch/restore it. An ElfSymbolPatchGroup bundles several // ElfSymbolPatchInfos and can update their data, e.g. // when images are loaded/unloaded. It uses a // ElfSymbolPatcher internally and provides a more convenient // API for the user. //------------------------------------------------------------------------------ #ifndef ELF_SYMBOL_PATCHER_H #define ELF_SYMBOL_PATCHER_H #include #include namespace SymbolPatcher { class ElfImage; class ElfSymbolPatcher; class ElfSymbolPatchGroup; // ElfSymbolPatchInfo class ElfSymbolPatchInfo { public: ElfSymbolPatchInfo(); ~ElfSymbolPatchInfo(); status_t InitCheck() const; const char* GetSymbolName() const; void* GetOriginalAddress() const; image_id GetOriginalAddressImage() const; status_t Patch(void* newAddress); status_t Restore(); private: class Entry; private: void Unset(); status_t SetSymbolName(const char* name); void SetOriginalAddress(void* address, image_id image); status_t CreateEntry(image_id image, BList* targets); bool DeleteEntry(image_id image); Entry* EntryAt(int32 index); Entry* EntryFor(image_id image); private: friend class ElfSymbolPatcher; friend class ElfSymbolPatchGroup; BString fSymbolName; void* fOriginalAddress; image_id fOriginalAddressImage; BList fEntries; }; // ElfSymbolPatcher class ElfSymbolPatcher { public: class UpdateAdapter; public: ElfSymbolPatcher(); ~ElfSymbolPatcher(); status_t InitCheck() const; status_t Update(UpdateAdapter* updateAdapter = NULL); void Unload(); status_t GetSymbolPatchInfo(const char* symbolName, ElfSymbolPatchInfo* info); status_t UpdateSymbolPatchInfo(ElfSymbolPatchInfo* info, ElfImage* image); private: status_t _Init(); void _Cleanup(); ElfImage* _ImageAt(int32 index) const; ElfImage* _ImageForID(image_id id) const; private: BList fImages; status_t fInitStatus; }; // UpdateAdapter class ElfSymbolPatcher::UpdateAdapter { public: UpdateAdapter(); virtual ~UpdateAdapter(); virtual void ImageAdded(ElfImage* image); virtual void ImageRemoved(ElfImage* image); }; // ElfSymbolPatchGroup class ElfSymbolPatchGroup : private ElfSymbolPatcher::UpdateAdapter { public: ElfSymbolPatchGroup( ElfSymbolPatcher* patcher = NULL); ~ElfSymbolPatchGroup(); ElfSymbolPatcher* GetPatcher() const { return fPatcher; } status_t AddPatch(const char* symbolName, void* newAddress, void** originalAddress); void RemoveAllPatches(); status_t Patch(); status_t Restore(); status_t Update(); private: class PatchInfo : public ElfSymbolPatchInfo { public: void* fNewAddress; }; private: virtual void ImageAdded(ElfImage* image); virtual void ImageRemoved(ElfImage* image); private: ElfSymbolPatcher* fPatcher; BList fPatchInfos; bool fOwnsPatcher; bool fPatched; }; } // namespace SymbolPatcher using namespace SymbolPatcher; #endif // ELF_SYMBOL_PATCHER_H