Implement dladdr() (partially)

Note that this always returns with dli_sname and dli_saddr set to NULL,
indicating no symbol matching addr could be found.

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
This commit is contained in:
Jon Turney 2017-03-06 18:30:45 +00:00
parent 51a993c266
commit c8432a01c8
6 changed files with 61 additions and 1 deletions

View File

@ -364,6 +364,7 @@ difftime NOSIGFE
dirfd SIGFE
dirname NOSIGFE
div NOSIGFE
dladdr SIGFE
dlclose SIGFE
dlerror NOSIGFE
dlfork NOSIGFE

View File

@ -386,3 +386,37 @@ dlerror ()
}
return res;
}
extern "C" int
dladdr (const void *addr, Dl_info *info)
{
HMODULE hModule;
BOOL ret = GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCSTR) addr,
&hModule);
if (!ret)
return 0;
/* Module handle happens to be equal to it's base load address. */
info->dli_fbase = hModule;
/* Get the module filename. This pathname may be in short-, long- or //?/
format, depending on how it was specified when loaded, but we assume this
is always an absolute pathname. */
WCHAR fname[MAX_PATH];
DWORD length = GetModuleFileNameW (hModule, fname, MAX_PATH);
if ((length == 0) || (length == MAX_PATH))
return 0;
/* Convert to a cygwin pathname */
ssize_t conv = cygwin_conv_path (CCP_WIN_W_TO_POSIX | CCP_ABSOLUTE, fname,
info->dli_fname, MAX_PATH);
if (conv)
return 0;
/* Always indicate no symbol matching addr could be found. */
info->dli_sname = NULL;
info->dli_saddr = NULL;
return 1;
}

View File

@ -472,12 +472,13 @@ details. */
305: [f]pathconf flag _PC_CASE_INSENSITIVE added.
306: Export getentropy, getrandom.
307: Export timingsafe_bcmp, timingsafe_memcmp.
308: Export dladdr.
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
sigaltstack, sethostname. */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 307
#define CYGWIN_VERSION_API_MINOR 308
/* There is also a compatibity version number associated with the shared memory
regions. It is incremented when incompatible changes are made to the shared

View File

@ -9,6 +9,9 @@ details. */
#ifndef _DLFCN_H
#define _DLFCN_H
#include <sys/cdefs.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -42,6 +45,21 @@ extern void dlfork (int);
#define RTLD_DEEPBIND 32 /* Place lookup scope so that this lib is */
/* preferred over global scope. */
#if __GNU_VISIBLE
typedef struct Dl_info Dl_info;
struct Dl_info
{
char dli_fname[PATH_MAX]; /* 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 */
};
extern int dladdr (const void *addr, Dl_info *info);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -3,6 +3,8 @@ What's new:
- New API: timingsafe_bcmp, timingsafe_memcmp
- New API: dladdr
What changed:
-------------

View File

@ -1277,6 +1277,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
clog10
clog10f
clog10l
dladdr (see chapter "Implementation Notes")
dremf
dup3
envz_add
@ -1665,6 +1666,9 @@ depending on whether _BSD_SOURCE or _GNU_SOURCE is defined when compiling.</para
<para><function>basename</function> is available in both POSIX and GNU flavors,
depending on whether libgen.h is included or not.</para>
<para><function>dladdr</function> always sets the Dl_info members dli_sname and
dli_saddr to NULL, indicating no symbol matching addr could be found.</para>
</sect1>
</chapter>