Added functionality for iterating through the symbols of a debugged

team's image to libdebug.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-09-15 12:47:59 +00:00
parent 0bec71008b
commit 68e6763b07
4 changed files with 185 additions and 5 deletions

View File

@ -55,6 +55,7 @@ status_t debug_get_stack_frame(debug_context *context,
// symbol lookup support
typedef struct debug_symbol_lookup_context debug_symbol_lookup_context;
typedef struct debug_symbol_iterator debug_symbol_iterator;
status_t debug_create_symbol_lookup_context(debug_context *debugContext,
debug_symbol_lookup_context **lookupContext);
@ -66,6 +67,14 @@ status_t debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
int32 symbolNameSize, char *imageName, int32 imageNameSize,
bool *exactMatch);
status_t debug_create_image_symbol_iterator(
debug_symbol_lookup_context* lookupContext, image_id imageID,
debug_symbol_iterator** _iterator);
void debug_delete_image_symbol_iterator(debug_symbol_iterator* iterator);
status_t debug_next_image_symbol(debug_symbol_iterator* iterator,
char* nameBuffer, size_t nameBufferLength, int32* _symbolType,
void** _symbolLocation, size_t* _symbolSize);
#ifdef __cplusplus
} // extern "C"

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -278,6 +278,55 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
return B_OK;
}
// InitSymbolIterator
status_t
SymbolLookup::InitSymbolIterator(image_id imageID, SymbolIterator& iterator)
{
// find the image
const image_t* image = _FindImageByID(imageID);
if (image == NULL)
return B_ENTRY_NOT_FOUND;
iterator.image = image;
iterator.symbolCount = Read(image->symhash[1]);
iterator.textDelta = image->regions->delta;
iterator.currentIndex = -1;
return B_OK;
}
// NextSymbol
status_t
SymbolLookup::NextSymbol(SymbolIterator& iterator, const char** _symbolName,
addr_t* _symbolAddress, size_t* _symbolSize, int32* _symbolType)
{
const image_t* image = iterator.image;
while (true) {
if (++iterator.currentIndex >= iterator.symbolCount)
return B_ENTRY_NOT_FOUND;
const struct Elf32_Sym* symbol = &Read(image->syms[
iterator.currentIndex]);
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|| symbol->st_value == 0) {
continue;
}
*_symbolName = SYMNAME(image, symbol);
*_symbolAddress = symbol->st_value + iterator.textDelta;
*_symbolSize = symbol->st_size;
*_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
return B_OK;
}
}
// _FindImageAtAddress
const image_t *
SymbolLookup::_FindImageAtAddress(addr_t address)
@ -297,3 +346,18 @@ SymbolLookup::_FindImageAtAddress(addr_t address)
return NULL;
}
// _FindImageByID
const image_t*
SymbolLookup::_FindImageByID(image_id id)
{
// iterate through the images
for (const image_t *image = &Read(*Read(fDebugArea->loaded_images->head));
image;
image = &Read(*image->next)) {
if (image->id == id)
return image;
}
return NULL;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -8,10 +8,12 @@
#include <stdio.h>
#include <image.h>
#include <OS.h>
#include <util/DoublyLinkedList.h>
//#define TRACE_DEBUG_SYMBOL_LOOKUP
#ifdef TRACE_DEBUG_SYMBOL_LOOKUP
# define TRACE(x) printf x
@ -19,9 +21,11 @@
# define TRACE(x) ;
#endif
struct image_t;
struct runtime_loader_debug_area;
namespace BPrivate {
// Exception
@ -43,6 +47,7 @@ private:
status_t fError;
};
// Area
class Area : public DoublyLinkedListLinkImpl<Area> {
public:
@ -81,6 +86,7 @@ private:
int32 fSize;
};
// RemoteMemoryAccessor
class RemoteMemoryAccessor {
public:
@ -111,6 +117,16 @@ private:
AreaList fAreas;
};
// SymbolIterator
struct SymbolIterator {
const image_t* image;
int32 symbolCount;
size_t textDelta;
int32 currentIndex;
};
// SymbolLookup
class SymbolLookup : private RemoteMemoryAccessor {
public:
@ -122,8 +138,13 @@ public:
status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
const char **_symbolName, const char **_imageName, bool *_exactMatch);
status_t InitSymbolIterator(image_id imageID, SymbolIterator& iterator);
status_t NextSymbol(SymbolIterator& iterator, const char** _symbolName,
addr_t* _symbolAddress, size_t* _symbolSize, int32* _symbolType);
private:
const image_t *_FindImageAtAddress(addr_t address);
const image_t *_FindImageByID(image_id id);
const runtime_loader_debug_area *fDebugArea;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -13,13 +13,19 @@
#include "arch_debug_support.h"
#include "SymbolLookup.h"
using std::nothrow;
struct debug_symbol_lookup_context {
debug_context context;
SymbolLookup *lookup;
};
struct debug_symbol_iterator : BPrivate::SymbolIterator {
debug_symbol_lookup_context* lookup_context;
};
// init_debug_context
status_t
@ -317,8 +323,8 @@ debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
const char *_symbolName;
const char *_imageName;
try {
status_t error = lookup->LookupSymbolAddress((addr_t)address, &_baseAddress,
&_symbolName, &_imageName, exactMatch);
status_t error = lookup->LookupSymbolAddress((addr_t)address,
&_baseAddress, &_symbolName, &_imageName, exactMatch);
if (error != B_OK)
return error;
} catch (BPrivate::Exception exception) {
@ -351,3 +357,83 @@ debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
return B_OK;
}
status_t
debug_create_image_symbol_iterator(debug_symbol_lookup_context* lookupContext,
image_id imageID, debug_symbol_iterator** _iterator)
{
if (!lookupContext || !lookupContext->lookup)
return B_BAD_VALUE;
SymbolLookup *lookup = lookupContext->lookup;
debug_symbol_iterator* iterator = new(std::nothrow) debug_symbol_iterator;
if (iterator == NULL)
return B_NO_MEMORY;
status_t error;
try {
error = lookup->InitSymbolIterator(imageID, *iterator);
} catch (BPrivate::Exception exception) {
error = exception.Error();
}
if (error != B_OK) {
delete iterator;
return error;
}
iterator->lookup_context = lookupContext;
*_iterator = iterator;
return B_OK;
}
void
debug_delete_image_symbol_iterator(debug_symbol_iterator* iterator)
{
delete iterator;
}
// debug_next_image_symbol
status_t
debug_next_image_symbol(debug_symbol_iterator* iterator, char* nameBuffer,
size_t nameBufferLength, int32* _symbolType, void** _symbolLocation,
size_t* _symbolSize)
{
if (iterator == NULL || iterator->lookup_context == NULL
|| iterator->lookup_context->lookup == NULL) {
return B_BAD_VALUE;
}
debug_symbol_lookup_context* lookupContext = iterator->lookup_context;
const char* symbolName;
addr_t symbolLocation;
try {
status_t error = lookupContext->lookup->NextSymbol(
*iterator, &symbolName, &symbolLocation, _symbolSize, _symbolType);
if (error != B_OK)
return error;
} catch (BPrivate::Exception exception) {
return exception.Error();
}
*_symbolLocation = (void*)symbolLocation;
// symbolName is a remote address: We read the string from the
// remote memory. The reason for not using the cloned area is that
// we don't trust that the data therein is valid (i.e. null-terminated)
// and thus strlcpy() could segfault when hitting the cloned area end.
if (symbolName != NULL) {
ssize_t sizeRead = debug_read_string(&lookupContext->context,
symbolName, nameBuffer, nameBufferLength);
if (sizeRead < 0)
return sizeRead;
} else
nameBuffer[0] = '\0';
return B_OK;
}