* SymbolLookup: Implemented loading the symbol tables from the shared

object files. Thus static functions will be found, too.
* debug_lookup_symbol_address() and debug_next_image_symbol() no longer
  need to read the symbol name via the debugger API, since the
  respective SymbolLookup methods compute the length of the symbol name
  that can safely be accessed locally, now.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27628 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-09-18 22:17:11 +00:00
parent 6126236e8a
commit abb2df34ee
3 changed files with 524 additions and 115 deletions
+448 -77
View File
@@ -5,15 +5,31 @@
#include "SymbolLookup.h"
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <new>
#include <string.h>
#include <runtime_loader.h>
#undef TRACE
//#define TRACE_DEBUG_SYMBOL_LOOKUP
#ifdef TRACE_DEBUG_SYMBOL_LOOKUP
# define TRACE(x) printf x
#else
# define TRACE(x) ;
#endif
using std::nothrow;
using namespace BPrivate;
// PrepareAddress
const void *
Area::PrepareAddress(const void *address)
@@ -89,7 +105,8 @@ RemoteMemoryAccessor::Init()
// PrepareAddress
const void *
RemoteMemoryAccessor::PrepareAddress(const void *remoteAddress, int32 size)
RemoteMemoryAccessor::PrepareAddress(const void *remoteAddress,
int32 size) const
{
TRACE(("RemoteMemoryAccessor::PrepareAddress(%p, %ld)\n", remoteAddress,
size));
@@ -102,13 +119,46 @@ RemoteMemoryAccessor::PrepareAddress(const void *remoteAddress, int32 size)
return _FindArea(remoteAddress, size).PrepareAddress(remoteAddress);
}
const void *
RemoteMemoryAccessor::PrepareAddressNoThrow(const void *remoteAddress,
int32 size) const
{
if (remoteAddress == NULL)
return NULL;
Area* area = _FindAreaNoThrow(remoteAddress, size);
if (area == NULL)
return NULL;
return area->PrepareAddress(remoteAddress);
}
// AreaForLocalAddress
Area*
RemoteMemoryAccessor::AreaForLocalAddress(const void* address) const
{
if (address == NULL)
return NULL;
for (AreaList::ConstIterator it = fAreas.GetIterator(); it.HasNext();) {
Area* area = it.Next();
if (area->ContainsLocalAddress(address))
return area;
}
return NULL;
}
// _FindArea
Area &
RemoteMemoryAccessor::_FindArea(const void *address, int32 size)
RemoteMemoryAccessor::_FindArea(const void *address, int32 size) const
{
TRACE(("RemoteMemoryAccessor::_FindArea(%p, %ld)\n", address, size));
for (AreaList::Iterator it = fAreas.GetIterator(); it.HasNext();) {
for (AreaList::ConstIterator it = fAreas.GetIterator(); it.HasNext();) {
Area *area = it.Next();
if (area->ContainsAddress(address, size))
return *area;
@@ -120,20 +170,254 @@ RemoteMemoryAccessor::_FindArea(const void *address, int32 size)
}
// _FindAreaNoThrow
Area*
RemoteMemoryAccessor::_FindAreaNoThrow(const void *address, int32 size) const
{
for (AreaList::ConstIterator it = fAreas.GetIterator(); it.HasNext();) {
Area *area = it.Next();
if (area->ContainsAddress(address, size))
return area;
}
return NULL;
}
// #pragma mark -
ImageFile::ImageFile(const image_info& info)
:
fInfo(info),
fFD(-1),
fFileSize(0),
fMappedFile((uint8*)MAP_FAILED),
fLoadDelta(0),
fSymbolTable(NULL),
fStringTable(NULL),
fSymbolCount(0)
{
}
ImageFile::~ImageFile()
{
if (fMappedFile != MAP_FAILED)
munmap(fMappedFile, fFileSize);
if (fFD >= 0)
close(fFD);
}
status_t
ImageFile::Load()
{
// open and stat() the file
fFD = open(fInfo.name, O_RDONLY);
if (fFD < 0)
return errno;
struct stat st;
if (fstat(fFD, &st) < 0)
return errno;
fFileSize = st.st_size;
if (fFileSize < sizeof(Elf32_Ehdr))
return B_NOT_AN_EXECUTABLE;
// map it
fMappedFile = (uint8*)mmap(NULL, fFileSize, PROT_READ, MAP_SHARED, fFD, 0);
if (fMappedFile == MAP_FAILED)
return errno;
// examine the elf header
Elf32_Ehdr* elfHeader = (Elf32_Ehdr*)fMappedFile;
if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0)
return B_NOT_AN_EXECUTABLE;
if (elfHeader->e_ident[4] != ELFCLASS32)
return B_NOT_AN_EXECUTABLE;
// verify the location of the program headers
int32 programHeaderCount = elfHeader->e_phnum;
if (elfHeader->e_phoff < sizeof(Elf32_Ehdr)
|| elfHeader->e_phentsize < sizeof(Elf32_Phdr)
|| elfHeader->e_phoff + programHeaderCount * elfHeader->e_phentsize
> fFileSize) {
return B_NOT_AN_EXECUTABLE;
}
Elf32_Phdr* programHeaders
= (Elf32_Phdr*)(fMappedFile + elfHeader->e_phoff);
// verify the location of the section headers
int32 sectionCount = elfHeader->e_shnum;
if (elfHeader->e_shoff < sizeof(Elf32_Ehdr)
|| elfHeader->e_shentsize < sizeof(Elf32_Shdr)
|| elfHeader->e_shoff + sectionCount * elfHeader->e_shentsize
> fFileSize) {
return B_NOT_AN_EXECUTABLE;
}
Elf32_Shdr* sectionHeaders
= (Elf32_Shdr*)(fMappedFile + elfHeader->e_shoff);
// find the first segment -- we need its relative offset
for (int32 i = 0; i < programHeaderCount; i++) {
Elf32_Phdr* header = (Elf32_Phdr*)
((uint8*)programHeaders + i * elfHeader->e_phentsize);
if (header->p_type == PT_LOAD) {
fLoadDelta = (addr_t)fInfo.text - header->p_vaddr;
break;
}
}
// find the symbol table
for (int32 i = 0; i < elfHeader->e_shnum; i++) {
Elf32_Shdr* sectionHeader = (Elf32_Shdr*)
((uint8*)sectionHeaders + i * elfHeader->e_shentsize);
if (sectionHeader->sh_type == SHT_SYMTAB) {
Elf32_Shdr& stringHeader = *(Elf32_Shdr*)
((uint8*)sectionHeaders
+ sectionHeader->sh_link * elfHeader->e_shentsize);
if (stringHeader.sh_type != SHT_STRTAB)
return B_BAD_DATA;
if (sectionHeader->sh_offset + sectionHeader->sh_size > fFileSize
|| stringHeader.sh_offset + stringHeader.sh_size > fFileSize) {
return B_BAD_DATA;
}
fSymbolTable
= (const Elf32_Sym*)(fMappedFile + sectionHeader->sh_offset);
fStringTable = (const char*)(fMappedFile + stringHeader.sh_offset);
fSymbolCount = sectionHeader->sh_size / sizeof(Elf32_Sym);
return B_OK;
}
}
return B_BAD_DATA;
}
const Elf32_Sym*
ImageFile::LookupSymbol(addr_t address, addr_t* _baseAddress,
const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const
{
const Elf32_Sym* symbolFound = NULL;
const char* symbolName = NULL;
bool exactMatch = false;
addr_t deltaFound = ~(addr_t)0;
for (int32 i = 0; i < fSymbolCount; i++) {
const Elf32_Sym* symbol = &fSymbolTable[i];
if (symbol->st_value == 0
|| symbol->st_size >= (size_t)fInfo.text_size + fInfo.data_size) {
continue;
}
addr_t symbolAddress = symbol->st_value + fLoadDelta;
if (symbolAddress > address)
continue;
addr_t symbolDelta = address - symbolAddress;
if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
exactMatch = true;
if (exactMatch || symbolDelta < deltaFound) {
deltaFound = symbolDelta;
symbolFound = symbol;
symbolName = fStringTable + symbol->st_name;
if (exactMatch)
break;
}
}
if (symbolFound != NULL) {
if (_baseAddress != NULL)
*_baseAddress = symbolFound->st_value + fLoadDelta;
if (_symbolName != NULL)
*_symbolName = symbolName;
if (_exactMatch != NULL)
*_exactMatch = exactMatch;
if (_symbolNameLen != NULL)
*_symbolNameLen = _SymbolNameLen(symbolName);
}
return symbolFound;
}
status_t
ImageFile::NextSymbol(int32& iterator, const char** _symbolName,
size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize,
int32* _symbolType) const
{
while (true) {
if (++iterator >= fSymbolCount)
return B_ENTRY_NOT_FOUND;
const Elf32_Sym* symbol = &fSymbolTable[iterator];
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|| symbol->st_value == 0) {
continue;
}
*_symbolName = fStringTable + symbol->st_name;
*_symbolNameLen = _SymbolNameLen(*_symbolName);
*_symbolAddress = symbol->st_value + fLoadDelta;
*_symbolSize = symbol->st_size;
*_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
return B_OK;
}
}
size_t
ImageFile::_SymbolNameLen(const char* symbolName) const
{
if (symbolName == NULL || (addr_t)symbolName < (addr_t)fStringTable
|| (addr_t)symbolName >= (addr_t)fMappedFile + fFileSize) {
return 0;
}
return strnlen(symbolName,
(addr_t)fMappedFile + fFileSize - (addr_t)symbolName);
}
// #pragma mark -
// constructor
SymbolLookup::SymbolLookup(team_id team)
: RemoteMemoryAccessor(team),
fDebugArea(NULL)
:
RemoteMemoryAccessor(team),
fDebugArea(NULL),
fImageFiles()
{
}
// destructor
SymbolLookup::~SymbolLookup()
{
while (ImageFile* imageFile = fImageFiles.RemoveHead())
delete imageFile;
}
// Init
status_t
SymbolLookup::Init()
@@ -170,29 +454,47 @@ SymbolLookup::Init()
TRACE(("SymbolLookup::Init(): translated debug area is at: %p, "
"loaded_images: %p\n", fDebugArea, fDebugArea->loaded_images));
} catch (Exception exception) {
return exception.Error();
}
// create a list of the team's images
image_info imageInfo;
cookie = 0;
while (get_next_image_info(fTeam, &cookie, &imageInfo) == B_OK) {
ImageFile* imageFile = new(std::nothrow) ImageFile(imageInfo);
if (imageFile == NULL)
break;
if (imageFile->Load() != B_OK)
delete imageFile;
fImageFiles.Add(imageFile);
}
return B_OK;
}
// LookupSymbolAddress
status_t
SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
const char **_symbolName, const char **_imageName, bool *_exactMatch)
const char **_symbolName, size_t *_symbolNameLen, const char **_imageName,
bool *_exactMatch) const
{
// Note, that this function doesn't find all symbols that we would like
// to find. E.g. static functions do not appear in the symbol table
// as function symbols, but as sections without name and size. The .symtab
// section together with the .strtab section, which apparently differ from
// the tables referred to by the .dynamic section, also contain proper names
// and sizes for those symbols. Therefore, to get completely satisfying
// results, we would need to read those tables from the shared object.
TRACE(("SymbolLookup::LookupSymbolAddress(%p)\n", (void*)address));
// Try the loaded image file first -- it also contains static symbols.
ImageFile* imageFile = _FindImageFileAtAddress(address);
if (imageFile != NULL) {
if (_imageName != NULL)
*_imageName = imageFile->Info().name;
const Elf32_Sym* symbol = imageFile->LookupSymbol(address, _baseAddress,
_symbolName, _symbolNameLen, _exactMatch);
if (symbol != NULL)
return B_OK;
}
// get the image for the address
const image_t *image = _FindImageAtAddress(address);
if (!image)
@@ -206,52 +508,49 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
const struct Elf32_Sym *symbolFound = NULL;
addr_t deltaFound = INT_MAX;
bool exactMatch = false;
const char *symbolName = NULL; // remote
const char *symbolName = NULL;
int32 hashTabSize = Read(image->symhash[0]);
const uint32 *hashBuckets = image->symhash + 2; // remote
const uint32 *hashChains = image->symhash + 2 + hashTabSize; // remote
int32 symbolCount = Read(image->symhash[1]);
const elf_region_t *textRegion = image->regions; // local
for (int32 i = 0; i < hashTabSize; i++) {
for (int32 j = Read(hashBuckets[i]);
j != STN_UNDEF;
j = Read(hashChains[j])) {
for (int32 i = 0; i < symbolCount; i++) {
const struct Elf32_Sym *symbol = &Read(image->syms[i]);
const struct Elf32_Sym *symbol = &Read(image->syms[j]);
// The symbol table contains not only symbols referring to functions
// and data symbols within the shared object, but also referenced
// symbols of other shared objects, as well as section and file
// references. We ignore everything but function and data symbols
// that have an st_value != 0 (0 seems to be an indication for a
// symbol defined elsewhere -- couldn't verify that in the specs
// though).
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|| symbol->st_value == 0
|| symbol->st_value + symbol->st_size + textRegion->delta
> textRegion->vmstart + textRegion->size) {
continue;
}
// The symbol table contains not only symbols referring to functions
// and data symbols within the shared object, but also referenced
// symbols of other shared objects, as well as section and file
// references. We ignore everything but function and data symbols
// that have an st_value != 0 (0 seems to be an indication for a
// symbol defined elsewhere -- couldn't verify that in the specs
// though).
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|| symbol->st_value == 0
|| symbol->st_value + symbol->st_size + textRegion->delta
> textRegion->vmstart + textRegion->size) {
// skip symbols starting after the given address
addr_t symbolAddress = symbol->st_value + textRegion->delta;
if (symbolAddress > address)
continue;
addr_t symbolDelta = address - symbolAddress;
if (!symbolFound || symbolDelta < deltaFound) {
symbolName = (const char*)PrepareAddressNoThrow(SYMNAME(image,
symbol), 1);
if (symbolName == NULL)
continue;
}
// skip symbols starting after the given address
addr_t symbolAddress = symbol->st_value + textRegion->delta;
deltaFound = symbolDelta;
symbolFound = symbol;
if (symbolAddress > address)
continue;
addr_t symbolDelta = address - symbolAddress;
if (!symbolFound || symbolDelta < deltaFound) {
deltaFound = symbolDelta;
symbolFound = symbol;
symbolName = SYMNAME(image, symbol);
if (symbolDelta >= 0 && symbolDelta < symbol->st_size) {
// exact match
exactMatch = true;
break;
}
if (symbolDelta >= 0 && symbolDelta < symbol->st_size) {
// exact match
exactMatch = true;
break;
}
}
}
@@ -275,26 +574,37 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
if (_exactMatch)
*_exactMatch = exactMatch;
if (_symbolNameLen != NULL)
*_symbolNameLen = _SymbolNameLen(symbolName);
return B_OK;
}
// InitSymbolIterator
status_t
SymbolLookup::InitSymbolIterator(image_id imageID, SymbolIterator& iterator)
SymbolLookup::InitSymbolIterator(image_id imageID,
SymbolIterator& iterator) const
{
TRACE(("SymbolLookup::InitSymbolIterator(): image ID: %ld\n", imageID));
// find the image
const image_t* image = _FindImageByID(imageID);
if (image == NULL) {
TRACE(("SymbolLookup::InitSymbolIterator() done: image not found\n"));
return B_ENTRY_NOT_FOUND;
// find the image file
iterator.imageFile = _FindImageFileByID(imageID);
// If that didn't work, find the image.
if (iterator.imageFile == NULL) {
const image_t* image = _FindImageByID(imageID);
if (image == NULL) {
TRACE(("SymbolLookup::InitSymbolIterator() done: image not "
"found\n"));
return B_ENTRY_NOT_FOUND;
}
iterator.image = image;
iterator.symbolCount = Read(image->symhash[1]);
iterator.textDelta = image->regions->delta;
}
iterator.image = image;
iterator.symbolCount = Read(image->symhash[1]);
iterator.textDelta = image->regions->delta;
iterator.currentIndex = -1;
return B_OK;
@@ -304,22 +614,28 @@ SymbolLookup::InitSymbolIterator(image_id imageID, SymbolIterator& iterator)
// InitSymbolIterator
status_t
SymbolLookup::InitSymbolIteratorByAddress(addr_t address,
SymbolIterator& iterator)
SymbolIterator& iterator) const
{
TRACE(("SymbolLookup::InitSymbolIteratorByAddress(): base address: %#lx\n",
address));
// find the image
const image_t *image = _FindImageAtAddress(address);
if (image == NULL) {
TRACE(("SymbolLookup::InitSymbolIteratorByAddress() done: image not "
"found\n"));
return B_ENTRY_NOT_FOUND;
// find the image file
iterator.imageFile = _FindImageFileAtAddress(address);
// If that didn't work, find the image.
if (iterator.imageFile == NULL) {
const image_t *image = _FindImageAtAddress(address);
if (image == NULL) {
TRACE(("SymbolLookup::InitSymbolIteratorByAddress() done: image "
"not found\n"));
return B_ENTRY_NOT_FOUND;
}
iterator.image = image;
iterator.symbolCount = Read(image->symhash[1]);
iterator.textDelta = image->regions->delta;
}
iterator.image = image;
iterator.symbolCount = Read(image->symhash[1]);
iterator.textDelta = image->regions->delta;
iterator.currentIndex = -1;
return B_OK;
@@ -329,8 +645,17 @@ SymbolLookup::InitSymbolIteratorByAddress(addr_t address,
// NextSymbol
status_t
SymbolLookup::NextSymbol(SymbolIterator& iterator, const char** _symbolName,
addr_t* _symbolAddress, size_t* _symbolSize, int32* _symbolType)
size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize,
int32* _symbolType) const
{
// If we have an image file, get the next symbol from it.
const ImageFile* imageFile = iterator.imageFile;
if (imageFile != NULL) {
return imageFile->NextSymbol(iterator.currentIndex, _symbolName,
_symbolNameLen, _symbolAddress, _symbolSize, _symbolType);
}
// Otherwise we've to fall be to iterating through the image.
const image_t* image = iterator.image;
while (true) {
@@ -345,7 +670,9 @@ SymbolLookup::NextSymbol(SymbolIterator& iterator, const char** _symbolName,
continue;
}
*_symbolName = SYMNAME(image, symbol);
*_symbolName = (const char*)PrepareAddressNoThrow(SYMNAME(image,
symbol), 1);
*_symbolNameLen = _SymbolNameLen(*_symbolName);
*_symbolAddress = symbol->st_value + iterator.textDelta;
*_symbolSize = symbol->st_size;
*_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
@@ -358,7 +685,7 @@ SymbolLookup::NextSymbol(SymbolIterator& iterator, const char** _symbolName,
// _FindImageAtAddress
const image_t *
SymbolLookup::_FindImageAtAddress(addr_t address)
SymbolLookup::_FindImageAtAddress(addr_t address) const
{
TRACE(("SymbolLookup::_FindImageAtAddress(%p)\n", (void*)address));
@@ -378,7 +705,7 @@ SymbolLookup::_FindImageAtAddress(addr_t address)
// _FindImageByID
const image_t*
SymbolLookup::_FindImageByID(image_id id)
SymbolLookup::_FindImageByID(image_id id) const
{
// iterate through the images
for (const image_t *image = &Read(*Read(fDebugArea->loaded_images->head));
@@ -390,3 +717,47 @@ SymbolLookup::_FindImageByID(image_id id)
return NULL;
}
// _FindImageFileAtAddress
ImageFile*
SymbolLookup::_FindImageFileAtAddress(addr_t address) const
{
DoublyLinkedList<ImageFile>::ConstIterator it = fImageFiles.GetIterator();
while (ImageFile* imageFile = it.Next()) {
const image_info& info = imageFile->Info();
if (address >= (addr_t)info.text
&& address < (addr_t)info.text + info.text_size) {
return imageFile;
}
}
return NULL;
}
// _FindImageFileByID
ImageFile*
SymbolLookup::_FindImageFileByID(image_id id) const
{
DoublyLinkedList<ImageFile>::ConstIterator it = fImageFiles.GetIterator();
while (ImageFile* imageFile = it.Next()) {
if (imageFile->Info().id == id)
return imageFile;
}
return NULL;
}
// _SymbolNameLen
size_t
SymbolLookup::_SymbolNameLen(const char* address) const
{
Area* area = AreaForLocalAddress(address);
if (area == NULL)
return 0;
return strnlen(address, (addr_t)area->LocalAddress() + area->Size()
- (addr_t)address);
}
+63 -17
View File
@@ -14,16 +14,9 @@
#include <util/DoublyLinkedList.h>
//#define TRACE_DEBUG_SYMBOL_LOOKUP
#ifdef TRACE_DEBUG_SYMBOL_LOOKUP
# define TRACE(x) printf x
#else
# define TRACE(x) ;
#endif
struct image_t;
struct runtime_loader_debug_area;
struct Elf32_Sym;
namespace BPrivate {
@@ -76,6 +69,12 @@ public:
&& (addr_t)address + size <= (addr_t)fRemoteAddress + fSize);
}
bool ContainsLocalAddress(const void* address) const
{
return (addr_t)address >= (addr_t)fLocalAddress
&& (addr_t)address < (addr_t)fLocalAddress + fSize;
}
const void *PrepareAddress(const void *address);
private:
@@ -95,9 +94,12 @@ public:
status_t Init();
const void *PrepareAddress(const void *remoteAddress, int32 size);
const void *PrepareAddress(const void *remoteAddress, int32 size) const;
const void *PrepareAddressNoThrow(const void *remoteAddress,
int32 size) const;
template<typename Type> inline const Type &Read(const Type &remoteData)
template<typename Type> inline const Type &Read(
const Type &remoteData) const
{
const void *remoteAddress = &remoteData;
const void *localAddress = PrepareAddress(remoteAddress,
@@ -105,8 +107,11 @@ public:
return *(const Type*)localAddress;
}
Area* AreaForLocalAddress(const void* address) const;
private:
Area &_FindArea(const void *address, int32 size);
Area &_FindArea(const void *address, int32 size) const;
Area* _FindAreaNoThrow(const void *address, int32 size) const;
typedef DoublyLinkedList<Area> AreaList;
@@ -118,9 +123,42 @@ private:
};
// ImageFile
class ImageFile : public DoublyLinkedListLinkImpl<ImageFile> {
public:
ImageFile(const image_info& info);
~ImageFile();
const image_info& Info() const { return fInfo; }
status_t Load();
const Elf32_Sym* LookupSymbol(addr_t address, addr_t* _baseAddress,
const char** _symbolName, size_t *_symbolNameLen,
bool *_exactMatch) const;
status_t NextSymbol(int32& iterator, const char** _symbolName,
size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize,
int32* _symbolType) const;
private:
size_t _SymbolNameLen(const char* symbolName) const;
private:
image_info fInfo;
int fFD;
off_t fFileSize;
uint8* fMappedFile;
addr_t fLoadDelta;
const Elf32_Sym* fSymbolTable;
const char* fStringTable;
int32 fSymbolCount;
};
// SymbolIterator
struct SymbolIterator {
const image_t* image;
const ImageFile* imageFile;
int32 symbolCount;
size_t textDelta;
int32 currentIndex;
@@ -136,19 +174,27 @@ public:
status_t Init();
status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
const char **_symbolName, const char **_imageName, bool *_exactMatch);
const char **_symbolName, size_t *_symbolNameLen,
const char **_imageName, bool *_exactMatch) const;
status_t InitSymbolIterator(image_id imageID, SymbolIterator& iterator);
status_t InitSymbolIterator(image_id imageID,
SymbolIterator& iterator) const;
status_t InitSymbolIteratorByAddress(addr_t address,
SymbolIterator& iterator);
SymbolIterator& iterator) const;
status_t NextSymbol(SymbolIterator& iterator, const char** _symbolName,
addr_t* _symbolAddress, size_t* _symbolSize, int32* _symbolType);
size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize,
int32* _symbolType) const;
private:
const image_t *_FindImageAtAddress(addr_t address);
const image_t *_FindImageByID(image_id id);
const image_t *_FindImageAtAddress(addr_t address) const;
const image_t *_FindImageByID(image_id id) const;
ImageFile* _FindImageFileAtAddress(addr_t address) const;
ImageFile* _FindImageFileByID(image_id id) const;
size_t _SymbolNameLen(const char* address) const;
private:
const runtime_loader_debug_area *fDebugArea;
DoublyLinkedList<ImageFile> fImageFiles;
};
} // namespace BPrivate
+13 -21
View File
@@ -321,10 +321,12 @@ debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
// find the symbol
addr_t _baseAddress;
const char *_symbolName;
size_t _symbolNameLen;
const char *_imageName;
try {
status_t error = lookup->LookupSymbolAddress((addr_t)address,
&_baseAddress, &_symbolName, &_imageName, exactMatch);
&_baseAddress, &_symbolName, &_symbolNameLen, &_imageName,
exactMatch);
if (error != B_OK)
return error;
} catch (BPrivate::Exception exception) {
@@ -336,15 +338,9 @@ debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext,
*baseAddress = (void*)_baseAddress;
if (symbolName && symbolNameSize > 0) {
// _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) {
ssize_t sizeRead = debug_read_string(&lookupContext->context,
_symbolName, symbolName, symbolNameSize);
if (sizeRead < 0)
return sizeRead;
if (_symbolName && _symbolNameLen > 0) {
strlcpy(symbolName, _symbolName,
min_c((size_t)symbolNameSize, _symbolNameLen + 1));
} else
symbolName[0] = '\0';
}
@@ -430,11 +426,13 @@ debug_next_image_symbol(debug_symbol_iterator* iterator, char* nameBuffer,
debug_symbol_lookup_context* lookupContext = iterator->lookup_context;
const char* symbolName;
size_t symbolNameLen;
addr_t symbolLocation;
try {
status_t error = lookupContext->lookup->NextSymbol(
*iterator, &symbolName, &symbolLocation, _symbolSize, _symbolType);
status_t error = lookupContext->lookup->NextSymbol(*iterator,
&symbolName, &symbolNameLen, &symbolLocation, _symbolSize,
_symbolType);
if (error != B_OK)
return error;
} catch (BPrivate::Exception exception) {
@@ -443,15 +441,9 @@ debug_next_image_symbol(debug_symbol_iterator* iterator, char* nameBuffer,
*_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;
if (symbolName != NULL && symbolNameLen > 0) {
strlcpy(nameBuffer, symbolName,
min_c(nameBufferLength, symbolNameLen + 1));
} else
nameBuffer[0] = '\0';