Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/libexec/ld.elf_so Add new RTLD test file for r_debug



details:   https://anonhg.NetBSD.org/src/rev/5a9a4e1ad438
branches:  trunk
changeset: 938960:5a9a4e1ad438
user:      kamil <kamil%NetBSD.org@localhost>
date:      Tue Sep 22 01:09:32 2020 +0000

description:
Add new RTLD test file for r_debug

New tests:
 - self
 - dlopen

Both check whether the r_debug structure seems to be well-formed, without
and with a dlopen(3) call.

diffstat:

 distrib/sets/lists/debug/mi              |    3 +-
 distrib/sets/lists/tests/mi              |    3 +-
 tests/libexec/ld.elf_so/Makefile         |    5 +-
 tests/libexec/ld.elf_so/t_rtld_r_debug.c |  164 +++++++++++++++++++++++++++++++
 4 files changed, 172 insertions(+), 3 deletions(-)

diffs (221 lines):

diff -r 67d7c9a90c9e -r 5a9a4e1ad438 distrib/sets/lists/debug/mi
--- a/distrib/sets/lists/debug/mi       Tue Sep 22 00:55:08 2020 +0000
+++ b/distrib/sets/lists/debug/mi       Tue Sep 22 01:09:32 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.337 2020/09/15 07:00:04 mrg Exp $
+# $NetBSD: mi,v 1.338 2020/09/22 01:09:32 kamil Exp $
 ./etc/mtree/set.debug                           comp-sys-root
 ./usr/lib                                      comp-sys-usr            compatdir
 ./usr/lib/i18n/libBIG5_g.a                     comp-c-debuglib         debuglib,compatfile
@@ -2359,6 +2359,7 @@
 ./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-false.debug  tests-libexec-debug     debug,atf,pic,compattestfile
 ./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlinfo.debug         tests-libexec-debug     debug,atf,pic,compattestfile
 ./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlvsym.debug         tests-libexec-debug     debug,atf,pic,compattestfile
+./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_rtld_r_debug.debug   tests-libexec-debug     debug,atf,pic,compattestfile
 ./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_ifunc.debug  tests-libexec-debug     debug,atf,pic,compattestfile
 ./usr/libdata/debug/usr/tests/modules/k_helper3.debug  tests-sys-debug         debug,atf,rump
 ./usr/libdata/debug/usr/tests/modules/t_builtin.debug  tests-sys-debug         debug,atf,rump
diff -r 67d7c9a90c9e -r 5a9a4e1ad438 distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi       Tue Sep 22 00:55:08 2020 +0000
+++ b/distrib/sets/lists/tests/mi       Tue Sep 22 01:09:32 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.924 2020/09/14 06:44:50 rillig Exp $
+# $NetBSD: mi,v 1.925 2020/09/22 01:09:33 kamil Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -3768,6 +3768,7 @@
 ./usr/tests/libexec/ld.elf_so/t_dlinfo                 tests-libexec-tests     compattestfile,atf,pic
 ./usr/tests/libexec/ld.elf_so/t_dlvsym                 tests-libexec-tests     compattestfile,atf,pic
 ./usr/tests/libexec/ld.elf_so/t_ifunc                  tests-libexec-tests     compattestfile,atf,pic
+./usr/tests/libexec/ld.elf_so/t_rtld_r_debug           tests-libexec-tests     compattestfile,atf,pic
 ./usr/tests/libexec/ld.elf_so/t_thread_local_dtor      tests-libexec-tests     compattestfile,atf,pic
 ./usr/tests/modules                                    tests-sys-tests         compattestfile,atf
 ./usr/tests/net                                                tests-net-tests         compattestfile,atf
diff -r 67d7c9a90c9e -r 5a9a4e1ad438 tests/libexec/ld.elf_so/Makefile
--- a/tests/libexec/ld.elf_so/Makefile  Tue Sep 22 00:55:08 2020 +0000
+++ b/tests/libexec/ld.elf_so/Makefile  Tue Sep 22 01:09:32 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.10 2019/05/14 19:07:07 christos Exp $
+# $NetBSD: Makefile,v 1.11 2020/09/22 01:09:32 kamil Exp $
 #
 
 NOMAN=         # defined
@@ -17,6 +17,9 @@
 TESTSDIR=      ${TESTSBASE}/libexec/ld.elf_so
 
 TESTS_C+=      t_dlerror-cleared t_dlerror-false t_dlinfo t_dlvsym t_ifunc
+TESTS_C+=      t_rtld_r_debug
+
+COPTS.t_rtld_r_debug.c += ${${ACTIVE_CC} == "gcc" :? -Wno-maybe-uninitialized :}
 
 LDADD.t_dlerror-false= -Wl,-rpath,/var/nonexistent/lib
 LDADD.t_dlvsym=                -Wl,-rpath,${TESTSDIR}/h_helper_symver_dso2
