* 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:
Ingo Weinhold 2009-11-05 17:16:17 +00:00
parent cf5f64c103
commit 239222b236
6 changed files with 93 additions and 9 deletions

View File

@ -39,6 +39,9 @@
#include <List.h>
#include <String.h>
namespace SymbolPatcher {
class ElfImage;
class ElfSymbolPatcher;
class ElfSymbolPatchGroup;
@ -159,4 +162,9 @@ private:
bool fPatched;
};
} // namespace SymbolPatcher
using namespace SymbolPatcher;
#endif // ELF_SYMBOL_PATCHER_H

View File

@ -57,7 +57,7 @@ read_exactly(BPositionIO &file, off_t position, void *buffer, size_t size,
// ElfSection
class ElfSection {
class SymbolPatcher::ElfSection {
public:
ElfSection();
~ElfSection();
@ -671,7 +671,7 @@ ElfFile::_SetTo(const char *filename)
return B_BAD_VALUE;
}
// allocate memory for the section header table and read it
fSectionHeaders = new(nothrow) uint8[sectionHeaderTableSize];
fSectionHeaders = new(std::nothrow) uint8[sectionHeaderTableSize];
fSectionCount = sectionHeaderCount;
fSectionHeaderSize = sectionHeaderSize;
if (!fSectionHeaders)
@ -682,7 +682,7 @@ ElfFile::_SetTo(const char *filename)
if (error != B_OK)
return error;
// allocate memory for the section pointers
fSections = new(nothrow) ElfSection[fSectionCount];
fSections = new(std::nothrow) ElfSection[fSectionCount];
if (!fSections)
return B_NO_MEMORY;
// init the sections

View File

@ -34,6 +34,9 @@
#include "Elf.h"
namespace SymbolPatcher {
class ElfFile;
class ElfSection;
@ -134,4 +137,9 @@ private:
size_t fSectionHeaderSize;
};
} // namespace SymbolPatcher
using namespace SymbolPatcher;
#endif // ELF_FILE_H

View File

@ -33,8 +33,65 @@
#include <List.h>
#include <debug/debug_support.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
// constructor
@ -122,6 +179,7 @@ ElfImage::GetSymbolRelocations(const char* symbolName, BList* relocations)
return error;
}
// _SetTo
status_t
ElfImage::_SetTo(image_id image)
@ -133,8 +191,8 @@ ElfImage::_SetTo(image_id image)
return error;
fImage = imageInfo.id;
// get the address of global offset table
error = get_image_symbol(image, "_GLOBAL_OFFSET_TABLE_",
B_SYMBOL_TYPE_ANY, (void**)&fGotAddress);
error = get_static_image_symbol(image, "_GLOBAL_OFFSET_TABLE_",
B_SYMBOL_TYPE_ANY, (void**)&fGotAddress);
if (error != B_OK)
return error;
fTextAddress = (uint8*)imageInfo.text;

View File

@ -35,6 +35,9 @@
#include "ElfFile.h"
class BList;
namespace SymbolPatcher {
class ElfSection;
class ElfSymbol;
@ -65,4 +68,9 @@ private:
uint8* fGotAddress;
};
} // namespace SymbolPatcher
using namespace SymbolPatcher;
#endif // ELF_IMAGE_H

View File

@ -343,7 +343,7 @@ ElfSymbolPatcher::Update(UpdateAdapter* updateAdapter)
ElfImage* image = _ImageForID(info.id);
if (image)
continue;
image = new(nothrow) ElfImage;
image = new(std::nothrow) ElfImage;
if (!image)
return B_NO_MEMORY;
if (!fImages.AddItem(image)) {
@ -398,6 +398,8 @@ ElfSymbolPatcher::GetSymbolPatchInfo(const char* symbolName,
if (info->GetOriginalAddress()) {
// A symbol with that name lives in at least two images.
// 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");
error = B_ERROR;
break;
@ -441,7 +443,7 @@ ElfSymbolPatcher::_Init()
image_info info;
int32 cookie = 0;
while (get_next_image_info(0, &cookie, &info) == B_OK) {
ElfImage* image = new(nothrow) ElfImage;
ElfImage* image = new(std::nothrow) ElfImage;
if (!image)
return B_NO_MEMORY;
if (!fImages.AddItem(image)) {
@ -494,7 +496,7 @@ ElfSymbolPatchGroup::ElfSymbolPatchGroup(ElfSymbolPatcher* patcher)
{
// create a patcher if none has been supplied
if (!fPatcher) {
fPatcher = new(nothrow) ElfSymbolPatcher;
fPatcher = new(std::nothrow) ElfSymbolPatcher;
if (fPatcher) {
if (fPatcher->InitCheck() == B_OK)
fOwnsPatcher = true;
@ -525,7 +527,7 @@ ElfSymbolPatchGroup::AddPatch(const char* symbolName, void* newAddress,
if (!symbolName || !originalAddress)
return B_BAD_VALUE;
// allocate patch info
PatchInfo* patchInfo = new(nothrow) PatchInfo;
PatchInfo* patchInfo = new(std::nothrow) PatchInfo;
if (!patchInfo)
return B_NO_MEMORY;
// init and add the patch info