A little library for patching symbols at runtime.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5296 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 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 ([email protected])
|
||||
// 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 <List.h>
|
||||
#include <String.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // ELF_SYMBOL_PATCHER_H
|
||||
Reference in New Issue
Block a user