aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/lib
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2021-10-04 10:24:35 +0200
committerMarkus Metzger <markus.t.metzger@intel.com>2022-10-18 14:16:08 +0200
commit8d56636a0ecbe6c38bf52b0683326ee21693c548 (patch)
treed31ea425eab963a5849039435427ea2880dba1c2 /gdb/testsuite/lib
parent60d09f0a0d8000359b8f1dd14b51e7f013ea9e5c (diff)
downloadgdb-8d56636a0ecbe6c38bf52b0683326ee21693c548.zip
gdb-8d56636a0ecbe6c38bf52b0683326ee21693c548.tar.gz
gdb-8d56636a0ecbe6c38bf52b0683326ee21693c548.tar.bz2
gdb, gdbserver: support dlmopen()
In glibc, the r_debug structure contains (amongst others) the following fields: int r_version: Version number for this protocol. It should be greater than 0. If r_version is 2, struct r_debug is extended to struct r_debug_extended with one additional field: struct r_debug_extended *r_next; Link to the next r_debug_extended structure. Each r_debug_extended structure represents a different namespace. The first r_debug_extended structure is for the default namespace. 1. Change solib_svr4_r_map argument to take the debug base. 2. Add solib_svr4_r_next to find the link map in the next namespace from the r_next field. 3. Update svr4_current_sos_direct to get the link map in the next namespace from the r_next field. 4. Don't check shared libraries in other namespaces when updating shared libraries in a new namespace. 5. Update svr4_same to check the load offset in addition to the name 6. Update svr4_default_sos to also set l_addr_inferior 7. Change the flat solib_list into a per-namespace list using the namespace's r_debug address to identify the namespace. Add gdb.base/dlmopen.exp to test this. To remain backwards compatible with older gdbserver, we reserve the namespace zero for a flat list of solibs from all namespaces. Subsequent patches will extend RSP to allow listing libraries grouped by namespace. This fixes PR 11839. Co-authored-by: Lu, Hongjiu <hongjiu.lu@intel.com>
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r--gdb/testsuite/lib/gdb.exp96
1 files changed, 96 insertions, 0 deletions
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 36bcfac..c510ab2 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -2512,6 +2512,102 @@ proc skip_shlib_tests {} {
return 1
}
+# Return 1 if we should skip dlmopen tests, 0 if we should not.
+
+gdb_caching_proc skip_dlmopen_tests {
+ global srcdir subdir gdb_prompt inferior_exited_re
+
+ # We need shared library support.
+ if { [skip_shlib_tests] } {
+ return 1
+ }
+
+ set me "skip_dlmopen_tests"
+ set lib {
+ int foo (void) {
+ return 42;
+ }
+ }
+ set src {
+ #define _GNU_SOURCE
+ #include <dlfcn.h>
+ #include <link.h>
+ #include <stdio.h>
+ #include <errno.h>
+
+ int main (void) {
+ struct r_debug *r_debug;
+ ElfW(Dyn) *dyn;
+ void *handle;
+
+ /* The version is kept at 1 until we create a new namespace. */
+ handle = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
+ if (!handle) {
+ printf ("dlmopen failed: %s.\n", dlerror ());
+ return 1;
+ }
+
+ r_debug = 0;
+ /* Taken from /usr/include/link.h. */
+ for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
+ if (dyn->d_tag == DT_DEBUG)
+ r_debug = (struct r_debug *) dyn->d_un.d_ptr;
+
+ if (!r_debug) {
+ printf ("r_debug not found.\n");
+ return 1;
+ }
+ if (r_debug->r_version < 2) {
+ printf ("dlmopen debug not supported.\n");
+ return 1;
+ }
+ printf ("dlmopen debug supported.\n");
+ return 0;
+ }
+ }
+
+ set libsrc [standard_temp_file "libfoo.c"]
+ set libout [standard_temp_file "libfoo.so"]
+ gdb_produce_source $libsrc $lib
+
+ if { [gdb_compile_shlib $libsrc $libout {debug}] != "" } {
+ verbose -log "failed to build library"
+ return 1
+ }
+ if { ![gdb_simple_compile $me $src executable \
+ [list shlib_load debug \
+ additional_flags=-DDSO_NAME=\"$libout\"]] } {
+ verbose -log "failed to build executable"
+ return 1
+ }
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $obj
+
+ if { [gdb_run_cmd] != 0 } {
+ verbose -log "failed to start skip test"
+ return 1
+ }
+ gdb_expect {
+ -re "$inferior_exited_re normally.*${gdb_prompt} $" {
+ set skip_dlmopen_tests 0
+ }
+ -re "$inferior_exited_re with code.*${gdb_prompt} $" {
+ set skip_dlmopen_tests 1
+ }
+ default {
+ warning "\n$me: default case taken"
+ set skip_dlmopen_tests 1
+ }
+ }
+ gdb_exit
+
+ verbose "$me: returning $skip_dlmopen_tests" 2
+ return $skip_dlmopen_tests
+}
+
# Return 1 if we should skip tui related tests.
proc skip_tui_tests {} {