Skip to content

Commit dfa73ee

Browse files
committed
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 - gcc-mirror/gcc@790854e - 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]>
1 parent 577d3a8 commit dfa73ee

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

exported_symbols/osv_libc.so.6.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ dirfd
8686
dirname
8787
div
8888
dl_iterate_phdr
89+
_dl_find_object
8990
dngettext
9091
dprintf
9192
drand48

include/api/__dlfcn.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef ___DLFCN_H
2+
#define ___DLFCN_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
struct dl_find_object
9+
{
10+
__extension__ unsigned long long int dlfo_flags;
11+
void *dlfo_map_start; /* Beginning of mapping containing address. */
12+
void *dlfo_map_end; /* End of mapping. */
13+
struct link_map *dlfo_link_map;
14+
void *dlfo_eh_frame; /* Exception handling data of the object. */
15+
__extension__ unsigned long long int __dflo_reserved[7];
16+
};
17+
18+
/* If ADDRESS is found in an object, fill in *RESULT and return 0.
19+
Otherwise, return -1. */
20+
int _dl_find_object (void *__address, struct dl_find_object *__result);
21+
22+
#ifdef __cplusplus
23+
}
24+
#endif
25+
26+
#endif

libc/dlfcn.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <dlfcn.h>
9+
#include <__dlfcn.h>
910
#include <osv/elf.hh>
1011
#include <link.h>
1112
#include <osv/debug.hh>
@@ -142,3 +143,22 @@ extern "C" char *dlerror(void)
142143
{
143144
return dlerror_set(nullptr);
144145
}
146+
147+
extern "C" int _dl_find_object(void *address, dl_find_object* result)
148+
{ //
149+
// Find ELF object with a mapping containing the passed in
150+
// address and if found populate the result structure as described
151+
// in http://www.gnu.org/software/libc/manual/html_node/Dynamic-Linker-Introspection.html
152+
auto eo = elf::get_program()->object_containing_addr(address);
153+
if (eo) {
154+
result->dlfo_map_start = eo->base();
155+
result->dlfo_map_end = eo->end();
156+
result->dlfo_eh_frame = eo->eh_frame_addr();
157+
//TODO: For now we are neglecting to populate the result->dlfo_link_map field
158+
//as it is not very well documented what exactly should go there. Eventually,
159+
//once we understand the purpose of this field better, we should populate it as well.
160+
return 0;
161+
} else {
162+
return -1;
163+
}
164+
}

0 commit comments

Comments
 (0)