| 1 | # Copyright 2007-2018 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 | # Test loading symbols from unrelocated C++ object files. |
| 17 | |
| 18 | standard_testfile .cc |
| 19 | append binfile .o |
| 20 | |
| 21 | if { [skip_cplus_tests] } { continue } |
| 22 | |
| 23 | if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {c++ debug}] != "" } { |
| 24 | untested "failed to compile" |
| 25 | return -1 |
| 26 | } |
| 27 | |
| 28 | proc get_func_address { func } { |
| 29 | global gdb_prompt hex |
| 30 | |
| 31 | set rfunc [string_to_regexp $func] |
| 32 | gdb_test_multiple "print ${func}" "get address of ${func}" { |
| 33 | -re "\\\$\[0-9\]+ = \\{.*\\} (($hex) <${rfunc}.*>)\[\r\n\]+${gdb_prompt} $" { |
| 34 | # $1 = {int ()} 0x24 <function_bar> |
| 35 | # But if the function is at zero, the name may be omitted. |
| 36 | pass "get address of ${func}" |
| 37 | if { $expect_out(1,string) == "0x0" } { |
| 38 | return "0x0" |
| 39 | } else { |
| 40 | return $expect_out(2,string) |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | return "" |
| 45 | } |
| 46 | |
| 47 | # Load the file as an executable; GDB should assign non-overlapping |
| 48 | # section offsets. |
| 49 | gdb_exit |
| 50 | gdb_start |
| 51 | gdb_reinitialize_dir $srcdir/$subdir |
| 52 | gdb_file_cmd ${binfile} |
| 53 | |
| 54 | # Find the interesting functions. We go to a little effort to find |
| 55 | # the right function names here, to work around PR c++/40. |
| 56 | set func1_name "" |
| 57 | set func2_name "" |
| 58 | gdb_test_multiple "info functions func<.>" "info functions" { |
| 59 | -re "\tint (\[^\r\]*func<1>\[^\r]*);" { |
| 60 | set func1_name $expect_out(1,string) |
| 61 | exp_continue |
| 62 | } |
| 63 | -re "\tint (\[^\r\]*func<2>\[^\r]*);" { |
| 64 | set func2_name $expect_out(1,string) |
| 65 | exp_continue |
| 66 | } |
| 67 | -re "$gdb_prompt $" { |
| 68 | if { ${func1_name} != "" && ${func2_name} != "" } { |
| 69 | pass "info functions" |
| 70 | } else { |
| 71 | fail "info functions" |
| 72 | return -1 |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | # Check that all the functions have different addresses. |
| 78 | set func1_addr [get_func_address "$func1_name"] |
| 79 | set func2_addr [get_func_address "$func2_name"] |
| 80 | set caller_addr [get_func_address "caller"] |
| 81 | |
| 82 | if { "${func1_addr}" == "${func2_addr}" |
| 83 | || "${func1_addr}" == "${func2_addr}" |
| 84 | || "${func2_addr}" == "${caller_addr}" } { |
| 85 | fail "C++ functions have different addresses" |
| 86 | } else { |
| 87 | pass "C++ functions have different addresses" |
| 88 | } |
| 89 | |
| 90 | # Figure out the names of the sections containing the template |
| 91 | # functions. |
| 92 | set func1_sec "" |
| 93 | set func2_sec "" |
| 94 | gdb_test_multiple "info file" "info file" { |
| 95 | -re "($hex) - ($hex) is (\[^\r\]*)\r" { |
| 96 | if { $expect_out(1,string) <= $func1_addr |
| 97 | && $expect_out(2,string) > $func1_addr } { |
| 98 | set func1_sec $expect_out(3,string) |
| 99 | } elseif { $expect_out(1,string) <= $func2_addr |
| 100 | && $expect_out(2,string) > $func2_addr } { |
| 101 | set func2_sec $expect_out(3,string) |
| 102 | } |
| 103 | exp_continue |
| 104 | } |
| 105 | -re "$gdb_prompt $" { |
| 106 | if { ${func1_sec} != "" && ${func2_sec} != "" } { |
| 107 | pass "info file" |
| 108 | } else { |
| 109 | fail "info file" |
| 110 | return -1 |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | if { $func1_sec == $func2_sec } { |
| 116 | untested "cp-relocate.exp - template functions in same sections" |
| 117 | return -1 |
| 118 | } |
| 119 | |
| 120 | # Now start a clean GDB, for add-symbol-file tests. |
| 121 | gdb_exit |
| 122 | gdb_start |
| 123 | gdb_reinitialize_dir $srcdir/$subdir |
| 124 | |
| 125 | gdb_test "add-symbol-file ${binfile} 0 -s ${func1_sec} 0x10000 -s ${func2_sec} 0x20000" \ |
| 126 | "Reading symbols from .*${testfile}\\.o\\.\\.\\.done\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)" \ |
| 127 | "add-symbol-file ${testfile}.o" \ |
| 128 | "add symbol table from file \".*${testfile}\\.o\" at.*\\(y or n\\) " \ |
| 129 | "y" |
| 130 | |
| 131 | # Make sure the function addresses were updated. |
| 132 | gdb_test "break *$func1_name" \ |
| 133 | "Breakpoint $decimal at 0x1....: file .*" |
| 134 | gdb_test "break *$func2_name" \ |
| 135 | "Breakpoint $decimal at 0x2....: file .*" |