diff options
-rw-r--r-- | gdb/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/sym-file-loader.c | 70 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/sym-file.exp | 50 |
3 files changed, 106 insertions, 26 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0d773b6..64e4cbd 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2014-04-15 Pedro Alves <palves@redhat.com> + + * gdb.base/sym-file-loader.c: Include <limits.h>. + (SELF_LINK): New define. + (get_origin): New function. + (load_shlib): Use it. + * gdb.base/sym-file.exp: Don't early return if the target is + remote. Use runto_main, and issue fail is that fails. Use + gdb_load_shlibs. + (shlib_name): Delete. + (lib_so, lib_syms, lib_dlopen): New globals. Use them throughout. + 2014-04-15 Pedro Alves <palves@redhat.com> * gdb.base/sym-file.exp: Remove regex characters from test diff --git a/gdb/testsuite/gdb.base/sym-file-loader.c b/gdb/testsuite/gdb.base/sym-file-loader.c index 65c48be..625788a 100644 --- a/gdb/testsuite/gdb.base/sym-file-loader.c +++ b/gdb/testsuite/gdb.base/sym-file-loader.c @@ -15,6 +15,7 @@ #include <unistd.h> #include <fcntl.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -77,6 +78,48 @@ load (uint8_t *addr, Elf_External_Phdr *phdr, struct segment *tail_seg) return seg; } +#ifdef __linux__ +# define SELF_LINK "/proc/self/exe" +#elif defined NETBSD +# define SELK_LINK "/proc/curproc/exe" +#elif defined __OpenBSD__ || defined __FreeBSD__ || defined __DragonFly__ +# define SELK_LINK "/proc/curproc/file" +#elif defined SunOS +# define SELK_LINK "/proc/self/path/a.out" +#endif + +/* Like RPATH=$ORIGIN, return the dirname of the current + executable. */ + +static const char * +get_origin (void) +{ + static char self_path[PATH_MAX]; + static ssize_t self_path_len; + + if (self_path_len == 0) + { +#ifdef SELF_LINK + self_path_len = readlink (SELF_LINK, self_path, PATH_MAX - 1); + if (self_path_len != -1) + { + char *dirsep; + + self_path[self_path_len] = '\0'; + dirsep = strrchr (self_path, '/'); + *dirsep = '\0'; + } +#else + self_path_len = -1; +#endif + } + + if (self_path_len == -1) + return NULL; + else + return self_path; +} + /* Mini shared library loader. No reallocation is performed for the sake of simplicity. */ @@ -85,16 +128,37 @@ load_shlib (const char *file, Elf_External_Ehdr **ehdr_out, struct segment **seg_out) { uint64_t i; - int fd; + int fd = -1; off_t fsize; uint8_t *addr; Elf_External_Ehdr *ehdr; Elf_External_Phdr *phdr; struct segment *head_seg = NULL; struct segment *tail_seg = NULL; + const char *origin; + char *path; + + /* Map the lib in memory for reading. + + If the file name is relative, try looking it up relative to the + main executable's path. I.e., emulate RPATH=$ORIGIN. */ + if (file[0] != '/') + { + origin = get_origin (); + if (origin == NULL) + { + fprintf (stderr, "get_origin not implemented."); + return -1; + } + + path = alloca (strlen (origin) + 1 + strlen (file) + 1); + sprintf (path, "%s/%s", origin, file); + fd = open (path, O_RDONLY); + } + + if (fd < 0) + fd = open (file, O_RDONLY); - /* Map the lib in memory for reading. */ - fd = open (file, O_RDONLY); if (fd < 0) { perror ("fopen failed."); diff --git a/gdb/testsuite/gdb.base/sym-file.exp b/gdb/testsuite/gdb.base/sym-file.exp index 9ee12e5..c87c3c7 100644 --- a/gdb/testsuite/gdb.base/sym-file.exp +++ b/gdb/testsuite/gdb.base/sym-file.exp @@ -16,14 +16,14 @@ # Test adding and removing a symbol file dynamically: # 1) Run to gdb_add_symbol_file in $srcfile. # 2) Set a pending breakpoint at bar in $srcfile3. -# 3) Load $shlib_name using 'add-symbol-file'. +# 3) Load the library's symbols using 'add-symbol-file'. # 4) 'info files' must display ${lib_basename}. # 5) Continue to bar in $srcfile3. # 6) Set a breakpoint at foo in $srcfile3. # 7) Continue to foo in $srcfile3. # 8) Set a breakpoint at gdb_remove_symbol_file. # 9) Continue to gdb_remove_symbol_file in $srcfile. -# 10) Remove $shlib_name using 'remove-symbol-file'. +# 10) Remove the library's symbols using 'remove-symbol-file'. # 11) 'info files' must not display ${lib_basename}, anymore. # 12) Check that the breakpoints at foo and bar are pending. # 13) Check that the execution can continue without error. @@ -36,10 +36,6 @@ if [skip_shlib_tests] { return 0 } -if [is_remote target] { - return 0 -} - set target_size TARGET_UNKNOWN if {[is_lp64_target]} { set target_size TARGET_LP64 @@ -56,15 +52,18 @@ set lib_basename sym-file-lib standard_testfile $main_basename.c $loader_basename.c $lib_basename.c set libsrc "${srcdir}/${subdir}/${srcfile3}" -set shlib_name [standard_output_file ${lib_basename}.so] +set lib_so [standard_output_file ${lib_basename}.so] +set lib_syms [shlib_symbol_file ${lib_so}] +set lib_dlopen [shlib_target_file ${lib_basename}.so] + set exec_opts [list debug "additional_flags= -I$srcdir/../../include/ -D$target_size\ - -DSHLIB_NAME\\=\"$shlib_name\""] + -DSHLIB_NAME\\=\"$lib_dlopen\""] if [get_compiler_info] { return -1 } -if {[gdb_compile_shlib $libsrc $shlib_name {debug}] != ""} { +if {[gdb_compile_shlib $libsrc $lib_so {debug}] != ""} { untested ${testfile} return } @@ -73,22 +72,27 @@ if {[prepare_for_testing $testfile $binfile "$srcfile $srcfile2" $exec_opts]} { return } -# 1) Run to GDB_ADD_SYMBOl_FILE in $srcfile for adding -# $shlib_name. -set result [runto gdb_add_symbol_file] -if {!$result} then { - return +gdb_load_shlibs ${lib_so} + +if ![runto_main] then { + fail "Can't run to main" + return } +# 1) Run to gdb_add_symbol_file in $srcfile for adding the library's +# symbols. +gdb_breakpoint gdb_add_symbol_file +gdb_continue_to_breakpoint gdb_add_symbol_file + # 2) Set a pending breakpoint at bar in $srcfile3. set result [gdb_breakpoint bar allow-pending] if {!$result} then { return } -# 3) Add $shlib_name using 'add-symbol-file'. -set result [gdb_test "add-symbol-file ${shlib_name} addr" \ - "Reading symbols from .*${lib_basename}\\.so\\.\\.\\.done\\." \ +# 3) Add the library's symbols using 'add-symbol-file'. +set result [gdb_test "add-symbol-file ${lib_syms} addr" \ + "Reading symbols from .*${lib_syms}\\.\\.\\.done\\." \ "add-symbol-file ${lib_basename}.so addr" \ "add symbol table from file \".*${lib_basename}\\.so\"\ at.*\\(y or n\\) " \ @@ -119,7 +123,7 @@ set lnum_foo [gdb_get_line_number "break at foo" $srcfile3] gdb_continue_to_breakpoint foo ".*${lib_basename}\\.c:$lnum_foo.*" # 8) Set a breakpoint at gdb_remove_symbol_file in $srcfile for -# removing $shlib_name. +# removing the library's symbols. set result [gdb_breakpoint gdb_remove_symbol_file] if {!$result} then { return @@ -128,7 +132,7 @@ if {!$result} then { # 9) Continue to gdb_remove_symbol_file in $srcfile. gdb_continue_to_breakpoint gdb_remove_symbol_file -# 10) Remove $shlib_name using 'remove-symbol-file'. +# 10) Remove the library's symbols using 'remove-symbol-file'. set result [gdb_test "remove-symbol-file -a addr" \ ""\ "remove-symbol-file -a addr" \ @@ -144,13 +148,13 @@ gdb_test "info files" \ "^(?!(.*${lib_basename})).*" \ "info files must not display ${lib_basename}" -# 12) Check that the breakpoints at foo and bar are pending after removing -# $shlib_name. -gdb_test "info breakpoints 2" \ +# 12) Check that the breakpoints at foo and bar are pending after +# removing the library's symbols. +gdb_test "info breakpoints 3" \ ".*PENDING.*" \ "breakpoint at foo is pending" -gdb_test "info breakpoints 3" \ +gdb_test "info breakpoints 4" \ ".*PENDING.*" \ "breakpoint at bar is pending" |