haiku/headers/tools/elfsymbolpatcher/ElfSymbolPatcher.h
Ingo Weinhold e79e4e7c9e A little library for patching symbols at runtime.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5296 a95241bf-73f2-0310-859d-f6bbb57e9c96
2003-11-10 00:38:35 +00:00

163 lines
4.6 KiB
C++

//------------------------------------------------------------------------------
// 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 <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