This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Implement dladdr() (partially)


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=c8432a01c8401c121940c806a9d868c4adc4cefd

commit c8432a01c8401c121940c806a9d868c4adc4cefd
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Mon Mar 6 18:30:45 2017 +0000

    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>

Diff:
---
 winsup/cygwin/common.din               |  1 +
 winsup/cygwin/dlfcn.cc                 | 34 ++++++++++++++++++++++++++++++++++
 winsup/cygwin/include/cygwin/version.h |  3 ++-
 winsup/cygwin/include/dlfcn.h          | 18 ++++++++++++++++++
 winsup/cygwin/release/2.7.1            |  2 ++
 winsup/doc/posix.xml                   |  4 ++++
 6 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index 6cbb012..f236813 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -364,6 +364,7 @@ difftime NOSIGFE
 dirfd SIGFE
 dirname NOSIGFE
 div NOSIGFE
+dladdr SIGFE
 dlclose SIGFE
 dlerror NOSIGFE
 dlfork NOSIGFE
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index 159d4fe..9959ff7 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -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;
+}
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 308bc8b..6023131 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -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
diff --git a/winsup/cygwin/include/dlfcn.h b/winsup/cygwin/include/dlfcn.h
index 8522ec5..d9435d0 100644
--- a/winsup/cygwin/include/dlfcn.h
+++ b/winsup/cygwin/include/dlfcn.h
@@ -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
diff --git a/winsup/cygwin/release/2.7.1 b/winsup/cygwin/release/2.7.1
index 227d7a2..43d9bd0 100644
--- a/winsup/cygwin/release/2.7.1
+++ b/winsup/cygwin/release/2.7.1
@@ -3,6 +3,8 @@ What's new:
 
 - New API: timingsafe_bcmp, timingsafe_memcmp
 
+- New API: dladdr
+
 What changed:
 -------------
 
diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml
index fac32b7..03d168d 100644
--- a/winsup/doc/posix.xml
+++ b/winsup/doc/posix.xml
@@ -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>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]