diff -r 67d7c9a90c9e -r 5a9a4e1ad438 tests/libexec/ld.elf_so/t_rtld_r_debug.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/libexec/ld.elf_so/t_rtld_r_debug.c  Tue Sep 22 01:09:32 2020 +0000
@@ -0,0 +1,164 @@
+/*     $NetBSD: t_rtld_r_debug.c,v 1.1 2020/09/22 01:09:32 kamil Exp $ */
+
+/*
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <link_elf.h>
+#include <stdbool.h>
+
+#include "h_macros.h"
+
+static long int
+getauxval(unsigned int type)
+{
+       const AuxInfo *aux;
+
+       for (aux = _dlauxinfo(); aux->a_type != AT_NULL; ++aux) {
+               if (type == aux->a_type)                                                                                                                      
+                       return aux->a_v;
+       }
+
+       return 0;
+}
+
+static Elf_Dyn *
+get_dynamic_section(void)
+{
+       uintptr_t relocbase = (uintptr_t)~0U;
+       const Elf_Phdr *phdr;
+       Elf_Half phnum;
+       const Elf_Phdr *phlimit, *dynphdr;
+
+       phdr = (void *)getauxval(AT_PHDR);
+       phnum = (Elf_Half)getauxval(AT_PHNUM);
+
+       ATF_CHECK(phdr != NULL);
+       ATF_CHECK(phnum != (Elf_Half)~0);
+
+       phlimit = phdr + phnum;
+       dynphdr = NULL;
+
+       for (; phdr < phlimit; ++phdr) {
+                if (phdr->p_type == PT_DYNAMIC)
+                        dynphdr = phdr;   
+                if (phdr->p_type == PT_PHDR)
+                        relocbase = (uintptr_t)phdr - phdr->p_vaddr;
+        }
+
+       return (Elf_Dyn *)((uint8_t *)dynphdr->p_vaddr + relocbase);
+}
+
+static struct r_debug *
+get_rtld_r_debug(void)
+{
+       struct r_debug *debug;
+       Elf_Dyn *dynp;
+
+       for (dynp = get_dynamic_section(); dynp->d_tag != DT_NULL; dynp++) {
+               if (dynp->d_tag == DT_DEBUG) {
+                       debug = (void *)dynp->d_un.d_val;
+                       break;
+               }
+       }
+       ATF_CHECK(debug != NULL);
+
+       return debug;
+}
+
+static void
+check_r_debug_return_link_map(const char *name, struct link_map **rmap)
+{
+       struct r_debug *debug;
+       struct link_map *map;
+       void *loader;
+       bool found;
+
+       loader = NULL;
+       debug = get_rtld_r_debug();
+       ATF_CHECK(debug != NULL);
+       ATF_CHECK(debug->r_version == R_DEBUG_VERSION);
+       map = debug->r_map;
+       ATF_CHECK(map != NULL);
+
+       for (found = false; map; map = map->l_next) {
+               if (strstr(map->l_name, name) != NULL) {
+                       if (rmap)
+                               *rmap = map;
+                       found = true;
+               } else if (strstr(map->l_name, "ld.elf_so") != NULL) {
+                       loader = (void *)map->l_addr;
+               }
+       }
+       ATF_CHECK(found);
+       ATF_CHECK(loader != NULL);
+       ATF_CHECK(debug->r_brk != NULL);
+       ATF_CHECK(debug->r_state == RT_CONSISTENT);
+       ATF_CHECK(debug->r_ldbase == loader);
+}
+
+ATF_TC(self);
+ATF_TC_HEAD(self, tc)
+{
+       atf_tc_set_md_var(tc, "descr", "check whether r_debug is well-formed");
+}
+ATF_TC_BODY(self, tc)
+{
+       check_r_debug_return_link_map("t_rtld_r_debug", NULL);
+}
+
+ATF_TC(dlopen);
+ATF_TC_HEAD(dlopen, tc)
+{
+       atf_tc_set_md_var(tc, "descr",
+           "check whether r_debug is well-formed after an dlopen(3) call");
+}
+ATF_TC_BODY(dlopen, tc)
+{
+       void *handle;
+       struct link_map *map, *r_map;
+
+       handle = dlopen("libutil.so", RTLD_LAZY);
+       ATF_CHECK(handle);
+
+       check_r_debug_return_link_map("libutil.so", &r_map);
+
+       RZ(dlinfo(handle, RTLD_DI_LINKMAP, &map));
+
+       ATF_CHECK(map == r_map);
+       dlclose(handle);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+       ATF_TP_ADD_TC(tp, self);
+       ATF_TP_ADD_TC(tp, dlopen);
+       return atf_no_error();
+}



Home | Main Index | Thread Index | Old Index