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-p...@gcc.gnu.org/msg275982.html
-
https://www.mail-archive.com/gcc-p...@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 <
jwkoz...@gmail.com>
---
exported_symbols/osv_libc.so.6.symbols | 1 +
include/api/__dlfcn.h | 26 ++++++++++++++++++++++++++
libc/dlfcn.cc | 20 ++++++++++++++++++++
3 files changed, 47 insertions(+)
create mode 100644 include/api/__dlfcn.h
diff --git a/exported_symbols/osv_libc.so.6.symbols b/exported_symbols/osv_libc.so.6.symbols
index 7bae56c4..7ae57c38 100644
--- 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
new file mode 100644
index 00000000..228122d1
--- /dev/null
+++ 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
index fa496e4e..8ec37148 100644
--- 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;
+ }
+}
--
2.34.1