# Copyright 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011 # 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 . */ # code_elim.exp -- tests that GDB can handle executables where some data/code # has been eliminated by the linker. if $tracelevel then { strace $tracelevel } set testfile1 code_elim1 set testfile2 code_elim2 set srcfile1 ${testfile1}.c set srcfile2 ${testfile2}.c set binfile1 ${objdir}/${subdir}/${testfile1} set binfile2 ${objdir}/${subdir}/${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" remote_exec build "rm -f ${binfile1}" remote_exec build "rm -f ${binfile2}" if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable $opts] != "" } { untested code_elim.exp return -1 } if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $opts] != "" } { untested code_elim.exp return -1 } proc get_var_address { var } { global gdb_prompt hex # Match output like: # $1 = (int *) 0x0 # $5 = (int (*)()) 0 # $6 = (int (*)()) 0x24 gdb_test_multiple "print &${var}" "get address of ${var}" { -re "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <${var}>)?\[\r\n\]+${gdb_prompt} $" { pass "get address of ${var}" if { $expect_out(1,string) == "0" } { return "0x0" } else { return $expect_out(1,string) } } } return "" } 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 "add-symbol-file ${binfile1} 0x100000" \ "Reading symbols from .*${testfile1}\\.\\.\\.done\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)" \ "add-symbol-file ${testfile1} 0x100000" \ "add symbol table from file \".*${testfile1}\" at\[ \t\r\n\]+\.text_addr = 0x100000\[\r\n\]+\\(y or n\\) " \ "y" 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 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 gdb_test "add-symbol-file ${binfile1} 0x100000" \ "Reading symbols from .*${testfile1}\\.\\.\\.done\\." \ "add-symbol-file ${testfile1} 0x100000" \ "add symbol table from file \".*${testfile1}\" at\[ \t\r\n\]+\.text_addr = 0x100000\[\r\n\]+\\(y or n\\) " \ "y" gdb_test "add-symbol-file ${binfile2} 0x200000" \ "Reading symbols from .*${testfile2}\\.\\.\\.done\\." \ "add-symbol-file ${testfile2} 0x200000" \ "add symbol table from file \".*${testfile2}\" at\[ \t\r\n\]+\.text_addr = 0x200000\[\r\n\]+\\(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 gdb_test "add-symbol-file ${binfile2} 0x200000" \ "Reading symbols from .*${testfile2}\\.\\.\\.done\\." \ "add-symbol-file ${testfile2} 0x200000" \ "add symbol table from file \".*${testfile2}\" at\[ \t\r\n\]+\.text_addr = 0x200000\[\r\n\]+\\(y or n\\) " \ "y" gdb_test "add-symbol-file ${binfile1} 0x100000" \ "Reading symbols from .*${testfile1}\\.\\.\\.done\\." \ "add-symbol-file ${testfile1} 0x100000" \ "add symbol table from file \".*${testfile1}\" at\[ \t\r\n\]+\.text_addr = 0x100000\[\r\n\]+\\(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