| # Copyright 2002-2021 Free Software Foundation, Inc. |
| |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| # code_elim.exp -- tests that GDB can handle executables where some data/code |
| # has been eliminated by the linker. |
| |
| set testfile1 code_elim1 |
| set testfile2 code_elim2 |
| set srcfile1 ${testfile1}.c |
| set srcfile2 ${testfile2}.c |
| set binfile1 [standard_output_file ${testfile1}] |
| set binfile2 [standard_output_file ${testfile2}] |
| set opts [list debug] |
| lappend opts "additional_flags=-ffunction-sections" |
| lappend opts "additional_flags=-fdata-sections" |
| lappend opts "additional_flags=-Wl,-gc-sections" |
| lappend opts "additional_flags=-Wl,-e,main" |
| |
| # Place variables in .data instead of .sdata. |
| if {[istarget "riscv*-*-*"]} { |
| lappend opts "additional_flags=-msmall-data-limit=0" |
| } |
| |
| remote_exec build "rm -f ${binfile1}" |
| remote_exec build "rm -f ${binfile2}" |
| |
| if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable $opts] != "" } { |
| untested "failed to compile" |
| return -1 |
| } |
| |
| if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $opts] != "" } { |
| untested "failed to compile" |
| return -1 |
| } |
| |
| proc not_null_var_address { var } { |
| |
| # Same as get_var_address, expect that it reports a failure if a null |
| # address is returned by gdb. |
| |
| set address [get_var_address $var] |
| regexp "0x\[0-9a-fA-F\]+" $address address |
| if { "$address" == "0x0" } { |
| fail "$var has null address" |
| } |
| } |
| |
| proc test_eliminated_var { var } { |
| global gdb_prompt hex |
| |
| # Match output 'No symbol "${var}" in current context' |
| |
| gdb_test_multiple "print &${var}" "test eliminated var ${var}" { |
| -re "No symbol \"${var}\" in current context\\.\[\r\n\]+${gdb_prompt} $" { |
| pass "test eliminated var ${var}" |
| } |
| -re "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <${var}>)?\[\r\n\]+${gdb_prompt} $" { |
| fail "test eliminated var ${var}" |
| } |
| } |
| } |
| |
| # Check that the code and data eliminated in binfile1 are not included |
| # into partial symtab... and that non-eliminated symbols are still there. |
| |
| gdb_exit |
| gdb_start |
| |
| gdb_test "symbol-file ${binfile1}" \ |
| "Reading symbols from .*${testfile1}\\.\\.\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)" \ |
| "symbol-file ${testfile1}" |
| |
| with_test_prefix "single psymtabs" { |
| test_eliminated_var my_global_symbol |
| test_eliminated_var my_static_symbol |
| test_eliminated_var my_global_func |
| not_null_var_address main |
| } |
| |
| # Same thing for symtabs |
| |
| gdb_exit |
| global GDBFLAGS |
| set saved_gdbflags $GDBFLAGS |
| set GDBFLAGS "$GDBFLAGS --readnow $binfile1" |
| gdb_start |
| set GDBFLAGS $saved_gdbflags |
| |
| with_test_prefix "single symtabs" { |
| test_eliminated_var my_global_symbol |
| test_eliminated_var my_static_symbol |
| test_eliminated_var my_global_func |
| not_null_var_address main |
| } |
| |
| # binfile2 contains the symbols that have been eliminated in binfile1. Check |
| # the eliminated symbols does not hide these valid ones. |
| |
| gdb_exit |
| gdb_start |
| |
| with_test_prefix "order1" { |
| gdb_test "add-symbol-file ${binfile1} 0x100000 -s .bss 0x120000" \ |
| "Reading symbols from .*${testfile1}\\.\\.\\." \ |
| "add-symbol-file ${testfile1} 0x100000" \ |
| "add symbol table from file \".*${testfile1}\" at.*\\(y or n\\) " \ |
| "y" |
| |
| gdb_test "add-symbol-file ${binfile2} 0x200000 -s .data 0x210000 -s .bss 0x220000" \ |
| "Reading symbols from .*${testfile2}\\.\\.\\." \ |
| "add-symbol-file ${testfile2} 0x200000" \ |
| "add symbol table from file \".*${testfile2}\" at.*\\(y or n\\) " \ |
| "y" |
| |
| not_null_var_address my_global_symbol |
| not_null_var_address my_static_symbol |
| not_null_var_address my_global_func |
| not_null_var_address main |
| } |
| |
| # Same thing, but loading binfile2 before binfile1. |
| |
| gdb_exit |
| gdb_start |
| |
| with_test_prefix "order2" { |
| gdb_test "add-symbol-file ${binfile2} 0x200000 -s .data 0x210000 -s .bss 0x220000" \ |
| "Reading symbols from .*${testfile2}\\.\\.\\." \ |
| "add-symbol-file ${testfile2} 0x200000" \ |
| "add symbol table from file \".*${testfile2}\" at.*\\(y or n\\) " \ |
| "y" |
| |
| gdb_test "add-symbol-file ${binfile1} 0x100000 -s .bss 0x120000" \ |
| "Reading symbols from .*${testfile1}\\.\\.\\." \ |
| "add-symbol-file ${testfile1} 0x100000" \ |
| "add symbol table from file \".*${testfile1}\" at.*\\(y or n\\) " \ |
| "y" |
| |
| not_null_var_address my_global_symbol |
| not_null_var_address my_static_symbol |
| not_null_var_address my_global_func |
| not_null_var_address main |
| } |