From: Waldemar Kozaczuk <[email protected]>
Committer: Waldemar Kozaczuk <[email protected]>
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/[email protected]/msg275982.html
- https://www.mail-archive.com/[email protected]/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 <[email protected]>

---
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/00000000000031bad405deeb41b8%40google.com.

Reply via email to