239222b236
* Several fixes to get things building with gcc 4. * Changed lookup of the _GLOBAL_OFFSET_TABLE_ symbol. It is hidden and static and get_image_symbol() doesn't find it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33897 a95241bf-73f2-0310-859d-f6bbb57e9c96
171 lines
4.7 KiB
C++
171 lines
4.7 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>
|
|
|
|
|
|
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
|