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:
@@ -55,6 +55,7 @@ status_t debug_get_stack_frame(debug_context *context,
|
|||||||
// symbol lookup support
|
// symbol lookup support
|
||||||
|
|
||||||
typedef struct debug_symbol_lookup_context debug_symbol_lookup_context;
|
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,
|
status_t debug_create_symbol_lookup_context(debug_context *debugContext,
|
||||||
debug_symbol_lookup_context **lookupContext);
|
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,
|
int32 symbolNameSize, char *imageName, int32 imageNameSize,
|
||||||
bool *exactMatch);
|
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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Ingo Weinhold, [email protected].
|
* Copyright 2005-2008, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -278,6 +278,55 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
|
|||||||
return B_OK;
|
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
|
// _FindImageAtAddress
|
||||||
const image_t *
|
const image_t *
|
||||||
SymbolLookup::_FindImageAtAddress(addr_t address)
|
SymbolLookup::_FindImageAtAddress(addr_t address)
|
||||||
@@ -297,3 +346,18 @@ SymbolLookup::_FindImageAtAddress(addr_t address)
|
|||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Ingo Weinhold, [email protected].
|
* Copyright 2005-2008, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -8,10 +8,12 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <image.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_DEBUG_SYMBOL_LOOKUP
|
//#define TRACE_DEBUG_SYMBOL_LOOKUP
|
||||||
#ifdef TRACE_DEBUG_SYMBOL_LOOKUP
|
#ifdef TRACE_DEBUG_SYMBOL_LOOKUP
|
||||||
# define TRACE(x) printf x
|
# define TRACE(x) printf x
|
||||||
@@ -19,9 +21,11 @@
|
|||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct image_t;
|
struct image_t;
|
||||||
struct runtime_loader_debug_area;
|
struct runtime_loader_debug_area;
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
|
|
||||||
// Exception
|
// Exception
|
||||||
@@ -43,6 +47,7 @@ private:
|
|||||||
status_t fError;
|
status_t fError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Area
|
// Area
|
||||||
class Area : public DoublyLinkedListLinkImpl<Area> {
|
class Area : public DoublyLinkedListLinkImpl<Area> {
|
||||||
public:
|
public:
|
||||||
@@ -81,6 +86,7 @@ private:
|
|||||||
int32 fSize;
|
int32 fSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// RemoteMemoryAccessor
|
// RemoteMemoryAccessor
|
||||||
class RemoteMemoryAccessor {
|
class RemoteMemoryAccessor {
|
||||||
public:
|
public:
|
||||||
@@ -111,6 +117,16 @@ private:
|
|||||||
AreaList fAreas;
|
AreaList fAreas;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// SymbolIterator
|
||||||
|
struct SymbolIterator {
|
||||||
|
const image_t* image;
|
||||||
|
int32 symbolCount;
|
||||||
|
size_t textDelta;
|
||||||
|
int32 currentIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// SymbolLookup
|
// SymbolLookup
|
||||||
class SymbolLookup : private RemoteMemoryAccessor {
|
class SymbolLookup : private RemoteMemoryAccessor {
|
||||||
public:
|
public:
|
||||||
@@ -122,8 +138,13 @@ public:
|
|||||||
status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
|
status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
|
||||||
const char **_symbolName, const char **_imageName, bool *_exactMatch);
|
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:
|
private:
|
||||||
const image_t *_FindImageAtAddress(addr_t address);
|
const image_t *_FindImageAtAddress(addr_t address);
|
||||||
|
const image_t *_FindImageByID(image_id id);
|
||||||
|
|
||||||
const runtime_loader_debug_area *fDebugArea;
|
const runtime_loader_debug_area *fDebugArea;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Ingo Weinhold, [email protected].
|
* Copyright 2005-2008, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -13,13 +13,19 @@
|
|||||||
#include "arch_debug_support.h"
|
#include "arch_debug_support.h"
|
||||||
#include "SymbolLookup.h"
|
#include "SymbolLookup.h"
|
||||||
|
|
||||||
|
|
||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
|
|
||||||
|
|
||||||
struct debug_symbol_lookup_context {
|
struct debug_symbol_lookup_context {
|
||||||
debug_context context;
|
debug_context context;
|
||||||
SymbolLookup *lookup;
|
SymbolLookup *lookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct debug_symbol_iterator : BPrivate::SymbolIterator {
|
||||||
|
debug_symbol_lookup_context* lookup_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// init_debug_context
|
// init_debug_context
|
||||||
status_t
|
status_t
|
||||||
@@ -317,8 +323,8 @@ debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
|
|||||||
const char *_symbolName;
|
const char *_symbolName;
|
||||||
const char *_imageName;
|
const char *_imageName;
|
||||||
try {
|
try {
|
||||||
status_t error = lookup->LookupSymbolAddress((addr_t)address, &_baseAddress,
|
status_t error = lookup->LookupSymbolAddress((addr_t)address,
|
||||||
&_symbolName, &_imageName, exactMatch);
|
&_baseAddress, &_symbolName, &_imageName, exactMatch);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
} catch (BPrivate::Exception exception) {
|
} catch (BPrivate::Exception exception) {
|
||||||
@@ -351,3 +357,83 @@ debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
|
|||||||
|
|
||||||
return B_OK;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user