From 239222b2369c39dc52df52b0a7cdd6cc0a91bc92 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 5 Nov 2009 17:16:17 +0000 Subject: [PATCH] * 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 --- .../tools/elfsymbolpatcher/ElfSymbolPatcher.h | 8 +++ src/tools/elfsymbolpatcher/ElfFile.cpp | 6 +- src/tools/elfsymbolpatcher/ElfFile.h | 8 +++ src/tools/elfsymbolpatcher/ElfImage.cpp | 62 ++++++++++++++++++- src/tools/elfsymbolpatcher/ElfImage.h | 8 +++ .../elfsymbolpatcher/ElfSymbolPatcher.cpp | 10 +-- 6 files changed, 93 insertions(+), 9 deletions(-) diff --git a/headers/tools/elfsymbolpatcher/ElfSymbolPatcher.h b/headers/tools/elfsymbolpatcher/ElfSymbolPatcher.h index 622470e9b0..41295b8dee 100644 --- a/headers/tools/elfsymbolpatcher/ElfSymbolPatcher.h +++ b/headers/tools/elfsymbolpatcher/ElfSymbolPatcher.h @@ -39,6 +39,9 @@ #include #include + +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 diff --git a/src/tools/elfsymbolpatcher/ElfFile.cpp b/src/tools/elfsymbolpatcher/ElfFile.cpp index a8bc14852f..7c9f7e10b1 100644 --- a/src/tools/elfsymbolpatcher/ElfFile.cpp +++ b/src/tools/elfsymbolpatcher/ElfFile.cpp @@ -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 diff --git a/src/tools/elfsymbolpatcher/ElfFile.h b/src/tools/elfsymbolpatcher/ElfFile.h index b84b34b824..52fafcaa3e 100644 --- a/src/tools/elfsymbolpatcher/ElfFile.h +++ b/src/tools/elfsymbolpatcher/ElfFile.h @@ -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 diff --git a/src/tools/elfsymbolpatcher/ElfImage.cpp b/src/tools/elfsymbolpatcher/ElfImage.cpp index b1a31cbf4c..fde80ef9e6 100644 --- a/src/tools/elfsymbolpatcher/ElfImage.cpp +++ b/src/tools/elfsymbolpatcher/ElfImage.cpp @@ -33,8 +33,65 @@ #include +#include + #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; diff --git a/src/tools/elfsymbolpatcher/ElfImage.h b/src/tools/elfsymbolpatcher/ElfImage.h index 1564761784..5ff2da5651 100644 --- a/src/tools/elfsymbolpatcher/ElfImage.h +++ b/src/tools/elfsymbolpatcher/ElfImage.h @@ -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 diff --git a/src/tools/elfsymbolpatcher/ElfSymbolPatcher.cpp b/src/tools/elfsymbolpatcher/ElfSymbolPatcher.cpp index 1118b01e5c..89e20010fc 100644 --- a/src/tools/elfsymbolpatcher/ElfSymbolPatcher.cpp +++ b/src/tools/elfsymbolpatcher/ElfSymbolPatcher.cpp @@ -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