* Moved everything into the SymbolPatcher namespace.
* 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
This commit is contained in:
@@ -39,6 +39,9 @@
|
|||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SymbolPatcher {
|
||||||
|
|
||||||
class ElfImage;
|
class ElfImage;
|
||||||
class ElfSymbolPatcher;
|
class ElfSymbolPatcher;
|
||||||
class ElfSymbolPatchGroup;
|
class ElfSymbolPatchGroup;
|
||||||
@@ -159,4 +162,9 @@ private:
|
|||||||
bool fPatched;
|
bool fPatched;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace SymbolPatcher
|
||||||
|
|
||||||
|
using namespace SymbolPatcher;
|
||||||
|
|
||||||
|
|
||||||
#endif // ELF_SYMBOL_PATCHER_H
|
#endif // ELF_SYMBOL_PATCHER_H
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ read_exactly(BPositionIO &file, off_t position, void *buffer, size_t size,
|
|||||||
|
|
||||||
// ElfSection
|
// ElfSection
|
||||||
|
|
||||||
class ElfSection {
|
class SymbolPatcher::ElfSection {
|
||||||
public:
|
public:
|
||||||
ElfSection();
|
ElfSection();
|
||||||
~ElfSection();
|
~ElfSection();
|
||||||
@@ -671,7 +671,7 @@ ElfFile::_SetTo(const char *filename)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
// allocate memory for the section header table and read it
|
// allocate memory for the section header table and read it
|
||||||
fSectionHeaders = new(nothrow) uint8[sectionHeaderTableSize];
|
fSectionHeaders = new(std::nothrow) uint8[sectionHeaderTableSize];
|
||||||
fSectionCount = sectionHeaderCount;
|
fSectionCount = sectionHeaderCount;
|
||||||
fSectionHeaderSize = sectionHeaderSize;
|
fSectionHeaderSize = sectionHeaderSize;
|
||||||
if (!fSectionHeaders)
|
if (!fSectionHeaders)
|
||||||
@@ -682,7 +682,7 @@ ElfFile::_SetTo(const char *filename)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
// allocate memory for the section pointers
|
// allocate memory for the section pointers
|
||||||
fSections = new(nothrow) ElfSection[fSectionCount];
|
fSections = new(std::nothrow) ElfSection[fSectionCount];
|
||||||
if (!fSections)
|
if (!fSections)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
// init the sections
|
// init the sections
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
|
|
||||||
#include "Elf.h"
|
#include "Elf.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SymbolPatcher {
|
||||||
|
|
||||||
class ElfFile;
|
class ElfFile;
|
||||||
class ElfSection;
|
class ElfSection;
|
||||||
|
|
||||||
@@ -134,4 +137,9 @@ private:
|
|||||||
size_t fSectionHeaderSize;
|
size_t fSectionHeaderSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace SymbolPatcher
|
||||||
|
|
||||||
|
using namespace SymbolPatcher;
|
||||||
|
|
||||||
|
|
||||||
#endif // ELF_FILE_H
|
#endif // ELF_FILE_H
|
||||||
|
|||||||
@@ -33,8 +33,65 @@
|
|||||||
|
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
|
|
||||||
|
#include <debug/debug_support.h>
|
||||||
|
|
||||||
#include "ElfImage.h"
|
#include "ElfImage.h"
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
get_static_image_symbol(image_id image, const char* name, int32 symbolType,
|
||||||
|
void** _address)
|
||||||
|
{
|
||||||
|
// try standard lookup first
|
||||||
|
status_t error = get_image_symbol(image, name, symbolType, _address);
|
||||||
|
if (error == B_OK)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
// get an image info
|
||||||
|
image_info imageInfo;
|
||||||
|
error = get_image_info(image, &imageInfo);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// get a symbol iterator
|
||||||
|
debug_symbol_iterator* iterator;
|
||||||
|
error = debug_create_file_symbol_iterator(imageInfo.name, &iterator);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// get the unrelocated image info
|
||||||
|
image_info unrelocatedImageInfo;
|
||||||
|
error = debug_get_symbol_iterator_image_info(iterator,
|
||||||
|
&unrelocatedImageInfo);
|
||||||
|
if (error != B_OK) {
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate through the symbols
|
||||||
|
int32 nameLength = strlen(name);
|
||||||
|
while (true) {
|
||||||
|
char foundName[nameLength + 1];
|
||||||
|
int32 foundType;
|
||||||
|
void* foundAddress;
|
||||||
|
size_t foundSize;
|
||||||
|
if (debug_next_image_symbol(iterator, foundName, nameLength + 1,
|
||||||
|
&foundType, &foundAddress, &foundSize) != B_OK) {
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(foundName, name) == 0
|
||||||
|
&& (symbolType == B_SYMBOL_TYPE_ANY || foundType == symbolType)) {
|
||||||
|
*_address = (void*)((addr_t)foundAddress + (addr_t)imageInfo.text
|
||||||
|
- (addr_t)unrelocatedImageInfo.text);
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ElfImage
|
// ElfImage
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
@@ -122,6 +179,7 @@ ElfImage::GetSymbolRelocations(const char* symbolName, BList* relocations)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _SetTo
|
// _SetTo
|
||||||
status_t
|
status_t
|
||||||
ElfImage::_SetTo(image_id image)
|
ElfImage::_SetTo(image_id image)
|
||||||
@@ -133,8 +191,8 @@ ElfImage::_SetTo(image_id image)
|
|||||||
return error;
|
return error;
|
||||||
fImage = imageInfo.id;
|
fImage = imageInfo.id;
|
||||||
// get the address of global offset table
|
// get the address of global offset table
|
||||||
error = get_image_symbol(image, "_GLOBAL_OFFSET_TABLE_",
|
error = get_static_image_symbol(image, "_GLOBAL_OFFSET_TABLE_",
|
||||||
B_SYMBOL_TYPE_ANY, (void**)&fGotAddress);
|
B_SYMBOL_TYPE_ANY, (void**)&fGotAddress);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
fTextAddress = (uint8*)imageInfo.text;
|
fTextAddress = (uint8*)imageInfo.text;
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
#include "ElfFile.h"
|
#include "ElfFile.h"
|
||||||
|
|
||||||
class BList;
|
class BList;
|
||||||
|
|
||||||
|
namespace SymbolPatcher {
|
||||||
|
|
||||||
class ElfSection;
|
class ElfSection;
|
||||||
class ElfSymbol;
|
class ElfSymbol;
|
||||||
|
|
||||||
@@ -65,4 +68,9 @@ private:
|
|||||||
uint8* fGotAddress;
|
uint8* fGotAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace SymbolPatcher
|
||||||
|
|
||||||
|
using namespace SymbolPatcher;
|
||||||
|
|
||||||
|
|
||||||
#endif // ELF_IMAGE_H
|
#endif // ELF_IMAGE_H
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ ElfSymbolPatcher::Update(UpdateAdapter* updateAdapter)
|
|||||||
ElfImage* image = _ImageForID(info.id);
|
ElfImage* image = _ImageForID(info.id);
|
||||||
if (image)
|
if (image)
|
||||||
continue;
|
continue;
|
||||||
image = new(nothrow) ElfImage;
|
image = new(std::nothrow) ElfImage;
|
||||||
if (!image)
|
if (!image)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
if (!fImages.AddItem(image)) {
|
if (!fImages.AddItem(image)) {
|
||||||
@@ -398,6 +398,8 @@ ElfSymbolPatcher::GetSymbolPatchInfo(const char* symbolName,
|
|||||||
if (info->GetOriginalAddress()) {
|
if (info->GetOriginalAddress()) {
|
||||||
// A symbol with that name lives in at least two images.
|
// A symbol with that name lives in at least two images.
|
||||||
// Better bail out.
|
// Better bail out.
|
||||||
|
// TODO: That doesn't work so well (on gcc 4). E.g. the libsupc++ symbols might
|
||||||
|
// appear in several images.
|
||||||
//printf("Found the symbol in more than one image!\n");
|
//printf("Found the symbol in more than one image!\n");
|
||||||
error = B_ERROR;
|
error = B_ERROR;
|
||||||
break;
|
break;
|
||||||
@@ -441,7 +443,7 @@ ElfSymbolPatcher::_Init()
|
|||||||
image_info info;
|
image_info info;
|
||||||
int32 cookie = 0;
|
int32 cookie = 0;
|
||||||
while (get_next_image_info(0, &cookie, &info) == B_OK) {
|
while (get_next_image_info(0, &cookie, &info) == B_OK) {
|
||||||
ElfImage* image = new(nothrow) ElfImage;
|
ElfImage* image = new(std::nothrow) ElfImage;
|
||||||
if (!image)
|
if (!image)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
if (!fImages.AddItem(image)) {
|
if (!fImages.AddItem(image)) {
|
||||||
@@ -494,7 +496,7 @@ ElfSymbolPatchGroup::ElfSymbolPatchGroup(ElfSymbolPatcher* patcher)
|
|||||||
{
|
{
|
||||||
// create a patcher if none has been supplied
|
// create a patcher if none has been supplied
|
||||||
if (!fPatcher) {
|
if (!fPatcher) {
|
||||||
fPatcher = new(nothrow) ElfSymbolPatcher;
|
fPatcher = new(std::nothrow) ElfSymbolPatcher;
|
||||||
if (fPatcher) {
|
if (fPatcher) {
|
||||||
if (fPatcher->InitCheck() == B_OK)
|
if (fPatcher->InitCheck() == B_OK)
|
||||||
fOwnsPatcher = true;
|
fOwnsPatcher = true;
|
||||||
@@ -525,7 +527,7 @@ ElfSymbolPatchGroup::AddPatch(const char* symbolName, void* newAddress,
|
|||||||
if (!symbolName || !originalAddress)
|
if (!symbolName || !originalAddress)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
// allocate patch info
|
// allocate patch info
|
||||||
PatchInfo* patchInfo = new(nothrow) PatchInfo;
|
PatchInfo* patchInfo = new(std::nothrow) PatchInfo;
|
||||||
if (!patchInfo)
|
if (!patchInfo)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
// init and add the patch info
|
// init and add the patch info
|
||||||
|
|||||||
Reference in New Issue
Block a user