From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Waldemar Kozaczuk <jwkozac...@gmail.com>
Branch: master

libc: implement _dl_find_object()

Ubuntu 2022.04 comes with a new version of GCC 11.2.0 that
somehow includes instance of libgcc_s.so.1 destined for GCC_12.0.0
at least based on what readelf shows. The implication of this is
that during exception handling and stack unwinding, this version
of libgcc_so.so.1 uses _dl_find_object() function what was
very recently added to glibc. For more details please read
following:
- https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg275982.html
- https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg273082.html
- 
https://github.com/gcc-mirror/gcc/commit/790854ea7670f11c14d431c102a49181d2915965
- 
http://www.gnu.org/software/libc/manual/html_node/Dynamic-Linker-Introspection.html

So this patch adds basic (a little incomplete) implementation of 
_dl_find_object()
that can satisfy the need of new libgcc_s.so.1 - field dlfo_eh_frame of the 
struct
dl_find_object. Please note that for now we do not populate the dlfo_link_map 
field
as it is not clear what exactly goes it there and how it is used. We may need to
revisit this later.

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>

---
diff --git a/exported_symbols/osv_libc.so.6.symbols 
b/exported_symbols/osv_libc.so.6.symbols
--- a/exported_symbols/osv_libc.so.6.symbols
+++ b/exported_symbols/osv_libc.so.6.symbols
@@ -86,6 +86,7 @@ dirfd
 dirname
 div
 dl_iterate_phdr
+_dl_find_object
 dngettext
 dprintf
 drand48
diff --git a/include/api/__dlfcn.h b/include/api/__dlfcn.h
--- a/include/api/__dlfcn.h
+++ b/include/api/__dlfcn.h
@@ -0,0 +1,26 @@
+#ifndef        ___DLFCN_H
+#define        ___DLFCN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dl_find_object
+{
+  __extension__ unsigned long long int dlfo_flags;
+  void *dlfo_map_start;                /* Beginning of mapping containing 
address.  */
+  void *dlfo_map_end;          /* End of mapping.  */
+  struct link_map *dlfo_link_map;
+  void *dlfo_eh_frame;         /* Exception handling data of the object.  */
+  __extension__ unsigned long long int __dflo_reserved[7];
+};
+
+/* If ADDRESS is found in an object, fill in *RESULT and return 0.
+   Otherwise, return -1.  */
+int _dl_find_object (void *__address, struct dl_find_object *__result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libc/dlfcn.cc b/libc/dlfcn.cc
--- a/libc/dlfcn.cc
+++ b/libc/dlfcn.cc
@@ -6,6 +6,7 @@
  */
 
 #include <dlfcn.h>
+#include <__dlfcn.h>
 #include <osv/elf.hh>
 #include <link.h>
 #include <osv/debug.hh>
@@ -142,3 +143,22 @@ extern "C" char *dlerror(void)
 {
     return dlerror_set(nullptr);
 }
+
+extern "C" int _dl_find_object(void *address, dl_find_object* result)
+{   //
+    // Find ELF object with a mapping containing the passed in
+    // address and if found populate the result structure as described
+    // in 
http://www.gnu.org/software/libc/manual/html_node/Dynamic-Linker-Introspection.html
+    auto eo = elf::get_program()->object_containing_addr(address);
+    if (eo) {
+        result->dlfo_map_start = eo->base();
+        result->dlfo_map_end = eo->end();
+        result->dlfo_eh_frame = eo->eh_frame_addr();
+        //TODO: For now we are neglecting to populate the 
result->dlfo_link_map field
+        //as it is not very well documented what exactly should go there. 
Eventually,
+        //once we understand the purpose of this field better, we should 
populate it as well.
+      return 0;
+   } else {
+      return -1;
+   }
+}

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/00000000000031bad405deeb41b8%40google.com.

Reply via email to