From: Daniel Jacobowitz Date: Mon, 26 Feb 2007 20:04:38 +0000 (+0000) Subject: * symfile.c (place_section): Check SEC_ALLOC. Do not check VMA. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2711e4564f4ab411bdf2cedff3fb92abadd630b8;p=binutils-gdb.git * symfile.c (place_section): Check SEC_ALLOC. Do not check VMA. (default_symfile_offsets): Check VMA here. Update section VMAs. * gdb.cp/cp-relocate.cc, gdb.cp/cp-relocate.exp: New. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7c0eb5531a5..9a208d8ef5c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2007-02-26 Daniel Jacobowitz + + * symfile.c (place_section): Check SEC_ALLOC. Do not check VMA. + (default_symfile_offsets): Check VMA here. Update section VMAs. + 2007-02-26 Daniel Jacobowitz * remote.c (init_remote_state): Add special handling for placeholder diff --git a/gdb/symfile.c b/gdb/symfile.c index d8ca7ca3365..4523b4b98bc 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -477,8 +477,8 @@ place_section (bfd *abfd, asection *sect, void *obj) int done; ULONGEST align = ((ULONGEST) 1) << bfd_get_section_alignment (abfd, sect); - /* We are only interested in loadable sections. */ - if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0) + /* We are only interested in allocated sections. */ + if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0) return; /* If the user specified an offset, honor it. */ @@ -502,13 +502,8 @@ place_section (bfd *abfd, asection *sect, void *obj) if (cur_sec == sect) continue; - /* We can only conflict with loadable sections. */ - if ((bfd_get_section_flags (abfd, cur_sec) & SEC_LOAD) == 0) - continue; - - /* We do not expect this to happen; just ignore sections in a - relocatable file with an assigned VMA. */ - if (bfd_section_vma (abfd, cur_sec) != 0) + /* We can only conflict with allocated sections. */ + if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0) continue; /* If the section offset is 0, either the section has not been placed @@ -581,9 +576,62 @@ default_symfile_offsets (struct objfile *objfile, if ((bfd_get_file_flags (objfile->obfd) & (EXEC_P | DYNAMIC)) == 0) { struct place_section_arg arg; - arg.offsets = objfile->section_offsets; - arg.lowest = 0; - bfd_map_over_sections (objfile->obfd, place_section, &arg); + bfd *abfd = objfile->obfd; + asection *cur_sec; + CORE_ADDR lowest = 0; + + for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next) + /* We do not expect this to happen; just skip this step if the + relocatable file has a section with an assigned VMA. */ + if (bfd_section_vma (abfd, cur_sec) != 0) + break; + + if (cur_sec == NULL) + { + CORE_ADDR *offsets = objfile->section_offsets->offsets; + + /* Pick non-overlapping offsets for sections the user did not + place explicitly. */ + arg.offsets = objfile->section_offsets; + arg.lowest = 0; + bfd_map_over_sections (objfile->obfd, place_section, &arg); + + /* Correctly filling in the section offsets is not quite + enough. Relocatable files have two properties that + (most) shared objects do not: + + - Their debug information will contain relocations. Some + shared libraries do also, but many do not, so this can not + be assumed. + + - If there are multiple code sections they will be loaded + at different relative addresses in memory than they are + in the objfile, since all sections in the file will start + at address zero. + + Because GDB has very limited ability to map from an + address in debug info to the correct code section, + it relies on adding SECT_OFF_TEXT to things which might be + code. If we clear all the section offsets, and set the + section VMAs instead, then symfile_relocate_debug_section + will return meaningful debug information pointing at the + correct sections. + + GDB has too many different data structures for section + addresses - a bfd, objfile, and so_list all have section + tables, as does exec_ops. Some of these could probably + be eliminated. */ + + for (cur_sec = abfd->sections; cur_sec != NULL; + cur_sec = cur_sec->next) + { + if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0) + continue; + + bfd_set_section_vma (abfd, cur_sec, offsets[cur_sec->index]); + offsets[cur_sec->index] = 0; + } + } } /* Remember the bfd indexes for the .text, .data, .bss and diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 656d0c82bbf..80496656a27 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-02-26 Daniel Jacobowitz + + * gdb.cp/cp-relocate.cc, gdb.cp/cp-relocate.exp: New. + 2007-02-26 Daniel Jacobowitz * gdb.arch/iwmmxt-regs.c, gdb.arch/iwmmxt-regs.exp: Update diff --git a/gdb/testsuite/gdb.cp/cp-relocate.cc b/gdb/testsuite/gdb.cp/cp-relocate.cc new file mode 100644 index 00000000000..e129d73cc06 --- /dev/null +++ b/gdb/testsuite/gdb.cp/cp-relocate.cc @@ -0,0 +1,29 @@ +/* This test file is part of GDB, the GNU debugger. + + Copyright 2007 + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +template int func(int) +{ + return X; +} + +int caller() +{ + return func<1>(1) + func<2>(2); +} diff --git a/gdb/testsuite/gdb.cp/cp-relocate.exp b/gdb/testsuite/gdb.cp/cp-relocate.exp new file mode 100644 index 00000000000..1fd1c0fffa0 --- /dev/null +++ b/gdb/testsuite/gdb.cp/cp-relocate.exp @@ -0,0 +1,137 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# Test loading symbols from unrelocated C++ object files. + +set testfile cp-relocate +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile}.o + +if { [skip_cplus_tests] } { continue } + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {c++ debug}] != "" } { + untested cp-relocate.exp + return -1 +} + +proc get_func_address { func } { + global gdb_prompt hex + + set rfunc [string_to_regexp $func] + gdb_test_multiple "print '${func}'" "get address of ${func}" { + -re "\\\$\[0-9\]+ = \\{.*\\} (0|($hex) <${rfunc}>)\[\r\n\]+${gdb_prompt} $" { + # $1 = {int ()} 0x24 + # But if the function is at zero, the name may be omitted. + pass "get address of ${func}" + if { $expect_out(1,string) == "0" } { + return "0x0" + } else { + return $expect_out(2,string) + } + } + } + return "" +} + +# Load the file as an executable; GDB should assign non-overlapping +# section offsets. +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_file_cmd ${binfile} + +# Find the interesting functions. We go to a little effort to find +# the right function names here, to work around PR c++/40. +set func1_name "" +set func2_name "" +gdb_test_multiple "info functions func<.>" "info functions" { + -re "\r\nint (\[^\r\]*func<1>\[^\r]*);" { + set func1_name $expect_out(1,string) + exp_continue + } + -re "\r\nint (\[^\r\]*func<2>\[^\r]*);" { + set func2_name $expect_out(1,string) + exp_continue + } + -re "$gdb_prompt $" { + if { ${func1_name} != "" && ${func2_name} != "" } { + pass "info functions" + } else { + fail "info functions" + return -1 + } + } +} + +# Check that all the functions have different addresses. +set func1_addr [get_func_address "$func1_name"] +set func2_addr [get_func_address "$func2_name"] +set caller_addr [get_func_address "caller"] + +if { "${func1_addr}" == "${func2_addr}" + || "${func1_addr}" == "${func2_addr}" + || "${func2_addr}" == "${caller_addr}" } { + fail "C++ functions have different addresses" +} else { + pass "C++ functions have different addresses" +} + +# Figure out the names of the sections containing the template +# functions. +set func1_sec "" +set func2_sec "" +gdb_test_multiple "info file" "info file" { + -re "($hex) - ($hex) is (\[^\r\]*)\r" { + if { $expect_out(1,string) <= $func1_addr + && $expect_out(2,string) > $func1_addr } { + set func1_sec $expect_out(3,string) + } elseif { $expect_out(1,string) <= $func2_addr + && $expect_out(2,string) > $func2_addr } { + set func2_sec $expect_out(3,string) + } + exp_continue + } + -re "$gdb_prompt $" { + if { ${func1_sec} != "" && ${func2_sec} != "" } { + pass "info file" + } else { + fail "info file" + return -1 + } + } +} + +if { $func1_sec == $func2_sec } { + untested "cp-relocate.exp - template functions in same sections" + return -1 +} + +# Now start a clean GDB, for add-symbol-file tests. +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +gdb_test "add-symbol-file ${binfile} 0 -s ${func1_sec} 0x40000 -s ${func2_sec} 0x80000" \ + "Reading symbols from .*${testfile}\\.o\\.\\.\\.done\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)" \ + "add-symbol-file ${binfile}" \ + "add symbol table from file \".*${testfile}\\.o\" at.*\\(y or n\\) " \ + "y" + +# Make sure the function addresses were updated. +gdb_test "break *'$func1_name'" \ + "Breakpoint $decimal at 0x4....: file .*" +gdb_test "break *'$func2_name'" \ + "Breakpoint $decimal at 0x8....: file .*"