* Applied patch by Romain Picard: added support for the GNU extension dladdr(),
thanks! * This closes ticket #2818. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28308 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2d265d2a5b
commit
e2040be893
@ -1,8 +1,10 @@
|
||||
/*
|
||||
* Copyright 2003-2008, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _DLFCN_H
|
||||
#define _DLFCN_H
|
||||
/*
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -17,10 +19,19 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This is a gnu extension for the dladdr function */
|
||||
typedef struct {
|
||||
const char *dli_fname; /* Filename of defining object */
|
||||
void *dli_fbase; /* Load address of that object */
|
||||
const char *dli_sname; /* Name of nearest lower symbol */
|
||||
void *dli_saddr; /* Exact value of nearest symbol */
|
||||
} Dl_info;
|
||||
|
||||
extern int dlclose(void *image);
|
||||
extern char *dlerror(void);
|
||||
extern void *dlopen(const char *path, int mode);
|
||||
extern void *dlsym(void *image, const char *symbolName);
|
||||
extern int dladdr(void *addr, Dl_info *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||
@ -72,6 +72,64 @@ dlerror(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dladdr(void *addr, Dl_info *info)
|
||||
{
|
||||
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)
|
||||
return 0;
|
||||
|
||||
imageName[0] = '\0';
|
||||
symName[0] = '\0';
|
||||
info->dli_fname = imageName;
|
||||
info->dli_saddr = NULL;
|
||||
info->dli_sname = symName;
|
||||
|
||||
cookie = 0;
|
||||
while (get_next_image_info(0, &cookie, &imageInfo) == B_OK) {
|
||||
// check if the image holds the symbol
|
||||
if ((addr_t)addr >= (addr_t)imageInfo.text
|
||||
&& (addr_t)addr < (addr_t)imageInfo.text + imageInfo.text_size) {
|
||||
strlcpy(imageName, imageInfo.name, MAXPATHLEN);
|
||||
info->dli_fbase = imageInfo.text;
|
||||
symIndex = 0;
|
||||
symNameLength = NAME_MAX;
|
||||
|
||||
while (get_nth_image_symbol(imageInfo.id, symIndex, curSymName,
|
||||
&symNameLength, &symType, &symLocation) == B_OK) {
|
||||
// check if symbol is the nearest until now
|
||||
if (symType == B_SYMBOL_TYPE_TEXT
|
||||
&& 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;
|
||||
}
|
||||
|
||||
|
||||
// __libc_dl*** wrappers
|
||||
// We use a mixed glibc / bsd libc, and glibc wants these
|
||||
void *__libc_dlopen(const char *name);
|
||||
@ -83,8 +141,8 @@ __libc_dlopen(const char *name)
|
||||
{
|
||||
return dlopen(name, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *
|
||||
__libc_dlsym(void *handle, const char *name)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user