#ifndef ELF_SYMBOL_PATCHER_H
#define ELF_SYMBOL_PATCHER_H
#include <List.h>
#include <String.h>
namespace SymbolPatcher {
class ElfImage;
class ElfSymbolPatcher;
class ElfSymbolPatchGroup;
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;
};
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;
};
class ElfSymbolPatcher::UpdateAdapter {
public:
UpdateAdapter();
virtual ~UpdateAdapter();
virtual void ImageAdded(ElfImage* image);
virtual void ImageRemoved(ElfImage* image);
};
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;
};
}
using namespace SymbolPatcher;
#endif