1# Copyright (C) 2003-2019 Free Software Foundation, Inc. 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15# 16 17# Tests for shared object file relocation. If two shared objects have 18# the same load address (actually, overlapping load spaces), one of 19# them gets relocated at load-time. Check that gdb gets the right 20# values for the debugging and minimal symbols. 21 22if {[skip_shlib_tests]} { 23 return 0 24} 25 26# 27# This file uses shreloc.c, shreloc1.c and shreloc2.c 28# 29 30 31standard_testfile .c shreloc1.c shreloc2.c 32 33set srcfile $srcdir/$subdir/$srcfile 34set lib1src $srcdir/$subdir/$srcfile2 35set lib2src $srcdir/$subdir/$srcfile3 36set binfile [standard_output_file $testfile] 37set lib1_sl [standard_output_file shreloc1.sl] 38set lib2_sl [standard_output_file shreloc2.sl] 39 40if [get_compiler_info] { 41 return -1 42} 43 44set lib_opts "debug" 45set exec_opts [list debug shlib=$lib1_sl shlib=$lib2_sl] 46 47if {([istarget "*pc-cygwin"] || [istarget "*pc-mingw32"]) } { 48 lappend lib_opts "ldflags=-Wl,--image-base,0x04000000" 49} 50 51if [test_compiler_info "xlc-*"] { 52 53 # IBM's xlc compiler does not add static variables to the ELF symbol 54 # table by default. We need this option to make the variables show 55 # up in "maint print msymbols". 56 57 lappend lib_opts "additional_flags=-qstatsym" 58 59} 60 61if { [gdb_compile_shlib $lib1src $lib1_sl $lib_opts] != ""} { 62 untested "could not build $lib1_sl." 63 return -1 64} elseif { [gdb_compile_shlib $lib2src $lib2_sl $lib_opts] != ""} { 65 untested "could not build $lib1_s2." 66 return -1 67} elseif { [gdb_compile $srcfile $binfile executable $exec_opts] != ""} { 68 untested "could not build $binfile." 69 return -1 70} 71 72# Start with a fresh gdb. 73 74clean_restart $binfile 75gdb_load_shlib $lib1_sl 76gdb_load_shlib $lib2_sl 77 78# Load up the shared objects 79if ![runto_main] then { 80 fail "can't run to main" 81 return 0 82} 83 84# 85# Check debugging symbol relocations 86# 87 88# Check extern function for relocation 89set fn_1_addr [get_var_address fn_1] 90set fn_2_addr [get_var_address fn_2] 91 92if { "${fn_1_addr}" == "${fn_2_addr}" } { 93 fail "relocated extern functions have different addresses" 94} else { 95 pass "relocated extern functions have different addresses" 96} 97 98# Check extern var for relocation 99set extern_var_1_addr [get_var_address extern_var_1] 100set extern_var_2_addr [get_var_address extern_var_2] 101 102if { "${extern_var_1_addr}" == "${extern_var_2_addr}" } { 103 fail "relocated extern variables have different addresses" 104} else { 105 pass "relocated extern variables have different addresses" 106} 107 108# Check static var for relocation 109set static_var_1_addr [get_var_address static_var_1] 110set static_var_2_addr [get_var_address static_var_2] 111 112if { "${static_var_1_addr}" == "${static_var_2_addr}" } { 113 fail "relocated static variables have different addresses" 114} else { 115 pass "relocated static variables have different addresses" 116} 117 118# 119# Check minimal symbol relocations 120# 121 122proc send_gdb_discard { command } { 123 # Send a command to gdb and discard output up to the next prompt 124 125 global gdb_prompt 126 127 # Discard output 128 gdb_test_multiple "${command}" "${command}" { 129 -re ".*\[\r\n]+${gdb_prompt} $" { 130 return 1 131 } 132 timeout { 133 fail "{$command} (timeout)" 134 return 0 135 } 136 } 137} 138 139proc get_msym_addrs { var msymfile } { 140 # Extract the list of values for symbols matching var in the 141 # minimal symbol output file 142 143 global gdb_prompt hex 144 set result "" 145 146 send_gdb "shell grep -E \" ${var}(\[ \t\]+.*)?\$\" ${msymfile}\n" 147 148 while 1 { 149 gdb_expect { 150 -re "\[\[\]\[ 0-9\]+\] . (${hex}) ${var}(\[ \t\]+\[^\r\n\]*)?\[\r\n\]+" { 151 set result [concat $result $expect_out(1,string)] 152 } 153 154 -re "$gdb_prompt $" { 155 pass "get_msym_addrs ${var}" 156 return "${result}" 157 } 158 159 -re "\[^\r\n\]*\[\r\n\]+" { 160 # Skip 161 } 162 163 timeout { 164 fail "get_msym_addrs ${var} (timeout)" 165 return -1 166 } 167 } 168 } 169} 170 171proc check_same {var msymfile} { 172 # Check that the minimal symbol values matching var are the same 173 174 set len [llength [lsort -unique [get_msym_addrs "${var}" "${msymfile}"]]] 175 176 if { $len == 1 } { 177 return 1 178 } else { 179 return 0 180 } 181} 182 183proc check_different {var msymfile} { 184 # Check that the minimal symbol values matching var are different 185 186 set addr_list [lsort [get_msym_addrs "${var}" "${msymfile}"]] 187 set prev "" 188 189 if { [llength ${addr_list}] < 2 } { 190 return 0 191 } 192 193 foreach addr ${addr_list} { 194 if { ${prev} == ${addr} } { 195 return 0 196 } 197 set prev ${addr} 198 } 199 200 return 1 201} 202 203if [is_remote host] { 204 set msymfile shreloc.txt 205} else { 206 set msymfile [standard_output_file shreloc.txt] 207} 208 209if [send_gdb_discard "maint print msymbols ${msymfile}"] { 210 if {[check_different "static_var_\[12\]" "${msymfile}"]} { 211 pass "(msymbol) relocated static vars have different addresses" 212 } else { 213 fail "(msymbol) relocated static vars have different addresses" 214 } 215 216 if {[check_different "extern_var_\[12\]" "${msymfile}"]} { 217 pass "(msymbol) relocated extern vars have different addresses" 218 } else { 219 fail "(msymbol) relocated extern vars have different addresses" 220 } 221 222 if {[check_different "fn_\[12\]" "${msymfile}"]} { 223 pass "(msymbol) relocated functions have different addresses" 224 } else { 225 fail "(msymbol) relocated functions have different addresses" 226 } 227} 228 229if {([istarget "*pc-cygwin"] || [istarget "*pc-mingw32"]) } { 230 # 231 # We know the names of some absolute symbols included in the 232 # portable-executable (DLL) format. Check that they didn't get 233 # relocated. 234 # 235 # A better approach would be include absolute symbols via the assembler. 236 # 237 if {[check_same "_minor_os_version__" "${msymfile}"]} { 238 pass "absolute symbols not relocated" 239 } else { 240 fail "absolute symbols not relocated" 241 } 242} 243