Ticket #2818: 20081011-dladdr.diff

File 20081011-dladdr.diff, 2.6 KB (added by romain, 16 years ago)
  • src/system/libroot/posix/dlfcn.c

     
    7272}
    7373
    7474
     75int
     76dladdr(void *addr, Dl_info *info)
     77{
     78    char        curSymName[NAME_MAX];
     79    static char     symName[NAME_MAX];
     80    static char     imageName[MAXPATHLEN];
     81    void    *symLocation;
     82    int32   cookie;
     83    int32   symType, symNameLength;
     84    uint32  symIndex;
     85    image_info  imageInfo;
     86
     87    if(info == NULL)
     88        return 0;
     89
     90    imageName[0] = '\0';
     91    symName[0] = '\0';
     92    info->dli_fname = imageName;
     93    info->dli_saddr = NULL;
     94    info->dli_sname = symName;
     95
     96    cookie = 0;
     97    while (get_next_image_info(0, &cookie, &imageInfo) == B_OK) {
     98        // check if the image holds the symbol
     99        if( (addr_t) addr >= (addr_t)imageInfo.text
     100            && (addr_t) addr < (addr_t)imageInfo.text + imageInfo.text_size)  {
     101            strncpy(imageName, imageInfo.name, MAXPATHLEN);
     102            imageName[MAXPATHLEN-1] = '\0';
     103            info->dli_fbase = imageInfo.text;
     104            symIndex = 0;
     105            symNameLength = NAME_MAX;
     106
     107            while(get_nth_image_symbol(imageInfo.id,
     108                symIndex, curSymName, &symNameLength,
     109                &symType, &symLocation) == B_OK) {
     110                // check if symbol is the nearest until now
     111                if(symType == B_SYMBOL_TYPE_TEXT
     112                    && symLocation <= addr
     113                    && symLocation >= info->dli_saddr) {
     114                    strncpy(symName, curSymName, NAME_MAX);
     115                    symName[NAME_MAX-1] = '\0';
     116                    info->dli_saddr = symLocation;
     117
     118                    // stop here if exact match
     119                    if(info->dli_saddr == addr)
     120                        return 1;
     121                }
     122                symIndex++;
     123                symNameLength = NAME_MAX;
     124            }
     125            break;
     126        }
     127
     128    }
     129
     130    if(info->dli_saddr != NULL)
     131        return 1;
     132    else
     133        return 0;
     134}
     135
     136
    75137// __libc_dl*** wrappers
    76138// We use a mixed glibc / bsd libc, and glibc wants these
    77139void *__libc_dlopen(const char *name);
  • headers/posix/dlfcn.h

     
    1717extern "C" {
    1818#endif
    1919
     20/* This is a gnu extension for the dladdr function */
     21typedef struct
     22{
     23   const char *dli_fname;  /* Filename of defining object */
     24   void *dli_fbase;        /* Load address of that object */
     25   const char *dli_sname;  /* Name of nearest lower symbol */
     26   void *dli_saddr;        /* Exact value of nearest symbol */
     27} Dl_info;
     28
    2029extern int  dlclose(void *image);
    2130extern char *dlerror(void);
    2231extern void *dlopen(const char *path, int mode);
    2332extern void *dlsym(void *image, const char *symbolName);
     33extern int  dladdr(void *addr, Dl_info *info);
    2434
    2535#ifdef __cplusplus
    2636}