Darn, should have been part of r30170 already.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30173 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SharedImage.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <debug_support.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
|
SharedImage::SharedImage()
|
||||||
|
:
|
||||||
|
fSymbols(NULL),
|
||||||
|
fSymbolCount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SharedImage::~SharedImage()
|
||||||
|
{
|
||||||
|
if (fSymbols != NULL) {
|
||||||
|
for (int32 i = 0; i < fSymbolCount; i++)
|
||||||
|
delete fSymbols[i];
|
||||||
|
delete[] fSymbols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
SharedImage::Init(team_id owner, image_id imageID)
|
||||||
|
{
|
||||||
|
// we need a temporary symbol lookup context
|
||||||
|
debug_symbol_lookup_context* lookupContext;
|
||||||
|
status_t error = debug_create_symbol_lookup_context(owner, &lookupContext);
|
||||||
|
if (error != B_OK) {
|
||||||
|
fprintf(stderr, "%s: Failed to create symbol lookup context "
|
||||||
|
"for team %ld: %s\n", kCommandName, owner, strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
// TODO: Creating a symbol lookup just for loading the symbols of a single
|
||||||
|
// image is unnecessarily expensive.
|
||||||
|
|
||||||
|
// create a symbol iterator
|
||||||
|
debug_symbol_iterator* iterator;
|
||||||
|
error = debug_create_image_symbol_iterator(lookupContext, imageID,
|
||||||
|
&iterator);
|
||||||
|
if (error != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to init symbol iterator: %s\n",
|
||||||
|
strerror(error));
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init
|
||||||
|
error = _Init(iterator);
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
debug_delete_symbol_lookup_context(lookupContext);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
SharedImage::Init(const char* path)
|
||||||
|
{
|
||||||
|
// create a symbol iterator
|
||||||
|
debug_symbol_iterator* iterator;
|
||||||
|
status_t error = debug_create_file_symbol_iterator(path, &iterator);
|
||||||
|
if (error != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to init symbol iterator: %s\n",
|
||||||
|
strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = _Init(iterator);
|
||||||
|
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
SharedImage::FindSymbol(addr_t address) const
|
||||||
|
{
|
||||||
|
// binary search the function
|
||||||
|
int32 lower = 0;
|
||||||
|
int32 upper = fSymbolCount;
|
||||||
|
|
||||||
|
while (lower < upper) {
|
||||||
|
int32 mid = (lower + upper) / 2;
|
||||||
|
if (address >= fSymbols[mid]->base + fSymbols[mid]->size)
|
||||||
|
lower = mid + 1;
|
||||||
|
else
|
||||||
|
upper = mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lower == fSymbolCount)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const Symbol* symbol = fSymbols[lower];
|
||||||
|
if (address >= symbol->base && address < symbol->base + symbol->size)
|
||||||
|
return lower;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
SharedImage::_Init(debug_symbol_iterator* iterator)
|
||||||
|
{
|
||||||
|
// get an image info
|
||||||
|
status_t error = debug_get_symbol_iterator_image_info(iterator, &fInfo);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// iterate through the symbols
|
||||||
|
BObjectList<Symbol> symbols(512, true);
|
||||||
|
char symbolName[1024];
|
||||||
|
int32 symbolType;
|
||||||
|
void* symbolLocation;
|
||||||
|
size_t symbolSize;
|
||||||
|
while (debug_next_image_symbol(iterator, symbolName, sizeof(symbolName),
|
||||||
|
&symbolType, &symbolLocation, &symbolSize) == B_OK) {
|
||||||
|
// printf(" %s %p (%6lu) %s\n",
|
||||||
|
// symbolType == B_SYMBOL_TYPE_TEXT ? "text" : "data",
|
||||||
|
// symbolLocation, symbolSize, symbolName);
|
||||||
|
if (symbolSize > 0 && symbolType == B_SYMBOL_TYPE_TEXT) {
|
||||||
|
Symbol* symbol = new(std::nothrow) Symbol(this,
|
||||||
|
(addr_t)symbolLocation, symbolSize, symbolName);
|
||||||
|
if (symbol == NULL || !symbols.AddItem(symbol)) {
|
||||||
|
delete symbol;
|
||||||
|
fprintf(stderr, "%s: Out of memory\n", kCommandName);
|
||||||
|
debug_delete_symbol_iterator(iterator);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the symbols
|
||||||
|
fSymbolCount = symbols.CountItems();
|
||||||
|
fSymbols = new(std::nothrow) Symbol*[fSymbolCount];
|
||||||
|
if (fSymbols == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
for (int32 i = fSymbolCount - 1; i >= 0 ; i--)
|
||||||
|
fSymbols[i] = symbols.RemoveItemAt(i);
|
||||||
|
|
||||||
|
std::sort(fSymbols, fSymbols + fSymbolCount, SymbolComparator());
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef SHARED_IMAGE_H
|
||||||
|
#define SHARED_IMAGE_H
|
||||||
|
|
||||||
|
#include <image.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "Referenceable.h"
|
||||||
|
|
||||||
|
|
||||||
|
class debug_symbol_iterator;
|
||||||
|
class debug_symbol_lookup_context;
|
||||||
|
class SharedImage;
|
||||||
|
|
||||||
|
|
||||||
|
class Symbol {
|
||||||
|
public:
|
||||||
|
Symbol(SharedImage* image, addr_t base, size_t size, const char* name)
|
||||||
|
:
|
||||||
|
image(image),
|
||||||
|
base(base),
|
||||||
|
size(size),
|
||||||
|
name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Name() const { return name.String(); }
|
||||||
|
|
||||||
|
SharedImage* image;
|
||||||
|
addr_t base;
|
||||||
|
size_t size;
|
||||||
|
BString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SymbolComparator {
|
||||||
|
inline bool operator()(const Symbol* a, const Symbol* b) const
|
||||||
|
{
|
||||||
|
return a->base < b->base;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SharedImage : public Referenceable {
|
||||||
|
public:
|
||||||
|
SharedImage();
|
||||||
|
~SharedImage();
|
||||||
|
|
||||||
|
status_t Init(team_id owner, image_id imageID);
|
||||||
|
status_t Init(const char* path);
|
||||||
|
|
||||||
|
inline const char* Name() const;
|
||||||
|
inline const image_info& Info() const;
|
||||||
|
|
||||||
|
inline Symbol** Symbols() const;
|
||||||
|
inline int32 SymbolCount() const;
|
||||||
|
|
||||||
|
inline bool ContainsAddress(addr_t address) const;
|
||||||
|
int32 FindSymbol(addr_t address) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t _Init(debug_symbol_iterator* iterator);
|
||||||
|
|
||||||
|
private:
|
||||||
|
image_info fInfo;
|
||||||
|
Symbol** fSymbols;
|
||||||
|
int32 fSymbolCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
SharedImage::Name() const
|
||||||
|
{
|
||||||
|
return fInfo.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const image_info&
|
||||||
|
SharedImage::Info() const
|
||||||
|
{
|
||||||
|
return fInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Symbol**
|
||||||
|
SharedImage::Symbols() const
|
||||||
|
{
|
||||||
|
return fSymbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
SharedImage::SymbolCount() const
|
||||||
|
{
|
||||||
|
return fSymbolCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SharedImage::ContainsAddress(addr_t address) const
|
||||||
|
{
|
||||||
|
return address >= (addr_t)fInfo.text
|
||||||
|
&& address <= (addr_t)fInfo.data + fInfo.data_size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SHARED_IMAGE_H
|
||||||
Reference in New Issue
Block a user