* Implemented dladdr() in the runtime loader. This is like a gazillion times
faster than before. * This also solves a TODO in dladdr(), although I did not use get_library_symbol() as I didn't quite see how that could fit as the comment suggested; there is now a new function get_symbol_at_address() for this. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42598 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
* Copyright 2003-2011, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -33,8 +33,11 @@ struct rld_export {
|
|||||||
int32 symbolType, bool recursive, image_id *_inImage, void **_location);
|
int32 symbolType, bool recursive, image_id *_inImage, void **_location);
|
||||||
status_t (*get_library_symbol)(void* handle, void* caller,
|
status_t (*get_library_symbol)(void* handle, void* caller,
|
||||||
const char* symbolName, void **_location);
|
const char* symbolName, void **_location);
|
||||||
status_t (*get_nth_image_symbol)(image_id imageID, int32 num, char *symbolName,
|
status_t (*get_nth_image_symbol)(image_id imageID, int32 num,
|
||||||
int32 *nameLength, int32 *symbolType, void **_location);
|
char *symbolName, int32 *nameLength, int32 *symbolType,
|
||||||
|
void **_location);
|
||||||
|
status_t (*get_symbol_at_address)(void* address, image_id* _imageID,
|
||||||
|
char* nameBuffer, int32* _nameLength, int32* _type, void** _location);
|
||||||
status_t (*test_executable)(const char *path, char *interpreter);
|
status_t (*test_executable)(const char *path, char *interpreter);
|
||||||
status_t (*get_next_image_dependency)(image_id id, uint32 *cookie,
|
status_t (*get_next_image_dependency)(image_id id, uint32 *cookie,
|
||||||
const char **_name);
|
const char **_name);
|
||||||
|
|||||||
@@ -72,60 +72,31 @@ dlerror(void)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
dladdr(void *addr, Dl_info *info)
|
dladdr(void *address, Dl_info *info)
|
||||||
{
|
{
|
||||||
// TODO: This can be implemented more efficiently in the runtime loader.
|
static char sImageName[MAXPATHLEN];
|
||||||
// get_library_symbol() already has the code doing that.
|
static char sSymbolName[NAME_MAX];
|
||||||
char curSymName[NAME_MAX];
|
|
||||||
static char symName[NAME_MAX];
|
|
||||||
static char imageName[MAXPATHLEN];
|
|
||||||
void *symLocation;
|
|
||||||
int32 cookie;
|
|
||||||
int32 symType, symNameLength;
|
|
||||||
uint32 symIndex;
|
|
||||||
image_info imageInfo;
|
|
||||||
|
|
||||||
if (info == NULL)
|
image_id image;
|
||||||
|
int32 nameLength = sizeof(sSymbolName);
|
||||||
|
void* location;
|
||||||
|
image_info imageInfo;
|
||||||
|
sStatus = __gRuntimeLoader->get_symbol_at_address(address, &image,
|
||||||
|
sSymbolName, &nameLength, NULL, &location);
|
||||||
|
if (sStatus != B_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
imageName[0] = '\0';
|
sStatus = get_image_info(image, &imageInfo);
|
||||||
symName[0] = '\0';
|
if (sStatus != B_OK)
|
||||||
info->dli_fname = imageName;
|
return 0;
|
||||||
info->dli_saddr = NULL;
|
|
||||||
info->dli_sname = symName;
|
|
||||||
|
|
||||||
cookie = 0;
|
strlcpy(sImageName, imageInfo.name, MAXPATHLEN);
|
||||||
while (get_next_image_info(0, &cookie, &imageInfo) == B_OK) {
|
info->dli_fname = sImageName;
|
||||||
// check if the image holds the symbol
|
info->dli_fbase = imageInfo.text;
|
||||||
if ((addr_t)addr >= (addr_t)imageInfo.text
|
info->dli_sname = sSymbolName;
|
||||||
&& (addr_t)addr < (addr_t)imageInfo.text + imageInfo.text_size) {
|
info->dli_saddr = location;
|
||||||
strlcpy(imageName, imageInfo.name, MAXPATHLEN);
|
|
||||||
info->dli_fbase = imageInfo.text;
|
|
||||||
symIndex = 0;
|
|
||||||
symNameLength = NAME_MAX;
|
|
||||||
|
|
||||||
while (get_nth_image_symbol(imageInfo.id, symIndex, curSymName,
|
return 1;
|
||||||
&symNameLength, &symType, &symLocation) == B_OK) {
|
|
||||||
// check if symbol is the nearest until now
|
|
||||||
if (symLocation <= addr && symLocation >= info->dli_saddr) {
|
|
||||||
strlcpy(symName, curSymName, NAME_MAX);
|
|
||||||
info->dli_saddr = symLocation;
|
|
||||||
|
|
||||||
// stop here if exact match
|
|
||||||
if (info->dli_saddr == addr)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
symIndex++;
|
|
||||||
symNameLength = NAME_MAX;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->dli_saddr != NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2003-2008, Axel Dörfler, [email protected].
|
* Copyright 2003-2011, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -709,6 +709,57 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
get_symbol_at_address(void* address, image_id* _imageID, char* nameBuffer,
|
||||||
|
int32* _nameLength, int32* _type, void** _location)
|
||||||
|
{
|
||||||
|
rld_lock();
|
||||||
|
|
||||||
|
image_t* image = find_loaded_image_by_address((addr_t)address);
|
||||||
|
if (image == NULL) {
|
||||||
|
rld_unlock();
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
|
||||||
|
for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
|
||||||
|
j = HASHCHAINS(image)[j]) {
|
||||||
|
struct Elf32_Sym *symbol = &image->syms[j];
|
||||||
|
addr_t location = symbol->st_value + image->regions[0].delta;
|
||||||
|
|
||||||
|
if (location <= (addr_t)address
|
||||||
|
&& location - 1 + symbol->st_size >= (addr_t)address) {
|
||||||
|
const char* symbolName = SYMNAME(image, symbol);
|
||||||
|
strlcpy(nameBuffer, symbolName, *_nameLength);
|
||||||
|
*_nameLength = strlen(symbolName);
|
||||||
|
|
||||||
|
int32 type;
|
||||||
|
if (ELF32_ST_TYPE(symbol->st_info) == STT_FUNC)
|
||||||
|
type = B_SYMBOL_TYPE_TEXT;
|
||||||
|
else if (ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT)
|
||||||
|
type = B_SYMBOL_TYPE_DATA;
|
||||||
|
else
|
||||||
|
type = B_SYMBOL_TYPE_ANY;
|
||||||
|
// TODO: check with the return types of that BeOS function
|
||||||
|
|
||||||
|
if (_imageID != NULL)
|
||||||
|
*_imageID = image->id;
|
||||||
|
if (_type != NULL)
|
||||||
|
*_type = type;
|
||||||
|
if (_location != NULL)
|
||||||
|
*_location = (void*)location;
|
||||||
|
|
||||||
|
rld_unlock();
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rld_unlock();
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
|
get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
|
||||||
bool recursive, image_id *_inImage, void **_location)
|
bool recursive, image_id *_inImage, void **_location)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
* Copyright 2003-2011, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -51,6 +51,7 @@ struct rld_export gRuntimeLoader = {
|
|||||||
get_symbol,
|
get_symbol,
|
||||||
get_library_symbol,
|
get_library_symbol,
|
||||||
get_nth_symbol,
|
get_nth_symbol,
|
||||||
|
get_symbol_at_address,
|
||||||
test_executable,
|
test_executable,
|
||||||
get_next_image_dependency,
|
get_next_image_dependency,
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2003-2009, Axel Dörfler, [email protected].
|
* Copyright 2003-2011, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -597,6 +597,22 @@ find_loaded_image_by_id(image_id id, bool ignoreDisposable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
image_t*
|
||||||
|
find_loaded_image_by_address(addr_t address)
|
||||||
|
{
|
||||||
|
for (image_t* image = sLoadedImages.head; image; image = image->next) {
|
||||||
|
for (uint32 i = 0; i < image->num_regions; i++) {
|
||||||
|
elf_region_t& region = image->regions[i];
|
||||||
|
if (region.vmstart <= address
|
||||||
|
&& region.vmstart - 1 + region.vmsize >= address)
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_image_flags_recursively(image_t* image, uint32 flags)
|
set_image_flags_recursively(image_t* image, uint32 flags)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2003-2011, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -66,6 +66,7 @@ void dequeue_disposable_image(image_t* image);
|
|||||||
|
|
||||||
image_t* find_loaded_image_by_name(char const* name, uint32 typeMask);
|
image_t* find_loaded_image_by_name(char const* name, uint32 typeMask);
|
||||||
image_t* find_loaded_image_by_id(image_id id, bool ignoreDisposable);
|
image_t* find_loaded_image_by_id(image_id id, bool ignoreDisposable);
|
||||||
|
image_t* find_loaded_image_by_address(addr_t address);
|
||||||
|
|
||||||
void set_image_flags_recursively(image_t* image, uint32 flags);
|
void set_image_flags_recursively(image_t* image, uint32 flags);
|
||||||
void clear_image_flags_recursively(image_t* image, uint32 flags);
|
void clear_image_flags_recursively(image_t* image, uint32 flags);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2003-2011, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -65,6 +65,8 @@ image_id load_library(char const* path, uint32 flags, bool addOn,
|
|||||||
status_t unload_library(void* handle, image_id imageID, bool addOn);
|
status_t unload_library(void* handle, image_id imageID, bool addOn);
|
||||||
status_t get_nth_symbol(image_id imageID, int32 num, char* nameBuffer,
|
status_t get_nth_symbol(image_id imageID, int32 num, char* nameBuffer,
|
||||||
int32* _nameLength, int32* _type, void** _location);
|
int32* _nameLength, int32* _type, void** _location);
|
||||||
|
status_t get_symbol_at_address(void* address, image_id* _imageID,
|
||||||
|
char* nameBuffer, int32* _nameLength, int32* _type, void** _location);
|
||||||
status_t get_symbol(image_id imageID, char const* symbolName, int32 symbolType,
|
status_t get_symbol(image_id imageID, char const* symbolName, int32 symbolType,
|
||||||
bool recursive, image_id* _inImage, void** _location);
|
bool recursive, image_id* _inImage, void** _location);
|
||||||
status_t get_library_symbol(void* handle, void* caller, const char* symbolName,
|
status_t get_library_symbol(void* handle, void* caller, const char* symbolName,
|
||||||
|
|||||||
Reference in New Issue
Block a user