diff --git a/gdb-6.3-nonthreaded-wp-20050117.patch b/gdb-6.3-nonthreaded-wp-20050117.patch deleted file mode 100644 index 6f49864..0000000 --- a/gdb-6.3-nonthreaded-wp-20050117.patch +++ /dev/null @@ -1,119 +0,0 @@ -[base] - -2007-10-13 Jan Kratochvil - - * linux-nat.c (iterate_over_lwps): Fixed missing LWP initialization for - current INFERIOR_PTID. - -2007-10-13 Jan Kratochvil - - * gdb.base/follow-child.exp, gdb.base/follow-child.c: New files. - -2007-10-16 Jan Kratochvil - - Port to GDB-6.7. - -2008-02-24 Jan Kratochvil - - Port to GDB-6.8pre. - -2008-08-25 Jan Kratochvil - - Remove the fix as causing an assertion failure for - gdb.base/checkpoint.exp and it is no longer needed for - gdb.base/follow-child.exp . - -Index: gdb-6.8cvs20080219/gdb/testsuite/gdb.base/follow-child.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-6.8cvs20080219/gdb/testsuite/gdb.base/follow-child.c 2008-02-22 08:14:04.000000000 +0100 -@@ -0,0 +1,29 @@ -+/* This testcase 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. -+ -+ Please email any bugs, comments, and/or additions to this file to: -+ bug-gdb@prep.ai.mit.edu */ -+ -+#include -+ -+int main() -+{ -+ fork (); -+ sleep (60); -+ return 0; -+} -Index: gdb-6.8cvs20080219/gdb/testsuite/gdb.base/follow-child.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-6.8cvs20080219/gdb/testsuite/gdb.base/follow-child.exp 2008-02-22 08:14:17.000000000 +0100 -@@ -0,0 +1,55 @@ -+# 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. -+ -+if $tracelevel then { -+ strace $tracelevel -+} -+ -+set prms_id 0 -+set bug_id 0 -+ -+set testfile follow-child -+set srcfile ${testfile}.c -+set binfile ${objdir}/${subdir}/${testfile} -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+ -+# Get things started. -+ -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+gdb_load ${binfile} -+ -+# For C programs, "start" should stop in main(). -+ -+gdb_test "set follow-fork-mode child" "" -+set test "started" -+# GDB_RUN_CMD already checks for `Starting program:'. -+gdb_run_cmd -+sleep 5 -+send_gdb "\003" -+set test "break" -+gdb_test_multiple "" $test { -+ -re "Program received signal SIGINT.*$gdb_prompt $" { -+ pass $test -+ } -+ -re "\\\[New process \[0-9\]+\\\]" { -+ fail $test -+ } -+} diff --git a/gdb-6.3-pie-20050110.patch b/gdb-6.3-pie-20050110.patch deleted file mode 100644 index 5c12597..0000000 --- a/gdb-6.3-pie-20050110.patch +++ /dev/null @@ -1,1350 +0,0 @@ -2007-11-02 Jan Kratochvil - - Port to GDB-6.7.1. - -2007-11-02 Jan Kratochvil - - Port to post-GDB-6.7.1 multi-PC breakpoints. - -2007-11-09 Jan Kratochvil - - * solib-svr4.c (svr4_current_sos): Fix segfault on NULL EXEC_BFD. - -2008-02-24 Jan Kratochvil - - Port to GDB-6.8pre. - -2008-02-27 Jan Kratochvil - - Port to gdb-6.7.50.20080227. - -2008-06-01 Jan Kratochvil - - Fix crash on a watchpoint update on an inferior stop. - -2008-09-01 Jan Kratochvil - - Fix scan_dyntag() for binaries provided by valgrind (BZ 460319). - -Index: gdb-6.8.91.20090925/gdb/amd64-tdep.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/amd64-tdep.c 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/amd64-tdep.c 2009-09-25 10:25:45.000000000 +0200 -@@ -36,6 +36,7 @@ - #include "regcache.h" - #include "regset.h" - #include "symfile.h" -+#include "exceptions.h" - - #include "gdb_assert.h" - -@@ -1591,18 +1592,31 @@ amd64_analyze_stack_align (CORE_ADDR pc, - Any function that doesn't start with this sequence will be assumed - to have no prologue and thus no valid frame pointer in %rbp. */ - --static CORE_ADDR --amd64_analyze_prologue (struct gdbarch *gdbarch, -- CORE_ADDR pc, CORE_ADDR current_pc, -- struct amd64_frame_cache *cache) -+struct amd64_analyze_prologue_data -+ { -+ struct gdbarch *gdbarch; -+ CORE_ADDR pc, current_pc; -+ struct amd64_frame_cache *cache; -+ CORE_ADDR retval; -+ }; -+ -+static int -+amd64_analyze_prologue_1 (void *data_pointer) - { -+ struct amd64_analyze_prologue_data *data = data_pointer; -+ struct gdbarch *gdbarch = data->gdbarch; -+ CORE_ADDR pc = data->pc, current_pc = data->current_pc; -+ struct amd64_frame_cache *cache = data->cache; - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - static gdb_byte proto[3] = { 0x48, 0x89, 0xe5 }; /* movq %rsp, %rbp */ - gdb_byte buf[3]; - gdb_byte op; - - if (current_pc <= pc) -- return current_pc; -+ { -+ data->retval = current_pc; -+ return 1; -+ } - - pc = amd64_analyze_stack_align (pc, current_pc, cache); - -@@ -1617,18 +1631,59 @@ amd64_analyze_prologue (struct gdbarch * - - /* If that's all, return now. */ - if (current_pc <= pc + 1) -- return current_pc; -+ { -+ data->retval = current_pc; -+ return 1; -+ } - - /* Check for `movq %rsp, %rbp'. */ - read_memory (pc + 1, buf, 3); - if (memcmp (buf, proto, 3) != 0) -- return pc + 1; -+ { -+ data->retval = pc + 1; -+ return 1; -+ } - - /* OK, we actually have a frame. */ - cache->frameless_p = 0; -- return pc + 4; -+ data->retval = pc + 4; -+ return 1; - } - -+ data->retval = pc; -+ return 1; -+} -+ -+/* Catch memory read errors and return just PC in such case. -+ It occurs very early on enable_break->new_symfile_objfile-> -+ ->breakpoint_re_set->decode_line_1->decode_variable_1-> -+ ->find_function_start_sal */ -+ -+static CORE_ADDR -+amd64_analyze_prologue (struct gdbarch *gdbarch, -+ CORE_ADDR pc, CORE_ADDR current_pc, -+ struct amd64_frame_cache *cache) -+{ -+ int status; -+ struct amd64_analyze_prologue_data data; -+ struct ui_file *saved_gdb_stderr; -+ -+ /* Suppress error messages. */ -+ saved_gdb_stderr = gdb_stderr; -+ gdb_stderr = ui_file_new (); -+ -+ data.gdbarch = gdbarch; -+ data.pc = pc; -+ data.current_pc = current_pc; -+ data.cache = cache; -+ status = catch_errors (amd64_analyze_prologue_1, &data, "", RETURN_MASK_ALL); -+ -+ /* Stop suppressing error messages. */ -+ ui_file_delete (gdb_stderr); -+ gdb_stderr = saved_gdb_stderr; -+ -+ if (status) -+ return data.retval; - return pc; - } - -Index: gdb-6.8.91.20090925/gdb/auxv.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/auxv.c 2009-07-02 19:25:52.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/auxv.c 2009-09-25 10:25:45.000000000 +0200 -@@ -78,7 +78,7 @@ procfs_xfer_auxv (struct target_ops *ops - Return 1 if an entry was read into *TYPEP and *VALP. */ - static int - default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, -- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) -+ gdb_byte *endptr, ULONGEST *typep, CORE_ADDR *valp) - { - const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) - / TARGET_CHAR_BIT; -@@ -106,7 +106,7 @@ default_auxv_parse (struct target_ops *o - Return 1 if an entry was read into *TYPEP and *VALP. */ - int - target_auxv_parse (struct target_ops *ops, gdb_byte **readptr, -- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) -+ gdb_byte *endptr, ULONGEST *typep, CORE_ADDR *valp) - { - struct target_ops *t; - for (t = ops; t != NULL; t = t->beneath) -@@ -121,9 +121,10 @@ target_auxv_parse (struct target_ops *op - an error getting the information. On success, return 1 after - storing the entry's value field in *VALP. */ - int --target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp) -+target_auxv_search (struct target_ops *ops, ULONGEST match, CORE_ADDR *valp) - { -- CORE_ADDR type, val; -+ CORE_ADDR val; -+ ULONGEST at_type; - gdb_byte *data; - LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data); - gdb_byte *ptr = data; -@@ -133,10 +134,10 @@ target_auxv_search (struct target_ops *o - return n; - - while (1) -- switch (target_auxv_parse (ops, &ptr, data + n, &type, &val)) -+ switch (target_auxv_parse (ops, &ptr, data + n, &at_type, &val)) - { - case 1: /* Here's an entry, check it. */ -- if (type == match) -+ if (at_type == match) - { - xfree (data); - *valp = val; -@@ -159,7 +160,8 @@ target_auxv_search (struct target_ops *o - int - fprint_target_auxv (struct ui_file *file, struct target_ops *ops) - { -- CORE_ADDR type, val; -+ CORE_ADDR val; -+ ULONGEST at_type; - gdb_byte *data; - LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, - &data); -@@ -169,13 +171,13 @@ fprint_target_auxv (struct ui_file *file - if (len <= 0) - return len; - -- while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0) -+ while (target_auxv_parse (ops, &ptr, data + len, &at_type, &val) > 0) - { - const char *name = "???"; - const char *description = ""; - enum { dec, hex, str } flavor = hex; - -- switch (type) -+ switch (at_type) - { - #define TAG(tag, text, kind) \ - case tag: name = #tag; description = text; flavor = kind; break -@@ -231,7 +233,7 @@ fprint_target_auxv (struct ui_file *file - } - - fprintf_filtered (file, "%-4s %-20s %-30s ", -- plongest (type), name, description); -+ plongest (at_type), name, description); - switch (flavor) - { - case dec: -@@ -253,7 +255,7 @@ fprint_target_auxv (struct ui_file *file - break; - } - ++ents; -- if (type == AT_NULL) -+ if (at_type == AT_NULL) - break; - } - -Index: gdb-6.8.91.20090925/gdb/auxv.h -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/auxv.h 2009-06-07 21:07:08.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/auxv.h 2009-09-25 10:25:45.000000000 +0200 -@@ -31,14 +31,14 @@ - Return 1 if an entry was read into *TYPEP and *VALP. */ - extern int target_auxv_parse (struct target_ops *ops, - gdb_byte **readptr, gdb_byte *endptr, -- CORE_ADDR *typep, CORE_ADDR *valp); -+ ULONGEST *typep, CORE_ADDR *valp); - - /* Extract the auxiliary vector entry with a_type matching MATCH. - Return zero if no such entry was found, or -1 if there was - an error getting the information. On success, return 1 after - storing the entry's value field in *VALP. */ - extern int target_auxv_search (struct target_ops *ops, -- CORE_ADDR match, CORE_ADDR *valp); -+ ULONGEST match, CORE_ADDR *valp); - - /* Print the contents of the target's AUXV on the specified file. */ - extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops); -Index: gdb-6.8.91.20090925/gdb/dwarf2read.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/dwarf2read.c 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/dwarf2read.c 2009-09-25 10:25:45.000000000 +0200 -@@ -1717,7 +1717,7 @@ dwarf2_build_psymtabs (struct objfile *o - dwarf2_read_section (objfile, &dwarf2_per_objfile->eh_frame); - dwarf2_read_section (objfile, &dwarf2_per_objfile->frame); - -- if (mainline -+ if ((mainline == 1) - || (objfile->global_psymbols.size == 0 - && objfile->static_psymbols.size == 0)) - { -Index: gdb-6.8.91.20090925/gdb/elfread.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/elfread.c 2009-09-25 10:25:38.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/elfread.c 2009-09-25 10:25:45.000000000 +0200 -@@ -681,7 +681,7 @@ elf_symfile_read (struct objfile *objfil - /* If we are reinitializing, or if we have never loaded syms yet, - set table to empty. MAINLINE is cleared so that *_read_psymtab - functions do not all also re-initialize the psymbol table. */ -- if (mainline) -+ if (mainline == 1) - { - init_psymbol_list (objfile, 0); - mainline = 0; -Index: gdb-6.8.91.20090925/gdb/infrun.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/infrun.c 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/infrun.c 2009-09-25 10:25:45.000000000 +0200 -@@ -3659,6 +3659,10 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME ( - #endif - target_terminal_inferior (); - -+ /* For PIE executables, we dont really know where the -+ breakpoints are going to be until we start up the inferior. */ -+ enable_breakpoints_after_startup (); -+ - /* If requested, stop when the dynamic linker notifies - gdb of events. This allows the user to get control - and place breakpoints in initializer routines for -Index: gdb-6.8.91.20090925/gdb/objfiles.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/objfiles.c 2009-09-25 10:25:38.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/objfiles.c 2009-09-25 10:25:45.000000000 +0200 -@@ -53,6 +53,9 @@ - #include "observer.h" - #include "complaints.h" - -+#include "auxv.h" -+#include "elf/common.h" -+ - /* Prototypes for local functions */ - - static void objfile_alloc_data (struct objfile *objfile); -@@ -280,9 +283,17 @@ init_entry_point_info (struct objfile *o - CORE_ADDR - entry_point_address (void) - { -+ int ret; -+ - struct gdbarch *gdbarch; - CORE_ADDR entry_point; - -+ /* Find the address of the entry point of the program from the -+ auxv vector. */ -+ ret = target_auxv_search (¤t_target, AT_ENTRY, &entry_point); -+ if (ret == 1) -+ return entry_point; -+ - if (symfile_objfile == NULL) - return 0; - -Index: gdb-6.8.91.20090925/gdb/solib-svr4.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/solib-svr4.c 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/solib-svr4.c 2009-09-25 10:28:07.000000000 +0200 -@@ -47,6 +47,7 @@ - #include "exec.h" - #include "auxv.h" - #include "exceptions.h" -+#include "command.h" - - static struct link_map_offsets *svr4_fetch_link_map_offsets (void); - static int svr4_have_link_map_offsets (void); -@@ -359,7 +360,9 @@ solib_svr4_inferior_exit (int pid) - - /* Local function prototypes */ - -+#if 0 - static int match_main (char *); -+#endif - - static CORE_ADDR bfd_lookup_symbol (bfd *, char *); - -@@ -600,10 +603,12 @@ scan_dyntag (int dyntag, bfd *abfd, CORE - int arch_size, step, sect_size; - long dyn_tag; - CORE_ADDR dyn_ptr, dyn_addr; -+ CORE_ADDR reloc_addr = 0; - gdb_byte *bufend, *bufstart, *buf; - Elf32_External_Dyn *x_dynp_32; - Elf64_External_Dyn *x_dynp_64; - struct bfd_section *sect; -+ int ret; - - if (abfd == NULL) - return 0; -@@ -615,19 +620,81 @@ scan_dyntag (int dyntag, bfd *abfd, CORE - if (arch_size == -1) - return 0; - -+ /* The auxv vector based relocatable files reading is limited to the main -+ executable. */ -+ gdb_assert (abfd == exec_bfd || ptr == NULL); -+ -+ if (ptr != NULL) -+ { -+ CORE_ADDR entry_addr; -+ -+ /* Find the address of the entry point of the program from the -+ auxv vector. */ -+ ret = target_auxv_search (¤t_target, AT_ENTRY, &entry_addr); -+ -+ if (ret == 0 || ret == -1) -+ { -+ /* No auxv info, maybe an older kernel. Fake our way through. */ -+ entry_addr = bfd_get_start_address (exec_bfd); -+ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: program entry address not found. Using bfd's %s for %s\n", -+ paddress (target_gdbarch, entry_addr), exec_bfd->filename); -+ } -+ else -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: found program entry address %s for %s\n", -+ paddress (target_gdbarch, entry_addr), exec_bfd->filename); -+ } -+ reloc_addr = entry_addr - bfd_get_start_address (exec_bfd); -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: expected relocation offset %s for %s\n", -+ paddress (target_gdbarch, reloc_addr), exec_bfd->filename); -+ } -+ - /* Find the start address of the .dynamic section. */ - sect = bfd_get_section_by_name (abfd, ".dynamic"); - if (sect == NULL) -- return 0; -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: .dynamic section not found in %s -- return now\n", -+ exec_bfd->filename); -+ return 0; -+ } -+ else -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: .dynamic section found in %s\n", -+ exec_bfd->filename); -+ } -+ - dyn_addr = bfd_section_vma (abfd, sect); -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: .dynamic addr %s\n", -+ paddress (target_gdbarch, dyn_addr)); - - /* Read in .dynamic from the BFD. We will get the actual value - from memory later. */ - sect_size = bfd_section_size (abfd, sect); - buf = bufstart = alloca (sect_size); -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: read in .dynamic section\n"); - if (!bfd_get_section_contents (abfd, sect, - buf, 0, sect_size)) -- return 0; -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: couldn't read .dynamic section -- return now\n"); -+ return 0; -+ } - - /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ - step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) -@@ -648,26 +715,105 @@ scan_dyntag (int dyntag, bfd *abfd, CORE - dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); - dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr); - } -- if (dyn_tag == DT_NULL) -+ -+ /* Verify RELOC_ADDR makes sense - it does not have to for valgrind which -+ supplies us a specially crafted executable in /proc/PID/fd/X while -+ /proc/PID/auxv corresponds to a different executable (.../memcheck). */ -+ if (reloc_addr) -+ { -+ gdb_byte tag_buf[8]; -+ CORE_ADDR tag_addr; -+ -+ tag_addr = dyn_addr + (buf - bufstart) + reloc_addr; -+ if (target_read_memory (tag_addr, tag_buf, arch_size / 8) == 0) -+ { -+ if (memcmp (tag_buf, buf, arch_size / 8) != 0) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: tag at offset 0x%lx does not match," -+ " dropping relocation offset %s\n", -+ (unsigned long) (buf - bufstart), paddress (target_gdbarch, reloc_addr)); -+ reloc_addr = 0; -+ } -+ } -+ else -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: tag at offset 0x%lx is not readable," -+ " dropping relocation offset %s\n", -+ (unsigned long) (buf - bufstart), paddress (target_gdbarch, reloc_addr)); -+ reloc_addr = 0; -+ } -+ } -+ -+ if (dyn_tag == DT_NULL) - return 0; -- if (dyn_tag == dyntag) -- { -- /* If requested, try to read the runtime value of this .dynamic -- entry. */ -- if (ptr) -- { -- struct type *ptr_type; -- gdb_byte ptr_buf[8]; -- CORE_ADDR ptr_addr; -- -- ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; -- ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; -- if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0) -- dyn_ptr = extract_typed_address (ptr_buf, ptr_type); -- *ptr = dyn_ptr; -- } -- return 1; -- } -+ if (dyn_tag == dyntag) -+ { -+ /* If requested, try to read the runtime value of this .dynamic -+ entry. */ -+ if (ptr) -+ { -+ gdb_byte ptr_buf[8]; -+ CORE_ADDR ptr_addr; -+ int got; -+ -+ ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; -+ if (ptr != NULL) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: unrelocated ptr addr %s\n", -+ paddress (target_gdbarch, ptr_addr)); -+ ptr_addr += reloc_addr; -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: relocated ptr addr %s" -+ " (relocation offset %s) for %s\n", -+ paddress (target_gdbarch, ptr_addr), paddress (target_gdbarch, reloc_addr), -+ exec_bfd->filename); -+ } -+ got = target_read_memory (ptr_addr, ptr_buf, arch_size / 8); -+ if (got != 0 && reloc_addr) -+ { -+ ptr_addr -= reloc_addr; -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: unrelocated back to ptr addr %s" -+ " as the memory was unreable for %s\n", -+ paddress (target_gdbarch, ptr_addr), exec_bfd->filename); -+ got = target_read_memory (ptr_addr, ptr_buf, arch_size / 8); -+ } -+ -+ if (got == 0) -+ { -+ struct type *ptr_type; -+ -+ ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; -+ dyn_ptr = extract_typed_address (ptr_buf, ptr_type); -+ if (ptr != NULL) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: Tag entry has value %s -- return now\n", -+ paddress (target_gdbarch, dyn_ptr)); -+ } -+ } -+ else -+ { -+ if (ptr != NULL) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "elf_locate_base: Couldn't read tag entry value -- return now\n"); -+ } -+ } -+ *ptr = dyn_ptr; -+ } -+ return 1; -+ } - } - - return 0; -@@ -1040,6 +1186,11 @@ svr4_current_sos (void) - CORE_ADDR ldsomap = 0; - struct inferior *inf; - struct svr4_info *info; -+ const char *filename = exec_bfd ? exec_bfd->filename : ""; -+ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: exec_bfd %s\n", filename); - - if (ptid_equal (inferior_ptid, null_ptid)) - return NULL; -@@ -1054,7 +1205,13 @@ svr4_current_sos (void) - /* If we can't find the dynamic linker's base structure, this - must not be a dynamically linked executable. Hmm. */ - if (! info->debug_base) -- return svr4_default_sos (); -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: no DT_DEBUG found in %s -- return now\n", -+ filename); -+ return svr4_default_sos (); -+ } - - /* Walk the inferior's link map list, and build our list of - `struct so_list' nodes. */ -@@ -1074,26 +1231,104 @@ svr4_current_sos (void) - new->lm_info->lm = xzalloc (lmo->link_map_size); - make_cleanup (xfree, new->lm_info->lm); - -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: read lm at %s\n", paddress (target_gdbarch, lm)); - read_memory (lm, new->lm_info->lm, lmo->link_map_size); - - lm = LM_NEXT (new); - -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: is first link entry? %d\n", -+ IGNORE_FIRST_LINK_MAP_ENTRY (new)); -+ - /* For SVR4 versions, the first entry in the link map is for the - inferior executable, so we must ignore it. For some versions of - SVR4, it has no name. For others (Solaris 2.3 for example), it - does have a name, so we can no longer use a missing name to - decide when to ignore it. */ -- if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0) -+ if (exec_bfd != NULL && IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0) - { -- info->main_lm_addr = new->lm_info->lm_addr; -- free_so (new); -- } -+ /* It is the first link map entry, i.e. it is the main executable. */ -+ -+ if (bfd_get_start_address (exec_bfd) == entry_point_address ()) -+ { -+ /* Non-pie case, main executable has not been relocated. */ -+ info->main_lm_addr = new->lm_info->lm_addr; -+ free_so (new); -+ } -+ else -+ { -+ /* Pie case, main executable has been relocated. */ -+ struct so_list *gdb_solib; -+ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: Processing first link map entry\n"); -+ strncpy (new->so_name, exec_bfd->filename, -+ SO_NAME_MAX_PATH_SIZE - 1); -+ new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -+ strcpy (new->so_original_name, new->so_name); -+ /*new->main = 1;*/ -+ new->main_relocated = 0; -+ -+ if (debug_solib) -+ { -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: Processing nameless DSO\n"); -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: adding name %s\n", -+ new->so_name); -+ } -+ -+ for (gdb_solib = master_so_list (); -+ gdb_solib; -+ gdb_solib = gdb_solib->next) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: compare gdb %s and new %s\n", -+ gdb_solib->so_name, new->so_name); -+ if (strcmp (gdb_solib->so_name, new->so_name) == 0) -+ if (gdb_solib->main_relocated) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: found main relocated\n"); -+ break; -+ } -+ } -+ -+ if ((gdb_solib && !gdb_solib->main_relocated) || (!gdb_solib)) -+ { -+ add_to_target_sections (0 /*from_tty*/, ¤t_target, new); -+ new->main = 1; -+ } -+ -+ /* We need this in the list of shared libs we return because -+ solib_add_stub will loop through it and add the symbol file. */ -+ new->next = 0; -+ *link_ptr = new; -+ link_ptr = &new->next; -+ } -+ } /* End of IGNORE_FIRST_LINK_MAP_ENTRY */ - else - { -+ /* This is not the first link map entry, i.e. is not the main -+ executable. Note however that it could be the DSO supplied on -+ certain systems (i.e. Linux 2.6) containing information about -+ the vsyscall page. We must ignore such entry. This entry is -+ nameless (just like the one for the main executable, sigh). */ -+ - int errcode; - char *buffer; - - /* Extract this shared object's name. */ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: read LM_NAME\n"); -+ - target_read_string (LM_NAME (new), &buffer, - SO_NAME_MAX_PATH_SIZE - 1, &errcode); - if (errcode != 0) -@@ -1101,63 +1336,76 @@ svr4_current_sos (void) - } - else - { -- struct build_id *build_id; -- -- strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1); -- new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -- /* May get overwritten below. */ -- strcpy (new->so_name, new->so_original_name); -- -- build_id = build_id_addr_get (LM_DYNAMIC_FROM_LINK_MAP (new)); -- if (build_id != NULL) -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: LM_NAME is <%s>\n", -+ buffer); -+ /* The name could be empty, in which case it is the -+ system supplied DSO. */ -+ if (strcmp (buffer, "") == 0) -+ free_so (new); -+ else - { -- char *name, *build_id_filename; -+ struct build_id *build_id; -+ -+ strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1); -+ new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -+ /* May get overwritten below. */ -+ strcpy (new->so_name, new->so_original_name); - -- /* Missing the build-id matching separate debug info file -- would be handled while SO_NAME gets loaded. */ -- name = build_id_to_filename (build_id, &build_id_filename, 0); -- if (name != NULL) -+ build_id = build_id_addr_get (LM_DYNAMIC_FROM_LINK_MAP (new)); -+ if (build_id != NULL) - { -- strncpy (new->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); -- new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -- xfree (name); -+ char *name, *build_id_filename; -+ -+ /* Missing the build-id matching separate debug info file -+ would be handled while SO_NAME gets loaded. */ -+ name = build_id_to_filename (build_id, &build_id_filename, 0); -+ if (name != NULL) -+ { -+ strncpy (new->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); -+ new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -+ xfree (name); -+ } -+ else -+ { -+ debug_print_missing (new->so_name, build_id_filename); -+ -+ /* In the case the main executable was found according to -+ its build-id (from a core file) prevent loading -+ a different build of a library with accidentally the -+ same SO_NAME. -+ -+ It suppresses bogus backtraces (and prints "??" there -+ instead) if the on-disk files no longer match the -+ running program version. */ -+ -+ if (symfile_objfile != NULL -+ && (symfile_objfile->flags -+ & OBJF_BUILD_ID_CORE_LOADED) != 0) -+ new->so_name[0] = 0; -+ } -+ -+ xfree (build_id_filename); -+ xfree (build_id); - } -- else -- { -- debug_print_missing (new->so_name, build_id_filename); - -- /* In the case the main executable was found according to -- its build-id (from a core file) prevent loading -- a different build of a library with accidentally the -- same SO_NAME. -- -- It suppresses bogus backtraces (and prints "??" there -- instead) if the on-disk files no longer match the -- running program version. */ -- -- if (symfile_objfile != NULL -- && (symfile_objfile->flags -- & OBJF_BUILD_ID_CORE_LOADED) != 0) -- new->so_name[0] = 0; -+ if (debug_solib) -+ { -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: Processing DSO: %s\n", -+ new->so_name); -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_current_sos: first link entry %d\n", -+ IGNORE_FIRST_LINK_MAP_ENTRY (new)); - } - -- xfree (build_id_filename); -- xfree (build_id); -+ new->next = 0; -+ *link_ptr = new; -+ link_ptr = &new->next; - } - } -- xfree (buffer); -- -- /* If this entry has no name, or its name matches the name -- for the main executable, don't include it in the list. */ -- if (! new->so_name[0] -- || match_main (new->so_name)) -- free_so (new); -- else -- { -- new->next = 0; -- *link_ptr = new; -- link_ptr = &new->next; -- } -+ xfree (buffer); - } - - /* On Solaris, the dynamic linker is not in the normal list of -@@ -1173,6 +1421,9 @@ svr4_current_sos (void) - if (head == NULL) - return svr4_default_sos (); - -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, "svr4_current_sos: ENDS %s\n", filename); -+ - return head; - } - -@@ -1205,7 +1456,7 @@ svr4_fetch_objfile_link_map (struct objf - /* On some systems, the only way to recognize the link map entry for - the main executable file is by looking at its name. Return - non-zero iff SONAME matches one of the known main executable names. */ -- -+#if 0 - static int - match_main (char *soname) - { -@@ -1219,6 +1470,7 @@ match_main (char *soname) - - return (0); - } -+#endif - - /* Return 1 if PC lies in the dynamic symbol resolution code of the - SVR4 run time loader. */ -@@ -1370,15 +1622,29 @@ enable_break (struct svr4_info *info) - /* Find the program interpreter; if not found, warn the user and drop - into the old breakpoint at symbol code. */ - interp_name = find_program_interpreter (); -+ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "enable_break: search for .interp in %s\n", -+ exec_bfd->filename); - if (interp_name) - { - CORE_ADDR load_addr = 0; -+ CORE_ADDR load_addr_mask = -1L; - int load_addr_found = 0; - int loader_found_in_list = 0; - struct so_list *so; - bfd *tmp_bfd = NULL; - struct target_ops *tmp_bfd_target; - volatile struct gdb_exception ex; -+ int arch_size; -+ -+ /* For 32bit inferiors with 64bit GDB we may get LOAD_ADDR at 0xff...... -+ and thus overflowing its addition to the address while CORE_ADDR is -+ 64bit producing 0x1........ address invalid across GDB. */ -+ arch_size = bfd_get_arch_size (exec_bfd); -+ if (arch_size > 0 && arch_size < sizeof (1UL) * 8) -+ load_addr_mask = (1UL << arch_size) - 1; - - sym_addr = 0; - -@@ -1395,6 +1661,9 @@ enable_break (struct svr4_info *info) - { - tmp_bfd = solib_bfd_open (interp_name); - } -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "enable_break: opening %s\n", interp_name); - if (tmp_bfd == NULL) - goto bkpt_at_symbol; - -@@ -1452,16 +1721,16 @@ enable_break (struct svr4_info *info) - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); - if (interp_sect) - { -- interp_text_sect_low = -- bfd_section_vma (tmp_bfd, interp_sect) + load_addr; -+ interp_text_sect_low = (bfd_section_vma (tmp_bfd, interp_sect) -+ + load_addr) & load_addr_mask; - interp_text_sect_high = - interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); - } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); - if (interp_sect) - { -- interp_plt_sect_low = -- bfd_section_vma (tmp_bfd, interp_sect) + load_addr; -+ interp_plt_sect_low = (bfd_section_vma (tmp_bfd, interp_sect) -+ + load_addr) & load_addr_mask; - interp_plt_sect_high = - interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); - } -@@ -1496,7 +1765,7 @@ enable_break (struct svr4_info *info) - - if (sym_addr != 0) - { -- create_solib_event_breakpoint (target_gdbarch, load_addr + sym_addr); -+ create_solib_event_breakpoint (target_gdbarch, (load_addr + sym_addr) & load_addr_mask); - xfree (interp_name); - return 1; - } -@@ -1769,6 +2038,9 @@ svr4_solib_create_inferior_hook (void) - while (tp->stop_signal != TARGET_SIGNAL_TRAP); - inf->stop_soon = NO_STOP_QUIETLY; - #endif /* defined(_SCO_DS) */ -+ -+ if (bfd_get_start_address (exec_bfd) != entry_point_address ()) -+ disable_breakpoints_before_startup (); - } - - static void -@@ -1945,6 +2217,76 @@ svr4_lp64_fetch_link_map_offsets (void) - - return lmp; - } -+void -+info_linkmap_command (char *cmd, int from_tty) -+{ -+ CORE_ADDR lm; -+ struct svr4_info *info = get_svr4_info (PIDGET (inferior_ptid)); -+ -+ /* Make sure we've looked up the inferior's dynamic linker's base -+ structure. */ -+ if (! info->debug_base) -+ { -+ info->debug_base = locate_base (info); -+ -+ /* If we can't find the dynamic linker's base structure, this -+ must not be a dynamically linked executable. Hmm. */ -+ if (! info->debug_base) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_print_linkmap: no DT_DEBUG found in %s -- return now\n", -+ exec_bfd->filename); -+ return; -+ } -+ } -+ -+ /* Walk the inferior's link map list, and print the info. */ -+ -+ lm = solib_svr4_r_map (info); -+ while (lm) -+ { -+ int errcode; -+ char *buffer; -+ CORE_ADDR load_addr; -+ -+ struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); -+ struct so_list *new -+ = (struct so_list *) xmalloc (sizeof (struct so_list)); -+ struct cleanup *old_chain = make_cleanup (xfree, new); -+ -+ memset (new, 0, sizeof (*new)); -+ -+ new->lm_info = xmalloc (sizeof (struct lm_info)); -+ make_cleanup (xfree, new->lm_info); -+ -+ new->lm_info->lm = xmalloc (lmo->link_map_size); -+ make_cleanup (xfree, new->lm_info->lm); -+ memset (new->lm_info->lm, 0, lmo->link_map_size); -+ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "svr4_print_linkmap: read lm at %s\n", paddress (target_gdbarch, lm)); -+ read_memory (lm, new->lm_info->lm, lmo->link_map_size); -+ -+ lm = LM_NEXT (new); -+ -+ /* Load address. */ -+ load_addr = LM_ADDR_CHECK (new, NULL); -+ /* Shared object's name. */ -+ target_read_string (LM_NAME (new), &buffer, -+ SO_NAME_MAX_PATH_SIZE - 1, &errcode); -+ make_cleanup (xfree, buffer); -+ if (errcode != 0) -+ { -+ warning ("svr4_print_linkmap: Can't read pathname for load map: %s\n", -+ safe_strerror (errcode)); -+ } -+ fprintf_filtered (gdb_stdout, "%-8s %-30s\n", paddress (target_gdbarch, load_addr), buffer); -+ do_cleanups (old_chain); -+ } -+} -+ - - - struct target_so_ops svr4_so_ops; -@@ -1985,4 +2327,7 @@ _initialize_svr4_solib (void) - svr4_so_ops.same = svr4_same; - - observer_attach_inferior_exit (solib_svr4_inferior_exit); -+ -+ add_info ("linkmap", info_linkmap_command, -+ "Display the inferior's linkmap."); - } -Index: gdb-6.8.91.20090925/gdb/solib.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/solib.c 2009-09-25 10:25:38.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/solib.c 2009-09-25 10:25:45.000000000 +0200 -@@ -82,6 +82,8 @@ set_solib_ops (struct gdbarch *gdbarch, - - /* external data declarations */ - -+int debug_solib; -+ - /* FIXME: gdbarch needs to control this variable, or else every - configuration needs to call set_solib_ops. */ - struct target_so_ops *current_target_so_ops; -@@ -105,6 +107,8 @@ The search path for loading non-absolute - value); - } - -+void add_to_target_sections (int, struct target_ops *, struct so_list *); -+ - /* - - GLOBAL FUNCTION -@@ -449,14 +453,38 @@ symbol_add_stub (struct so_list *so, int - /* Have we already loaded this shared object? */ - ALL_OBJFILES (so->objfile) - { -- if (strcmp (so->objfile->name, so->so_name) == 0) -+ /* Found an already loaded shared library. */ -+ if (strcmp (so->objfile->name, so->so_name) == 0 -+ && !so->main) -+ return; -+ /* Found an already loaded main executable. This could happen in -+ two circumstances. -+ First case: the main file has already been read in -+ as the first thing that gdb does at startup, and the file -+ hasn't been relocated properly yet. Therefor we need to read -+ it in with the proper section info. -+ Second case: it has been read in with the correct relocation, -+ and therefore we need to skip it. */ -+ if (strcmp (so->objfile->name, so->so_name) == 0 -+ && so->main -+ && so->main_relocated) - return; - } - - sap = build_section_addr_info_from_section_table (so->sections, - so->sections_end); - -- so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); -+ if (so->main) -+ { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "symbol_add_stub: adding symbols for main\n"); -+ so->objfile = symbol_file_add_from_bfd (so->abfd, (flags & ~SYMFILE_VERBOSE) | SYMFILE_MAINLINE, sap, 0); -+ so->main_relocated = 1; -+ } -+ else -+ so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); -+ - free_section_addr_info (sap); - - return; -@@ -596,6 +624,10 @@ update_solib_list (int from_tty, struct - } - else - { -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "update_solib_list: compare gdb:%s and inferior:%s\n", -+ gdb->so_original_name, i->so_original_name); - if (! strcmp (gdb->so_original_name, i->so_original_name)) - break; - } -@@ -650,18 +682,7 @@ update_solib_list (int from_tty, struct - /* Fill in the rest of each of the `struct so_list' nodes. */ - for (i = inferior; i; i = i->next) - { -- i->from_tty = from_tty; -- -- /* Fill in the rest of the `struct so_list' node. */ -- catch_errors (solib_map_sections, i, -- "Error while mapping shared library sections:\n", -- RETURN_MASK_ALL); -- -- /* Add the shared object's sections to the current set of -- file section tables. Do this immediately after mapping -- the object so that later nodes in the list can query this -- object, as is needed in solib-osf.c. */ -- add_target_sections (i->sections, i->sections_end); -+ add_to_target_sections (from_tty, target, i); - - /* Notify any observer that the shared object has been - loaded now that we've added it to GDB's tables. */ -@@ -771,6 +792,32 @@ solib_add (char *pattern, int from_tty, - } - } - -+void -+add_to_target_sections (int from_tty, struct target_ops *target, struct so_list *solib) -+{ -+ /* If this is set, then the sections have been already added to the -+ target list. */ -+ if (solib->main) -+ return; -+ -+ solib->from_tty = from_tty; -+ -+ /* Fill in the rest of the `struct so_list' node. */ -+ catch_errors (solib_map_sections, solib, -+ "Error while mapping shared library sections:\n", -+ RETURN_MASK_ALL); -+ -+ if (debug_solib) -+ fprintf_unfiltered (gdb_stdlog, -+ "add_to_target_sections: add %s to to_sections\n", -+ solib->so_original_name); -+ -+ /* Add the shared object's sections to the current set of -+ file section tables. Do this immediately after mapping -+ the object so that later nodes in the list can query this -+ object, as is needed in solib-osf.c. */ -+ add_target_sections (solib->sections, solib->sections_end); -+} - - /* - -@@ -1189,4 +1236,12 @@ This takes precedence over the environme - reload_shared_libraries, - show_solib_search_path, - &setlist, &showlist); -+ -+ add_setshow_boolean_cmd ("solib", no_class, &debug_solib, -+ _("\ -+Set debugging of GNU/Linux shlib module.\n"), _("\ -+Show debugging status of GNU/Linux shlib module.\n"), _("\ -+Enables printf debugging output of GNU/Linux shlib module.\n"), -+ NULL, NULL, -+ &setdebuglist, &showdebuglist); - } -Index: gdb-6.8.91.20090925/gdb/solist.h -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/solist.h 2009-09-25 10:25:38.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/solist.h 2009-09-25 10:25:45.000000000 +0200 -@@ -61,6 +61,8 @@ struct so_list - bfd *abfd; - char symbols_loaded; /* flag: symbols read in yet? */ - char from_tty; /* flag: print msgs? */ -+ char main; /* flag: is this the main executable? */ -+ char main_relocated; /* flag: has it been relocated yet? */ - struct objfile *objfile; /* objfile for loaded lib */ - struct target_section *sections; - struct target_section *sections_end; -@@ -147,4 +149,10 @@ struct symbol *solib_global_lookup (cons - const char *name, - const domain_enum domain); - -+/* Add the list of sections in so_list to the target to_sections. */ -+extern void add_to_target_sections (int, struct target_ops *, struct so_list *); -+ -+/* Controls the printing of debugging output. */ -+extern int debug_solib; -+ - #endif -Index: gdb-6.8.91.20090925/gdb/symfile-mem.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/symfile-mem.c 2009-09-25 10:25:38.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/symfile-mem.c 2009-09-25 10:25:45.000000000 +0200 -@@ -115,7 +115,7 @@ symbol_file_add_from_memory (struct bfd - ++i; - } - -- objf = symbol_file_add_from_bfd (nbfd, from_tty ? SYMFILE_VERBOSE : 0, -+ objf = symbol_file_add_from_bfd (nbfd, (from_tty ? SYMFILE_VERBOSE : 0) | SYMFILE_MAINLINE2_BOTH, - sai, OBJF_SHARED); - - /* This might change our ideas about frames already looked at. */ -Index: gdb-6.8.91.20090925/gdb/symfile.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/symfile.c 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/symfile.c 2009-09-25 10:25:45.000000000 +0200 -@@ -49,6 +49,7 @@ - #include "readline/readline.h" - #include "gdb_assert.h" - #include "block.h" -+#include "varobj.h" - #include "observer.h" - #include "exec.h" - #include "parser-defs.h" -@@ -779,7 +780,7 @@ syms_from_objfile (struct objfile *objfi - - /* Now either addrs or offsets is non-zero. */ - -- if (mainline) -+ if ((add_flags & SYMFILE_MAINLINE) && !(add_flags & SYMFILE_MAINLINE2_ONLY)) - { - /* We will modify the main symbol table, make sure that all its users - will be cleaned up if an error occurs during symbol reading. */ -@@ -807,7 +808,7 @@ syms_from_objfile (struct objfile *objfi - - We no longer warn if the lowest section is not a text segment (as - happens for the PA64 port. */ -- if (!mainline && addrs && addrs->other[0].name) -+ if (/*!mainline &&*/ addrs && addrs->other[0].name) - { - asection *lower_sect; - asection *sect; -@@ -890,7 +891,7 @@ syms_from_objfile (struct objfile *objfi - init_objfile_sect_indices (objfile); - } - -- (*objfile->sf->sym_read) (objfile, mainline); -+ (*objfile->sf->sym_read) (objfile, add_flags & SYMFILE_MAINLINE2_ONLY ? 2 : (add_flags & SYMFILE_MAINLINE ? 1 : 0)); - - /* Discard cleanups as symbol reading was successful. */ - -@@ -909,17 +910,22 @@ new_symfile_objfile (struct objfile *obj - /* If this is the main symbol file we have to clean up all users of the - old main symbol file. Otherwise it is sufficient to fixup all the - breakpoints that may have been redefined by this symbol file. */ -- if (add_flags & SYMFILE_MAINLINE) -+ if (add_flags & SYMFILE_MAINLINE && !(add_flags & SYMFILE_MAINLINE2_ONLY)) - { - /* OK, make it the "real" symbol file. */ - symfile_objfile = objfile; - - clear_symtab_users (); - } -- else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0) -+ else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0 -+ && (add_flags & SYMFILE_MAINLINE2_BOTH) == 0) - { - breakpoint_re_set (); - } -+ else -+ { -+ /* Don't reset breakpoints or it will screw up PIE. */ -+ } - - /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (&symfile_complaints, 0, add_flags & SYMFILE_VERBOSE); -@@ -973,7 +979,7 @@ symbol_file_add_with_addrs_or_offsets (b - /* Give user a chance to burp if we'd be - interactively wiping out any existing symbols. */ - -- if ((add_flags & SYMFILE_MAINLINE) -+ if ((add_flags & SYMFILE_MAINLINE) && !(add_flags & SYMFILE_MAINLINE2_ONLY) - && (have_full_symbols () || have_partial_symbols ()) - && from_tty - && (have_full_symbols () || have_partial_symbols ()) -@@ -1163,6 +1169,9 @@ symbol_file_clear (int from_tty) - symfile_objfile->name) - : !query (_("Discard symbol table? ")))) - error (_("Not confirmed.")); -+#ifdef CLEAR_SOLIB -+ CLEAR_SOLIB (); -+#endif - - free_all_objfiles (); - -@@ -3367,6 +3376,8 @@ reread_symbols (void) - /* Discard cleanups as symbol reading was successful. */ - discard_cleanups (old_cleanups); - -+ init_entry_point_info (objfile); -+ - /* If the mtime has changed between the time we set new_modtime - and now, we *want* this to be out of date, so don't call stat - again now. */ -Index: gdb-6.8.91.20090925/gdb/target.h -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/target.h 2009-09-25 10:25:38.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/target.h 2009-09-25 10:25:45.000000000 +0200 -@@ -545,7 +545,7 @@ struct target_ops - Return -1 if there is insufficient buffer for a whole entry. - Return 1 if an entry was read into *TYPEP and *VALP. */ - int (*to_auxv_parse) (struct target_ops *ops, gdb_byte **readptr, -- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp); -+ gdb_byte *endptr, ULONGEST *typep, CORE_ADDR *valp); - - /* Search SEARCH_SPACE_LEN bytes beginning at START_ADDR for the - sequence of bytes in PATTERN with length PATTERN_LEN. -Index: gdb-6.8.91.20090925/gdb/symfile.h -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/symfile.h 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/symfile.h 2009-09-25 10:25:45.000000000 +0200 -@@ -229,7 +229,13 @@ enum symfile_add_flags - SYMFILE_MAINLINE = 1 << 2, - - /* Do not call breakpoint_re_set when adding this symbol file. */ -- SYMFILE_DEFER_BP_RESET = 1 << 3 -+ SYMFILE_DEFER_BP_RESET = 1 << 3, -+ -+ /* Red Hat PIE patch: Like SYMFILE_MAINLINE but for mainline == 2. -+ Former code was checking `if (mainline)' being satisfied both by -+ standard 1 and rare 2, simulate it here. */ -+ SYMFILE_MAINLINE2_ONLY = 1 << 4, -+ SYMFILE_MAINLINE2_BOTH = SYMFILE_MAINLINE2_ONLY | SYMFILE_MAINLINE - }; - - extern void syms_from_objfile (struct objfile *, -Index: gdb-6.8.91.20090925/gdb/infcmd.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/infcmd.c 2009-09-25 10:25:39.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/infcmd.c 2009-09-25 10:25:45.000000000 +0200 -@@ -2308,6 +2308,9 @@ attach_command_post_wait (char *args, in - - post_create_inferior (¤t_target, from_tty); - -+ /* Undo the disable from post_create_inferior. */ -+ enable_breakpoints_after_startup (); -+ - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - -Index: gdb-6.8.91.20090925/gdb/linux-tdep.c -=================================================================== ---- gdb-6.8.91.20090925.orig/gdb/linux-tdep.c 2009-08-04 22:41:13.000000000 +0200 -+++ gdb-6.8.91.20090925/gdb/linux-tdep.c 2009-09-25 10:25:45.000000000 +0200 -@@ -163,5 +163,7 @@ in this session.\n")); - void - _initialize_linux_tdep (void) - { -+#if 0 /* gdb-6.3-pie-20050110.patch */ - observer_attach_executable_changed (check_is_pie_binary); -+#endif - } diff --git a/gdb-6.3-test-pie-20050107.patch b/gdb-6.3-test-pie-20050107.patch index 6ba24a0..9208981 100644 --- a/gdb-6.3-test-pie-20050107.patch +++ b/gdb-6.3-test-pie-20050107.patch @@ -436,7 +436,7 @@ Index: gdb-6.8.50.20090909/gdb/testsuite/gdb.pie/attach.exp =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gdb-6.8.50.20090909/gdb/testsuite/gdb.pie/attach.exp 2009-09-09 19:06:01.000000000 +0200 -@@ -0,0 +1,432 @@ +@@ -0,0 +1,433 @@ +# Copyright 1997, 1999, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify @@ -817,7 +817,8 @@ Index: gdb-6.8.50.20090909/gdb/testsuite/gdb.pie/attach.exp + -re ".*warning: reading register.*I.*O error.*$gdb_prompt $" { + fail "attach call, read register 3 error" + } -+ -re "Attaching to.*process $testpid.*libc.*$gdb_prompt $" { ++ -re "Attaching to.*process $testpid.*$gdb_prompt $" { ++ # libc is relocated, not relocated, therefore not printed. + pass "attach call" + } + -re "$gdb_prompt $" {fail "attach call"} diff --git a/gdb-7.0-upstream.patch b/gdb-7.0-upstream.patch index d6da0cf..4f466c7 100644 --- a/gdb-7.0-upstream.patch +++ b/gdb-7.0-upstream.patch @@ -262,3 +262,366 @@ ## -1 +1 @@ -7.0 +7.0.0.20091030-cvs + + + +http://sourceware.org/ml/gdb-patches/2009-11/msg00594.html +http://sourceware.org/ml/gdb-cvs/2009-11/msg00233.html +Subject: [patch] testsuite: bigcore.exp fuzzy PASS message fix + +Hi, + +seen needlessly fuzzy results: + -PASS: gdb.base/bigcore.exp: extract next heap (stop at 50) + -PASS: gdb.base/bigcore.exp: extract prev heap (stop at 50) + +PASS: gdb.base/bigcore.exp: extract next heap + +PASS: gdb.base/bigcore.exp: extract prev heap + +but the .exp file just is not patient enough: + -Total of 4292375328 (0xffd87320) bytes bytes 53 chunks + +Total of 4292422432 (0xffd92b20) bytes bytes 41 chunks + +Increased to 200. Tested on {x86_64,x86_64-m32}-fedora12-linux-gnu. + + +Thanks, +Jan + + +gdb/testsuite/ +2009-11-29 Jan Kratochvil + + * gdb.base/bigcore.exp (extract_heap): Set $lim limit to 200. + +--- a/gdb/testsuite/gdb.base/bigcore.exp ++++ b/gdb/testsuite/gdb.base/bigcore.exp +@@ -96,7 +96,7 @@ proc extract_heap { dir } { + } + -re " = \\(struct list \\*\\) (0x\[0-9a-f\]*).*$gdb_prompt $" { + set heap [concat $heap $expect_out(1,string)] +- if { $lim >= 50 } { ++ if { $lim >= 200 } { + pass "$test (stop at $lim)" + } else { + incr lim + + + +http://sourceware.org/ml/gdb-patches/2009-11/msg00593.html +http://sourceware.org/ml/gdb-cvs/2009-12/msg00013.html +Subject: [patch] testcase: Fix spurious structs.exp FAILs + +Hi, + +There were some rare unreproducible fuzzy FAILs seen on i386 (32-bit) inferiors: + + return foo2 + The location at which to store the function's return value is unknown. + If you continue, the return value that you specified will be ignored. + Make fun2 return now? (y or n) y + #0 main () at /rpmbuild/BUILD/gdb-7.0/gdb/testsuite/gdb.base/structs.c:435 + 435 L2 = fun2(); + (gdb) next + 436 L3 = fun3(); + (gdb) PASS: gdb.base/structs.exp: return foo; return 2 structs-tf-td + p/c L2 +-$4 = {a = -16 '\360', b = 0 '\000'} +-(gdb) PASS: gdb.base/structs.exp: value foo returned; return 2 structs-tf-td ++$4 = {a = 44 ',', b = 0 '\000'} ++(gdb) FAIL: gdb.base/structs.exp: value foo returned; return 2 structs-tf-td + +Apparently + a = 44 ',', +does not match + a = \[^,\}\]*, +which is needed for cases where L2 (L*) remains uninitialized with random +content. + +Alternative patch would just use regex `.*' and the whole new `chartest' and +`anychar_re' parts can be dropped. + +Formerly 9s, now 11s, without the $first optimization it would cost 47s. + +Testcase has been run on {x86_64,x86_64-m32}-fedora12-linux-gnu. + + +Thanks, +Jan + + +gdb/testsuite/ +2009-11-29 Jan Kratochvil + + Fix spurious false FAILs. + * gdb.base/structs.c (chartest): New. + (main): Fill-in chartest. + * gdb.base/structs.exp (anychar_re, first): New. + (start_structs_test): Import global anychar_re and first. + New gdb_test call "set print elements 300; ${testfile}" + (start_structs_test <$first>): New block. + (any): Import global anychar_re. New variable ac. Use ${ac}. + +--- a/gdb/testsuite/gdb.base/structs.c ++++ b/gdb/testsuite/gdb.base/structs.c +@@ -396,6 +396,8 @@ zed () + L18.r = 'Z'; + } + ++static struct { char c; } chartest[256]; ++ + int main() + { + #ifdef usestubs +@@ -404,6 +406,10 @@ int main() + #endif + int i; + ++ for (i = 0; i < 256; i++) ++ chartest[i].c = i; ++ chartest[0].c = 0; /* chartest-done */ ++ + Fun1(foo1); + Fun2(foo2); + Fun3(foo3); +--- a/gdb/testsuite/gdb.base/structs.exp ++++ b/gdb/testsuite/gdb.base/structs.exp +@@ -36,6 +36,9 @@ set testfile "structs" + set srcfile ${testfile}.c + set binfile ${objdir}/${subdir}/${testfile} + ++# Regex matching any value of `char' type like: a = 65 'A' ++set anychar_re {-?[0-9]{1,3} '(.|\\([0-7]{3}|[a-z]|\\|'))'} ++ + # Create and source the file that provides information about the + # compiler used to compile the test case. + +@@ -48,6 +51,7 @@ if [get_compiler_info ${binfile}] { + # the last TYPES field). Run the compmiled program up to "main". + # Also updates the global "testfile" to reflect the most recent build. + ++set first 1 + proc start_structs_test { types } { + global testfile + global srcfile +@@ -56,6 +60,8 @@ proc start_structs_test { types } { + global subdir + global srcdir + global gdb_prompt ++ global anychar_re ++ global first + + # Create the additional flags + set flags "debug" +@@ -91,6 +97,8 @@ proc start_structs_test { types } { + "set print address off; ${testfile}" + gdb_test "set width 0" "" \ + "set width 0; ${testfile}" ++ gdb_test "set print elements 300" "" \ ++ "set print elements 300; ${testfile}" + + # Advance to main + if { ![runto_main] } then { +@@ -100,6 +108,16 @@ proc start_structs_test { types } { + # Get the debug format + get_debug_format + ++ # Limit the slow $anychar_re{256} matching for better performance. ++ if $first { ++ set first 0 ++ ++ # Verify $anychar_re can match all the values of `char' type. ++ gdb_breakpoint [gdb_get_line_number "chartest-done"] ++ gdb_continue_to_breakpoint "chartest-done" ".*chartest-done.*" ++ gdb_test "p chartest" "= {({c = ${anychar_re}}, ){255}{c = ${anychar_re}}}" ++ } ++ + # check that at the struct containing all the relevant types is correct + set foo_t "type = struct struct[llength ${types}] \{" + for {set n 0} {$n<[llength ${types}]} {incr n} { +@@ -161,26 +179,28 @@ proc zed { n } { + } + + proc any { n } { +- return [lindex { +- "{}" +- "{a = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*, o = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*, o = \[^,\}\]*, p = \[^,\}\]*}" +- "{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*, o = \[^,\}\]*, p = \[^,\}\]*, q = \[^,\}\]*}" +- } $n] ++ global anychar_re ++ set ac $anychar_re ++ return [lindex [list \ ++ "{}" \ ++ "{a = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}, l = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}, l = ${ac}, m = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}, l = ${ac}, m = ${ac}, n = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}, l = ${ac}, m = ${ac}, n = ${ac}, o = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}, l = ${ac}, m = ${ac}, n = ${ac}, o = ${ac}, p = ${ac}}" \ ++ "{a = ${ac}, b = ${ac}, c = ${ac}, d = ${ac}, e = ${ac}, f = ${ac}, g = ${ac}, h = ${ac}, i = ${ac}, j = ${ac}, k = ${ac}, l = ${ac}, m = ${ac}, n = ${ac}, o = ${ac}, p = ${ac}, q = ${ac}}" \ ++ ] $n] + } + + # Given N (0..25), return the corresponding alphabetic letter in lower + + + +http://sourceware.org/ml/gdb-patches/2009-11/msg00573.html +http://sourceware.org/ml/gdb-cvs/2009-11/msg00232.html +Subject: [patch] testsuite fuzzy results fixup: foll-fork.exp + +Hi, + +one occasional timeout: + + (gdb) PASS: gdb.base/foll-fork.exp: default show parent follow, no catchpoints + next 2 +-callee: 9949 + 25 if (pid == 0) /* set breakpoint here */ +-(gdb) PASS: gdb.base/foll-fork.exp: default parent follow, no catchpoints ++(gdb) callee: 18747 ++FAIL: gdb.base/foll-fork.exp: (timeout) default parent follow, no catchpoints + +Dropped the strings as there is no "callee" string expectation in +foll-fork.exp. + + +and with glibc-debuginfo installed one gets: + +(gdb) break 39 +Reading in symbols for ../nptl/sysdeps/unix/sysv/linux/fork.c...done. +Breakpoint 12 at 0x3ad22a4876: file ../nptl/sysdeps/unix/sysv/linux/fork.c, line 39. +(gdb) FAIL: gdb.base/foll-fork.exp: unpatch child, breakpoint at exit call ++ +Breakpoint 12, __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/fork.c:158 +158 fresetlockfiles (); +(gdb) FAIL: gdb.base/foll-fork.exp: unpatch child, unpatched parent breakpoints from child (unknown output) + + +Thanks, +Jan + + +gdb/testsuite/ +2009-11-26 Jan Kratochvil + + * gdb.base/foll-fork.exp (unpatch child, breakpoint at exit call): + Force $srcfile file. + * gdb.base/foll-fork.c (callee): Comment out the printf call. + +--- a/gdb/testsuite/gdb.base/foll-fork.c ++++ b/gdb/testsuite/gdb.base/foll-fork.c +@@ -9,7 +9,8 @@ void callee (i) + int i; + #endif + { +- printf("callee: %d\n", i); ++ /* Any output corrupts GDB CLI expect strings. ++ printf("callee: %d\n", i); */ + } + + #ifdef PROTOTYPES +--- a/gdb/testsuite/gdb.base/foll-fork.exp ++++ b/gdb/testsuite/gdb.base/foll-fork.exp +@@ -240,7 +240,8 @@ proc catch_fork_unpatch_child {} { + # Delete all breakpoints and catchpoints. + delete_breakpoints + +- gdb_test "break $bp_exit" \ ++ # Force $srcfile as the current GDB source can be in glibc sourcetree. ++ gdb_test "break $srcfile:$bp_exit" \ + "Breakpoint .*file .*$srcfile, line .*" \ + "unpatch child, breakpoint at exit call" + + + + +http://sourceware.org/ml/gdb-patches/2009-11/msg00388.html +http://sourceware.org/ml/gdb-cvs/2009-11/msg00156.html +Subject: [patch] Fix crash on reading stabs + +Hi, + +there is a crash on reading stabs fpc binary: + https://bugzilla.redhat.com/show_bug.cgi?id=537837 + +Program received signal SIGSEGV, Segmentation fault. +0x000000000069db3d in read_dbx_symtab (objfile=0x1daf5f0) at dbxread.c:1369 +1369 if ((namestring[0] == '-' && namestring[1] == 'l') + +(gdb) p/x nlist.n_strx +$7 = 0xfffffff8 +(gdb) p sizeof(nlist.n_strx) +$10 = 8 + +Below the patch context is: + namestring = (nlist->n_strx + file_string_table_offset + + DBX_STRINGTAB (objfile)); + +so IMO the `(unsigned)' cast is excessive as it does not match the expression +below. Such cast is there since the GDB "Initial revision" (1999). + +`n_strx' type: +struct internal_nlist +{ + unsigned long n_strx; /* Index into string table of name. */ +... +}; + +Regression tested on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu which does not +mean anything with the default DWARF debug info. It was hanging for stabs so +tried just a large part of gdb.base/*.exp on x86_64-m32 - `unix/-gstabs+/-m32'. + +If it isn't obviously approved please feel free to drop it as one should not +use STABS in the first place. + + +Regards, +Jan + + +gdb/ +2009-11-17 Jan Kratochvil + + * dbxread.c (set_namestring): Remove cast to unsigned. Check N_STRX + overflow. + +--- a/gdb/dbxread.c ++++ b/gdb/dbxread.c +@@ -965,8 +965,9 @@ set_namestring (struct objfile *objfile, const struct internal_nlist *nlist) + { + char *namestring; + +- if (((unsigned) nlist->n_strx + file_string_table_offset) +- >= DBX_STRINGTAB_SIZE (objfile)) ++ if (nlist->n_strx + file_string_table_offset ++ >= DBX_STRINGTAB_SIZE (objfile) ++ || nlist->n_strx + file_string_table_offset < nlist->n_strx) + { + complaint (&symfile_complaints, _("bad string table offset in symbol %d"), + symnum); + diff --git a/gdb-archer-pie-addons.patch b/gdb-archer-pie-addons.patch new file mode 100644 index 0000000..387dfc1 --- /dev/null +++ b/gdb-archer-pie-addons.patch @@ -0,0 +1,290 @@ +--- a/gdb/dwarf2read.c ++++ b/gdb/dwarf2read.c +@@ -5754,7 +5754,12 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) + { + struct attribute *attr; + struct symbol *sym; +- CORE_ADDR base = (CORE_ADDR) 0; ++ struct objfile *objfile = cu->objfile; ++ CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets, ++ SECT_OFF_TEXT (objfile)); ++ /* This is used only for DW_AT_data_member_location entries. */ ++ CORE_ADDR base = 0; ++ int base_p = 0; + + attr = dwarf2_attr (die, DW_AT_location, cu); + if (attr) +@@ -5763,6 +5768,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) + if (attr_form_is_block (attr)) + { + base = decode_locdesc (DW_BLOCK (attr), cu); ++ base_p = 1; + } + else if (attr_form_is_section_offset (attr)) + { +@@ -5824,12 +5830,15 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) + else + dwarf2_complex_location_expr_complaint (); + +- SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset; ++ if (!base_p) ++ dwarf2_invalid_attrib_class_complaint ++ ("DW_AT_data_member_location", "common block member"); ++ SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset + baseaddr; + add_symbol_to_list (sym, &global_symbols); + } + + if (SYMBOL_CLASS (sym) == LOC_STATIC) +- SET_FIELD_PHYSADDR (*field, SYMBOL_VALUE_ADDRESS (sym)); ++ SET_FIELD_PHYSADDR (*field, SYMBOL_VALUE_ADDRESS (sym) - baseaddr); + else + SET_FIELD_PHYSNAME (*field, SYMBOL_LINKAGE_NAME (sym)); + FIELD_TYPE (*field) = SYMBOL_TYPE (sym); +@@ -5843,7 +5852,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) + + sym = new_symbol (die, type, cu); + /* SYMBOL_VALUE_ADDRESS never gets used as all its fields are static. */ +- SYMBOL_VALUE_ADDRESS (sym) = base; ++ SYMBOL_VALUE_ADDRESS (sym) = base + baseaddr; + + set_die_type (die, type, cu); + } +--- a/gdb/exec.c ++++ b/gdb/exec.c +@@ -32,6 +32,7 @@ + #include "exec.h" + #include "observer.h" + #include "arch-utils.h" ++#include "solib.h" + + #include + #include "readline/readline.h" +@@ -220,6 +221,10 @@ exec_file_attach (char *filename, int from_tty) + char *scratch_pathname; + int scratch_chan; + struct target_section *sections = NULL, *sections_end = NULL; ++ struct target_section *p; ++ int addr_bit; ++ CORE_ADDR mask = CORE_ADDR_MAX; ++ CORE_ADDR displacement; + + scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, + write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, +@@ -288,12 +293,23 @@ exec_file_attach (char *filename, int from_tty) + scratch_pathname, bfd_errmsg (bfd_get_error ())); + } + ++ set_gdbarch_from_file (exec_bfd); ++ ++ addr_bit = gdbarch_addr_bit (target_gdbarch); ++ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) ++ mask = ((CORE_ADDR) 1 << addr_bit) - 1; ++ ++ displacement = solib_exec_displacement (); ++ for (p = sections; p < sections_end; p++) ++ { ++ p->addr = (p->addr + displacement) & mask; ++ p->endaddr = (p->endaddr + displacement) & mask; ++ } ++ + exec_bfd_mtime = bfd_get_mtime (exec_bfd); + + validate_files (); + +- set_gdbarch_from_file (exec_bfd); +- + /* Add the executable's sections to the current address spaces' + list of sections. */ + add_target_sections (sections, sections_end); +--- a/gdb/gdbtypes.h ++++ b/gdb/gdbtypes.h +@@ -966,6 +966,7 @@ extern void allocate_cplus_struct_type (struct type *); + #define FIELD_LOC_KIND(thisfld) ((thisfld).loc_kind) + #define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos) + #define FIELD_STATIC_PHYSNAME(thisfld) ((thisfld).loc.physname) ++/* This address is unrelocated by the objfile's ANOFFSET. */ + #define FIELD_STATIC_PHYSADDR(thisfld) ((thisfld).loc.physaddr) + #define FIELD_DWARF_BLOCK(thisfld) ((thisfld).loc.dwarf_block) + #define SET_FIELD_BITPOS(thisfld, bitpos) \ +@@ -974,6 +975,7 @@ extern void allocate_cplus_struct_type (struct type *); + #define SET_FIELD_PHYSNAME(thisfld, name) \ + (FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_PHYSNAME, \ + FIELD_STATIC_PHYSNAME (thisfld) = (name)) ++/* This address is unrelocated by the objfile's ANOFFSET. */ + #define SET_FIELD_PHYSADDR(thisfld, addr) \ + (FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_PHYSADDR, \ + FIELD_STATIC_PHYSADDR (thisfld) = (addr)) +@@ -989,6 +991,7 @@ extern void allocate_cplus_struct_type (struct type *); + #define TYPE_FIELD_LOC_KIND(thistype, n) FIELD_LOC_KIND (TYPE_FIELD (thistype, n)) + #define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS (TYPE_FIELD (thistype, n)) + #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_STATIC_PHYSNAME (TYPE_FIELD (thistype, n)) ++/* This address is unrelocated by the objfile's ANOFFSET. */ + #define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_STATIC_PHYSADDR (TYPE_FIELD (thistype, n)) + #define TYPE_FIELD_DWARF_BLOCK(thistype, n) FIELD_DWARF_BLOCK (TYPE_FIELD (thistype, n)) + #define TYPE_FIELD_ARTIFICIAL(thistype, n) FIELD_ARTIFICIAL(TYPE_FIELD(thistype,n)) +--- a/gdb/jv-lang.c ++++ b/gdb/jv-lang.c +@@ -416,7 +416,8 @@ java_link_class_type (struct gdbarch *gdbarch, + + fields = NULL; + nfields--; /* First set up dummy "class" field. */ +- SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas)); ++ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas) ++ - (TYPE_OBJFILE (type) == NULL ? 0 : ANOFFSET (TYPE_OBJFILE (type)->section_offsets, SECT_OFF_TEXT (TYPE_OBJFILE (type))))); + TYPE_FIELD_NAME (type, nfields) = "class"; + TYPE_FIELD_TYPE (type, nfields) = value_type (clas); + SET_TYPE_FIELD_PRIVATE (type, nfields); +@@ -462,7 +463,8 @@ java_link_class_type (struct gdbarch *gdbarch, + SET_TYPE_FIELD_PROTECTED (type, i); + } + if (accflags & 0x0008) /* ACC_STATIC */ +- SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset); ++ SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset ++ - (TYPE_OBJFILE (type) == NULL ? 0 : ANOFFSET (TYPE_OBJFILE (type)->section_offsets, SECT_OFF_TEXT (TYPE_OBJFILE (type))))); + else + TYPE_FIELD_BITPOS (type, i) = 8 * boffset; + if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */ +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -1621,7 +1621,10 @@ svr4_exec_displacement (void) + if (target_auxv_search (¤t_target, AT_ENTRY, &entry_point) == 1) + return entry_point - exec_entry_point (exec_bfd, ¤t_target); + +- return svr4_static_exec_displacement (); ++ if (!ptid_equal (inferior_ptid, null_ptid)) ++ return svr4_static_exec_displacement (); ++ ++ return 0; + } + + /* Relocate the main executable. This function should be called upon +@@ -1632,7 +1635,7 @@ svr4_exec_displacement (void) + static void + svr4_relocate_main_executable (void) + { +- CORE_ADDR displacement = svr4_exec_displacement (); ++ CORE_ADDR displacement = solib_exec_displacement (); + + /* Even if DISPLACEMENT is 0 still try to relocate it as this is a new + difference of in-memory vs. in-file addresses and we could already +@@ -1975,6 +1978,7 @@ _initialize_svr4_solib (void) + svr4_so_ops.free_so = svr4_free_so; + svr4_so_ops.clear_solib = svr4_clear_solib; + svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook; ++ svr4_so_ops.exec_displacement = svr4_exec_displacement; + svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling; + svr4_so_ops.current_sos = svr4_current_sos; + svr4_so_ops.open_symbol_file_object = open_symbol_file_object; +--- a/gdb/solib.c ++++ b/gdb/solib.c +@@ -1014,6 +1014,19 @@ solib_create_inferior_hook (int from_tty) + ops->solib_create_inferior_hook (from_tty); + } + ++/* Query the difference of in-memory VMA addresses vs. exec_bfd VMAs. */ ++ ++CORE_ADDR ++solib_exec_displacement (void) ++{ ++ struct target_so_ops *ops = solib_ops (target_gdbarch); ++ ++ if (ops->exec_displacement != NULL) ++ return (*ops->exec_displacement) (); ++ else ++ return 0; ++} ++ + /* GLOBAL FUNCTION + + in_solib_dynsym_resolve_code -- check to see if an address is in +--- a/gdb/solib.h ++++ b/gdb/solib.h +@@ -43,6 +43,8 @@ extern int solib_read_symbols (struct so_list *, int); + + extern void solib_create_inferior_hook (int from_tty); + ++extern CORE_ADDR solib_exec_displacement (void); ++ + /* If ADDR lies in a shared library, return its name. */ + + extern char *solib_name_from_address (CORE_ADDR); +--- a/gdb/solist.h ++++ b/gdb/solist.h +@@ -89,6 +89,9 @@ struct target_so_ops + /* Target dependent code to run after child process fork. */ + void (*solib_create_inferior_hook) (int from_tty); + ++ /* Query the difference of in-memory VMA addresses vs. exec_bfd VMAs. */ ++ CORE_ADDR (*exec_displacement) (void); ++ + /* Do additional symbol handling, lookup, etc. after symbols + for a shared object have been loaded. */ + void (*special_symbol_handling) (void); +--- a/gdb/symfile.c ++++ b/gdb/symfile.c +@@ -873,15 +873,36 @@ syms_from_objfile (struct objfile *objfile, + if an error occurs during symbol reading. */ + old_chain = make_cleanup_free_objfile (objfile); + +- /* If ADDRS and OFFSETS are both NULL, put together a dummy address +- list. We now establish the convention that an addr of zero means +- no load address was specified. */ ++ /* If ADDRS and OFFSETS are both NULL, put together a dummy offset list. */ ++ + if (! addrs && ! offsets) + { +- local_addr +- = alloc_section_addr_info (bfd_count_sections (objfile->obfd)); +- make_cleanup (xfree, local_addr); +- addrs = local_addr; ++ /* Relocateble files have an exception in default_symfile_offsets which ++ applies only for ADDRS. But calling solib_exec_displacement is more ++ suitable for OFFSETS. Fortunately we never need the both ++ functionalities simultaneously and in other cases zeroed ADDRS and ++ zeroed OFFSETS are equivalent. */ ++ ++ if ((bfd_get_file_flags (objfile->obfd) & (EXEC_P | DYNAMIC)) == 0) ++ { ++ local_addr ++ = alloc_section_addr_info (bfd_count_sections (objfile->obfd)); ++ make_cleanup (xfree, local_addr); ++ addrs = local_addr; ++ } ++ else ++ { ++ CORE_ADDR displacement = 0; ++ int i; ++ ++ if (mainline) ++ displacement = solib_exec_displacement (); ++ ++ num_offsets = bfd_count_sections (objfile->obfd); ++ offsets = alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets)); ++ for (i = 0; i < num_offsets; i++) ++ offsets->offsets[i] = displacement; ++ } + } + + /* Now either addrs or offsets is non-zero. */ +--- a/gdb/value.c ++++ b/gdb/value.c +@@ -1890,7 +1890,8 @@ value_static_field (struct type *type, int fieldno) + if (TYPE_FIELD_LOC_KIND (type, fieldno) == FIELD_LOC_KIND_PHYSADDR) + { + retval = value_at (TYPE_FIELD_TYPE (type, fieldno), +- TYPE_FIELD_STATIC_PHYSADDR (type, fieldno)); ++ TYPE_FIELD_STATIC_PHYSADDR (type, fieldno) ++ + (TYPE_OBJFILE (type) == NULL ? 0 : ANOFFSET (TYPE_OBJFILE (type)->section_offsets, SECT_OFF_TEXT (TYPE_OBJFILE (type))))); + } + else + { +@@ -1920,7 +1921,8 @@ value_static_field (struct type *type, int fieldno) + } + if (retval && VALUE_LVAL (retval) == lval_memory) + SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), +- value_address (retval)); ++ value_address (retval) ++ - (TYPE_OBJFILE (type) == NULL ? 0 : ANOFFSET (TYPE_OBJFILE (type)->section_offsets, SECT_OFF_TEXT (TYPE_OBJFILE (type))))); + } + return retval; + } diff --git a/gdb-archer-pie.patch b/gdb-archer-pie.patch new file mode 100644 index 0000000..0c8aabb --- /dev/null +++ b/gdb-archer-pie.patch @@ -0,0 +1,2647 @@ +http://sourceware.org/gdb/wiki/ProjectArcher +http://sourceware.org/gdb/wiki/ArcherBranchManagement + +archer-jankratochvil-pie-fedora12 +GIT snapshot: +commit 2ae60b5156d43aabfe5757940eaf7b4370fb05d2 + + +diff --git a/gdb/auxv.c b/gdb/auxv.c +index 7b4ecbe..7df8eb5 100644 +--- a/gdb/auxv.c ++++ b/gdb/auxv.c +@@ -25,6 +25,7 @@ + #include "inferior.h" + #include "valprint.h" + #include "gdb_assert.h" ++#include "gdbcore.h" + + #include "auxv.h" + #include "elf/common.h" +@@ -33,15 +34,11 @@ + #include + + +-/* This function is called like a to_xfer_partial hook, but must be +- called with TARGET_OBJECT_AUXV. It handles access via +- /proc/PID/auxv, which is a common method for native targets. */ ++/* This function handles access via /proc/PID/auxv, which is a common method ++ for native targets. */ + +-LONGEST +-procfs_xfer_auxv (struct target_ops *ops, +- enum target_object object, +- const char *annex, +- gdb_byte *readbuf, ++static LONGEST ++procfs_xfer_auxv (gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, + LONGEST len) +@@ -50,9 +47,6 @@ procfs_xfer_auxv (struct target_ops *ops, + int fd; + LONGEST n; + +- gdb_assert (object == TARGET_OBJECT_AUXV); +- gdb_assert (readbuf || writebuf); +- + pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid)); + fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY); + xfree (pathname); +@@ -72,6 +66,152 @@ procfs_xfer_auxv (struct target_ops *ops, + return n; + } + ++/* This function handles access via ld.so's symbol `_dl_auxv'. */ ++ ++static LONGEST ++ld_so_xfer_auxv (gdb_byte *readbuf, ++ const gdb_byte *writebuf, ++ ULONGEST offset, ++ LONGEST len) ++{ ++ struct minimal_symbol *msym; ++ CORE_ADDR data_address, pointer_address; ++ struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; ++ size_t ptr_size = TYPE_LENGTH (ptr_type); ++ size_t auxv_pair_size = 2 * ptr_size; ++ gdb_byte *ptr_buf = alloca (ptr_size); ++ LONGEST retval; ++ size_t block; ++ ++ msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL); ++ if (msym == NULL) ++ return -1; ++ ++ if (MSYMBOL_SIZE (msym) != ptr_size) ++ return -1; ++ ++ /* POINTER_ADDRESS is a location where the `_dl_auxv' variable resides. ++ DATA_ADDRESS is the inferior value present in `_dl_auxv', therefore the ++ real inferior AUXV address. */ ++ ++ pointer_address = SYMBOL_VALUE_ADDRESS (msym); ++ ++ data_address = read_memory_typed_address (pointer_address, ptr_type); ++ ++ /* Possibly still not initialized such as during an inferior startup. */ ++ if (data_address == 0) ++ return -1; ++ ++ data_address += offset; ++ ++ if (writebuf != NULL) ++ { ++ if (target_write_memory (data_address, writebuf, len) == 0) ++ return len; ++ else ++ return -1; ++ } ++ ++ /* Stop if trying to read past the existing AUXV block. The final AT_NULL ++ was already returned before. */ ++ ++ if (offset >= auxv_pair_size) ++ { ++ if (target_read_memory (data_address - auxv_pair_size, ptr_buf, ++ ptr_size) != 0) ++ return -1; ++ ++ if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL) ++ return 0; ++ } ++ ++ retval = 0; ++ block = 0x400; ++ gdb_assert (block % auxv_pair_size == 0); ++ ++ while (len > 0) ++ { ++ if (block > len) ++ block = len; ++ ++ /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported. Tails ++ unaligned to AUXV_PAIR_SIZE will not be read during a call (they ++ should be completed during next read with new/extended buffer). */ ++ ++ block &= -auxv_pair_size; ++ if (block == 0) ++ return retval; ++ ++ if (target_read_memory (data_address, readbuf, block) != 0) ++ { ++ if (block <= auxv_pair_size) ++ return retval; ++ ++ block = auxv_pair_size; ++ continue; ++ } ++ ++ data_address += block; ++ len -= block; ++ ++ /* Check terminal AT_NULL. This function is being called indefinitely ++ being extended its READBUF until it returns EOF (0). */ ++ ++ while (block >= auxv_pair_size) ++ { ++ retval += auxv_pair_size; ++ ++ if (extract_typed_address (readbuf, ptr_type) == AT_NULL) ++ return retval; ++ ++ readbuf += auxv_pair_size; ++ block -= auxv_pair_size; ++ } ++ } ++ ++ return retval; ++} ++ ++/* This function is called like a to_xfer_partial hook, but must be ++ called with TARGET_OBJECT_AUXV. It handles access to AUXV. */ ++ ++LONGEST ++memory_xfer_auxv (struct target_ops *ops, ++ enum target_object object, ++ const char *annex, ++ gdb_byte *readbuf, ++ const gdb_byte *writebuf, ++ ULONGEST offset, ++ LONGEST len) ++{ ++ /* Workaround gdb-7.0 bug where linux_nat_xfer_partial() does ++ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid)); ++ and current_inferior() assertion fails not finding the LWP->PID. ++ It got fixed post-gdb-7.0 by: ++ Add base multi-executable/process support to GDB. ++ 40ff0a289e6165aa930af284df5c52162cb0cd5f ++ by introducing `current_inferior_'. */ ++ struct inferior *inf = find_inferior_pid (ptid_get_pid (inferior_ptid)); ++ ++ gdb_assert (object == TARGET_OBJECT_AUXV); ++ gdb_assert (readbuf || writebuf); ++ ++ /* ld_so_xfer_auxv is the only function safe for virtual executables being ++ executed by valgrind's memcheck. As using ld_so_xfer_auxv is problematic ++ during inferior startup GDB does call it only for attached processes. */ ++ ++ if (inf == NULL || inf->attach_flag != 0) ++ { ++ LONGEST retval; ++ ++ retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len); ++ if (retval != -1) ++ return retval; ++ } ++ ++ return procfs_xfer_auxv (readbuf, writebuf, offset, len); ++} ++ + /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. + Return 0 if *READPTR is already at the end of the buffer. + Return -1 if there is insufficient buffer for a whole entry. +diff --git a/gdb/auxv.h b/gdb/auxv.h +index 71e6562..87c24ae 100644 +--- a/gdb/auxv.h ++++ b/gdb/auxv.h +@@ -43,11 +43,7 @@ extern int target_auxv_search (struct target_ops *ops, + /* Print the contents of the target's AUXV on the specified file. */ + extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops); + +-/* This function is called like a to_xfer_partial hook, but must be +- called with TARGET_OBJECT_AUXV. It handles access via +- /proc/PID/auxv, which is a common method for native targets. */ +- +-extern LONGEST procfs_xfer_auxv (struct target_ops *ops, ++extern LONGEST memory_xfer_auxv (struct target_ops *ops, + enum target_object object, + const char *annex, + gdb_byte *readbuf, +diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c +index 0f35101..bffc5a6 100644 +--- a/gdb/breakpoint.c ++++ b/gdb/breakpoint.c +@@ -4805,7 +4805,8 @@ disable_breakpoints_in_shlibs (void) + to insert those breakpoints and fail. */ + if (((b->type == bp_breakpoint) + || (b->type == bp_hardware_breakpoint) +- || (b->type == bp_tracepoint)) ++ || (b->type == bp_tracepoint) ++ || b->type == bp_shlib_event) + && !loc->shlib_disabled + #ifdef PC_SOLIB + && PC_SOLIB (loc->address) +diff --git a/gdb/defs.h b/gdb/defs.h +index 94674dc..57aaae2 100644 +--- a/gdb/defs.h ++++ b/gdb/defs.h +@@ -98,7 +98,20 @@ + /* A byte from the program being debugged. */ + typedef bfd_byte gdb_byte; + +-/* An address in the program being debugged. Host byte order. */ ++/* An address in the program being debugged. Host byte order. ++ ++ Its width is the maximum width of all the supported targets. That means ++ 32-bit target will run on such GDB using 64-bit CORE_ADDR cluttering the ++ bits 32...63 with random data from internal GDB calculations. GDB currently ++ in general truncates the address width only when it is being presented/used ++ externally (such as by the paddress function). ++ ++ FIXME: This is still not right as any GDB internal comparisons (such as >=) ++ of CORE_ADDR do not use the properly truncated width. As converting all the ++ CORE_ADDR operations to width-aware functions is not feasible the way out ++ could be a width-aware C++ class CORE_ADDR referencing gdbarch as its ++ constructor parameter. */ ++ + typedef bfd_vma CORE_ADDR; + + /* The largest CORE_ADDR value. */ +diff --git a/gdb/exec.c b/gdb/exec.c +index 455151e..67f40d9 100644 +--- a/gdb/exec.c ++++ b/gdb/exec.c +@@ -656,8 +656,33 @@ print_section_info (struct target_section_table *t, bfd *abfd) + wrap_here (" "); + printf_filtered (_("file type %s.\n"), bfd_get_target (abfd)); + if (abfd == exec_bfd) +- printf_filtered (_("\tEntry point: %s\n"), +- paddress (gdbarch, bfd_get_start_address (abfd))); ++ { ++ bfd_vma displacement = 0; ++ ++ for (p = t->sections; p < t->sections_end; p++) ++ { ++ asection *asect = p->the_bfd_section; ++ ++ if ((bfd_get_section_flags (abfd, asect) & (SEC_ALLOC | SEC_LOAD)) ++ != (SEC_ALLOC | SEC_LOAD)) ++ continue; ++ ++ if (bfd_get_section_vma (abfd, asect) <= abfd->start_address ++ && abfd->start_address < bfd_get_section_vma (abfd, asect) ++ + bfd_get_section_size (asect)) ++ { ++ displacement = p->addr - bfd_get_section_vma (abfd, asect); ++ break; ++ } ++ } ++ if (p == t->sections_end) ++ warning (_("Cannot find section for the entry point of %s.\n"), ++ bfd_get_filename (abfd)); ++ ++ printf_filtered (_("\tEntry point: %s\n"), ++ paddress (gdbarch, bfd_get_start_address (abfd) ++ + displacement)); ++ } + for (p = t->sections; p < t->sections_end; p++) + { + printf_filtered ("\t%s", hex_string_custom (p->addr, wid)); +diff --git a/gdb/infcmd.c b/gdb/infcmd.c +index fab1892..fc0f05d 100644 +--- a/gdb/infcmd.c ++++ b/gdb/infcmd.c +@@ -395,22 +395,6 @@ post_create_inferior (struct target_ops *target, int from_tty) + /* Now that we know the register layout, retrieve current PC. */ + stop_pc = regcache_read_pc (get_current_regcache ()); + +- /* If the solist is global across processes, there's no need to +- refetch it here. */ +- if (exec_bfd && !gdbarch_has_global_solist (target_gdbarch)) +- { +- /* Sometimes the platform-specific hook loads initial shared +- libraries, and sometimes it doesn't. Try to do so first, so +- that we can add them with the correct value for FROM_TTY. +- If we made all the inferior hook methods consistent, +- this call could be removed. */ +-#ifdef SOLIB_ADD +- SOLIB_ADD (NULL, from_tty, target, auto_solib_add); +-#else +- solib_add (NULL, from_tty, target, auto_solib_add); +-#endif +- } +- + if (exec_bfd) + { + /* Create the hooks to handle shared library load and unload +@@ -418,7 +402,25 @@ post_create_inferior (struct target_ops *target, int from_tty) + #ifdef SOLIB_CREATE_INFERIOR_HOOK + SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid)); + #else +- solib_create_inferior_hook (); ++ solib_create_inferior_hook (from_tty); ++#endif ++ } ++ ++ /* If the solist is global across processes, there's no need to ++ refetch it here. */ ++ if (exec_bfd && !gdbarch_has_global_solist (target_gdbarch)) ++ { ++ /* Sometimes the platform-specific hook loads initial shared ++ libraries, and sometimes it doesn't. If it doesn't FROM_TTY will be ++ incorrectly 0 but such solib targets should be fixed anyway. If we ++ made all the inferior hook methods consistent, this call could be ++ removed. Call it only after the solib target has been initialized by ++ solib_create_inferior_hook. */ ++ ++#ifdef SOLIB_ADD ++ SOLIB_ADD (NULL, 0, target, auto_solib_add); ++#else ++ solib_add (NULL, 0, target, auto_solib_add); + #endif + } + +diff --git a/gdb/infrun.c b/gdb/infrun.c +index 9d29b15..ed451d5 100644 +--- a/gdb/infrun.c ++++ b/gdb/infrun.c +@@ -544,7 +544,7 @@ follow_exec (ptid_t pid, char *execd_pathname) + #ifdef SOLIB_CREATE_INFERIOR_HOOK + SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid)); + #else +- solib_create_inferior_hook (); ++ solib_create_inferior_hook (0); + #endif + + jit_inferior_created_hook (); +diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c +index 0907f03..1c18782 100644 +--- a/gdb/linux-nat.c ++++ b/gdb/linux-nat.c +@@ -4674,7 +4674,7 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object, + LONGEST xfer; + + if (object == TARGET_OBJECT_AUXV) +- return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf, ++ return memory_xfer_auxv (ops, object, annex, readbuf, writebuf, + offset, len); + + if (object == TARGET_OBJECT_OSDATA) +diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c +index 6634703..37770f5 100644 +--- a/gdb/linux-tdep.c ++++ b/gdb/linux-tdep.c +@@ -18,12 +18,8 @@ + along with this program. If not, see . */ + + #include "defs.h" +-#include "gdbcore.h" + #include "gdbtypes.h" + #include "linux-tdep.h" +-#include "observer.h" +- +-#include "elf-bfd.h" + + /* This function is suitable for architectures that don't + extend/override the standard siginfo structure. */ +@@ -138,30 +134,3 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) + + return siginfo_type; + } +- +-/* Observer for the executable_changed event, to check whether the new +- exec binary is a PIE (Position Independent Executable) specimen, which +- is currently unsupported. */ +- +-static void +-check_is_pie_binary (void) +-{ +- Elf_Internal_Ehdr *elf_hdr; +- +- if (!exec_bfd) +- return; +- else if (bfd_get_flavour (exec_bfd) != bfd_target_elf_flavour) +- return; +- +- if (elf_tdata (exec_bfd)->elf_header->e_type == ET_DYN) +- warning (_("\ +-The current binary is a PIE (Position Independent Executable), which\n\ +-GDB does NOT currently support. Most debugger features will fail if used\n\ +-in this session.\n")); +-} +- +-void +-_initialize_linux_tdep (void) +-{ +- observer_attach_executable_changed (check_is_pie_binary); +-} +diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c +index 0adb045..ea89331 100644 +--- a/gdb/nto-procfs.c ++++ b/gdb/nto-procfs.c +@@ -652,7 +652,7 @@ static void + procfs_post_attach (pid_t pid) + { + if (exec_bfd) +- solib_create_inferior_hook (); ++ solib_create_inferior_hook (0); + } + + static ptid_t +@@ -1212,7 +1212,7 @@ procfs_create_inferior (struct target_ops *ops, char *exec_file, + + if (exec_bfd != NULL + || (symfile_objfile != NULL && symfile_objfile->obfd != NULL)) +- solib_create_inferior_hook (); ++ solib_create_inferior_hook (0); + } + + static void +diff --git a/gdb/objfiles.c b/gdb/objfiles.c +index e5442ca..fb0cea9 100644 +--- a/gdb/objfiles.c ++++ b/gdb/objfiles.c +@@ -544,9 +544,10 @@ free_all_objfiles (void) + } + + /* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS +- entries in new_offsets. */ +-void +-objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) ++ entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here. */ ++ ++static void ++objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets) + { + struct obj_section *s; + struct section_offsets *delta = +@@ -624,6 +625,10 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) + } + } + ++ if (objfile->psymtabs_addrmap) ++ addrmap_relocate (objfile->psymtabs_addrmap, ++ ANOFFSET (delta, SECT_OFF_TEXT (objfile))); ++ + { + struct partial_symtab *p; + +@@ -701,6 +706,49 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) + exec_set_section_address (bfd_get_filename (objfile->obfd), idx, + obj_section_addr (s)); + } ++} ++ ++/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS ++ entries in new_offsets. Process also OBJFILE's SEPARATE_DEBUG_OBJFILE. ++ ++ The number and ordering of sections does differ between the two objfiles. ++ Only their names match. Also the file offsets will differ (objfile being ++ possibly prelinked but separate_debug_objfile is probably not prelinked) but ++ the in-memory absolute address as specified by NEW_OFFSETS must match both ++ files. */ ++ ++void ++objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) ++{ ++ objfile_relocate1 (objfile, new_offsets); ++ ++ if (objfile->separate_debug_objfile != NULL) ++ { ++ struct objfile *debug_objfile = objfile->separate_debug_objfile; ++ struct section_addr_info *objfile_addrs; ++ struct section_offsets *new_debug_offsets; ++ int new_debug_num_sections; ++ struct cleanup *my_cleanups; ++ ++ objfile_addrs = build_section_addr_info_from_objfile (objfile); ++ my_cleanups = make_cleanup (xfree, objfile_addrs); ++ ++ /* Here OBJFILE_ADDRS contain the correct absolute addresses, the ++ relative ones must be already created according to debug_objfile. */ ++ ++ addr_info_make_relative (objfile_addrs, debug_objfile->obfd); ++ ++ gdb_assert (debug_objfile->num_sections ++ == bfd_count_sections (debug_objfile->obfd)); ++ new_debug_offsets = alloca (SIZEOF_N_SECTION_OFFSETS ++ (debug_objfile->num_sections)); ++ relative_addr_info_to_section_offsets (new_debug_offsets, ++ debug_objfile->num_sections, ++ objfile_addrs); ++ do_cleanups (my_cleanups); ++ ++ objfile_relocate1 (debug_objfile, new_debug_offsets); ++ } + + /* Relocate breakpoints as necessary, after things are relocated. */ + breakpoint_re_set (); +diff --git a/gdb/procfs.c b/gdb/procfs.c +index b569bac..15829c2 100644 +--- a/gdb/procfs.c ++++ b/gdb/procfs.c +@@ -4376,7 +4376,7 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object, + + #ifdef NEW_PROC_API + case TARGET_OBJECT_AUXV: +- return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf, ++ return memory_xfer_auxv (ops, object, annex, readbuf, writebuf, + offset, len); + #endif + +diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c +index 9428d92..3591168 100644 +--- a/gdb/solib-darwin.c ++++ b/gdb/solib-darwin.c +@@ -277,7 +277,7 @@ darwin_special_symbol_handling (void) + + /* Shared library startup support. See documentation in solib-svr4.c */ + static void +-darwin_solib_create_inferior_hook (void) ++darwin_solib_create_inferior_hook (int from_tty) + { + struct minimal_symbol *msymbol; + char **bkpt_namep; +diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c +index b8d5528..002c589 100644 +--- a/gdb/solib-frv.c ++++ b/gdb/solib-frv.c +@@ -971,7 +971,7 @@ frv_relocate_main_executable (void) + */ + + static void +-frv_solib_create_inferior_hook (void) ++frv_solib_create_inferior_hook (int from_tty) + { + /* Relocate main executable. */ + frv_relocate_main_executable (); +diff --git a/gdb/solib-irix.c b/gdb/solib-irix.c +index a0c1cd2..f94f7dc 100644 +--- a/gdb/solib-irix.c ++++ b/gdb/solib-irix.c +@@ -386,7 +386,7 @@ enable_break (void) + + SYNOPSIS + +- void solib_create_inferior_hook () ++ void solib_create_inferior_hook (int from_tty) + + DESCRIPTION + +@@ -431,7 +431,7 @@ enable_break (void) + */ + + static void +-irix_solib_create_inferior_hook (void) ++irix_solib_create_inferior_hook (int from_tty) + { + struct inferior *inf; + struct thread_info *tp; +diff --git a/gdb/solib-null.c b/gdb/solib-null.c +index b39ccdb..87f7848 100644 +--- a/gdb/solib-null.c ++++ b/gdb/solib-null.c +@@ -32,7 +32,7 @@ null_special_symbol_handling (void) + } + + static void +-null_solib_create_inferior_hook (void) ++null_solib_create_inferior_hook (int from_tty) + { + } + +diff --git a/gdb/solib-osf.c b/gdb/solib-osf.c +index c295335..0acc7fb 100644 +--- a/gdb/solib-osf.c ++++ b/gdb/solib-osf.c +@@ -306,7 +306,7 @@ osf_clear_solib (void) + Also, what if child has exit()ed? Must exit loop somehow. */ + + static void +-osf_solib_create_inferior_hook (void) ++osf_solib_create_inferior_hook (int from_tty) + { + struct inferior *inf; + struct thread_info *tp; +diff --git a/gdb/solib-pa64.c b/gdb/solib-pa64.c +index 637fc1a..16d4010 100644 +--- a/gdb/solib-pa64.c ++++ b/gdb/solib-pa64.c +@@ -329,7 +329,7 @@ bfd_lookup_symbol (bfd *abfd, char *symname) + with shared libraries mapped shareable. */ + + static void +-pa64_solib_create_inferior_hook (void) ++pa64_solib_create_inferior_hook (int from_tty) + { + struct minimal_symbol *msymbol; + unsigned int dld_flags, status; +diff --git a/gdb/solib-som.c b/gdb/solib-som.c +index 16f00a3..37ac8cd 100644 +--- a/gdb/solib-som.c ++++ b/gdb/solib-som.c +@@ -182,7 +182,7 @@ struct { + means running until the "_start" is called. */ + + static void +-som_solib_create_inferior_hook (void) ++som_solib_create_inferior_hook (int from_tty) + { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); + struct minimal_symbol *msymbol; +diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c +index 9f06fa9..45e7e69 100644 +--- a/gdb/solib-spu.c ++++ b/gdb/solib-spu.c +@@ -52,25 +52,19 @@ + static void + spu_relocate_main_executable (int spufs_fd) + { +- struct objfile *objfile; +- struct cleanup *old_chain; + struct section_offsets *new_offsets; + int i; + +- for (objfile = symfile_objfile; +- objfile; +- objfile = objfile->separate_debug_objfile) +- { +- new_offsets = xcalloc (objfile->num_sections, +- sizeof (struct section_offsets)); +- old_chain = make_cleanup (xfree, new_offsets); ++ if (symfile_objfile == NULL) ++ return; + +- for (i = 0; i < objfile->num_sections; i++) +- new_offsets->offsets[i] = SPUADDR (spufs_fd, 0); ++ new_offsets = alloca (symfile_objfile->num_sections ++ * sizeof (struct section_offsets)); + +- objfile_relocate (objfile, new_offsets); +- do_cleanups (old_chain); +- } ++ for (i = 0; i < symfile_objfile->num_sections; i++) ++ new_offsets->offsets[i] = SPUADDR (spufs_fd, 0); ++ ++ objfile_relocate (symfile_objfile, new_offsets); + } + + /* When running a stand-alone SPE executable, we may need to skip one more +@@ -370,7 +364,7 @@ spu_enable_break (struct objfile *objfile) + + /* Create inferior hook. */ + static void +-spu_solib_create_inferior_hook (void) ++spu_solib_create_inferior_hook (int from_tty) + { + /* Remove all previously installed solib breakpoints. Both the SVR4 + code and us will re-install all required breakpoints. */ +@@ -401,7 +395,7 @@ spu_solib_create_inferior_hook (void) + } + + /* Call SVR4 hook -- this will re-insert the SVR4 solib breakpoints. */ +- svr4_so_ops.solib_create_inferior_hook (); ++ svr4_so_ops.solib_create_inferior_hook (from_tty); + + /* If the inferior is statically linked against libspe, we need to install + our own solib breakpoint right now. Otherwise, it will be installed by +diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c +index 9b2a470..b2a147d 100644 +--- a/gdb/solib-sunos.c ++++ b/gdb/solib-sunos.c +@@ -740,7 +740,7 @@ sunos_special_symbol_handling (void) + */ + + static void +-sunos_solib_create_inferior_hook (void) ++sunos_solib_create_inferior_hook (int from_tty) + { + struct thread_info *tp; + struct inferior *inf; +diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c +index 68aadc0..efbe717 100644 +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -50,6 +50,7 @@ + + static struct link_map_offsets *svr4_fetch_link_map_offsets (void); + static int svr4_have_link_map_offsets (void); ++static void svr4_relocate_main_executable (void); + + /* Link map info to include in an allocated so_list entry */ + +@@ -599,11 +600,12 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) + { + int arch_size, step, sect_size; + long dyn_tag; +- CORE_ADDR dyn_ptr, dyn_addr; ++ CORE_ADDR dyn_ptr; + gdb_byte *bufend, *bufstart, *buf; + Elf32_External_Dyn *x_dynp_32; + Elf64_External_Dyn *x_dynp_64; + struct bfd_section *sect; ++ struct target_section *target_section; + + if (abfd == NULL) + return 0; +@@ -619,7 +621,13 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) + sect = bfd_get_section_by_name (abfd, ".dynamic"); + if (sect == NULL) + return 0; +- dyn_addr = bfd_section_vma (abfd, sect); ++ ++ for (target_section = target_get_section_table (&exec_ops)->sections; ++ target_section < target_get_section_table (&exec_ops)->sections_end; ++ target_section++) ++ if (sect == target_section->the_bfd_section) ++ break; ++ gdb_assert (target_section < target_get_section_table (&exec_ops)->sections_end); + + /* Read in .dynamic from the BFD. We will get the actual value + from memory later. */ +@@ -661,7 +669,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) + CORE_ADDR ptr_addr; + + ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; +- ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; ++ ptr_addr = target_section->addr + (buf - bufstart) + arch_size / 8; + if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0) + dyn_ptr = extract_typed_address (ptr_buf, ptr_type); + *ptr = dyn_ptr; +@@ -1258,7 +1266,7 @@ exec_entry_point (struct bfd *abfd, struct target_ops *targ) + */ + + static int +-enable_break (struct svr4_info *info) ++enable_break (struct svr4_info *info, int from_tty) + { + struct minimal_symbol *msymbol; + char **bkpt_namep; +@@ -1279,7 +1287,7 @@ enable_break (struct svr4_info *info) + mean r_brk has already been relocated. Assume the dynamic linker + is the object containing r_brk. */ + +- solib_add (NULL, 0, ¤t_target, auto_solib_add); ++ solib_add (NULL, from_tty, ¤t_target, auto_solib_add); + sym_addr = 0; + if (info->debug_base && solib_svr4_r_map (info) != 0) + sym_addr = solib_svr4_r_brk (info); +@@ -1339,6 +1347,11 @@ enable_break (struct svr4_info *info) + bfd *tmp_bfd = NULL; + struct target_ops *tmp_bfd_target; + volatile struct gdb_exception ex; ++ int addr_bit = gdbarch_addr_bit (target_gdbarch); ++ CORE_ADDR mask = CORE_ADDR_MAX; ++ ++ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) ++ mask = ((CORE_ADDR) 1 << addr_bit) - 1; + + sym_addr = 0; + +@@ -1404,7 +1417,7 @@ enable_break (struct svr4_info *info) + info->debug_loader_name = xstrdup (interp_name); + info->debug_loader_offset_p = 1; + info->debug_loader_offset = load_addr; +- solib_add (NULL, 0, ¤t_target, auto_solib_add); ++ solib_add (NULL, from_tty, ¤t_target, auto_solib_add); + } + + /* Record the relocated start and end address of the dynamic linker +@@ -1414,16 +1427,20 @@ enable_break (struct svr4_info *info) + { + interp_text_sect_low = + bfd_section_vma (tmp_bfd, interp_sect) + load_addr; ++ interp_text_sect_low &= mask; + interp_text_sect_high = + interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); ++ interp_text_sect_high &= mask; + } + interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + if (interp_sect) + { + interp_plt_sect_low = + bfd_section_vma (tmp_bfd, interp_sect) + load_addr; ++ interp_text_sect_low &= mask; + interp_plt_sect_high = + interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); ++ interp_text_sect_high &= mask; + } + + /* Now try to set a breakpoint in the dynamic linker. */ +@@ -1448,7 +1465,7 @@ enable_break (struct svr4_info *info) + + if (sym_addr != 0) + { +- create_solib_event_breakpoint (target_gdbarch, load_addr + sym_addr); ++ create_solib_event_breakpoint (target_gdbarch, (load_addr + sym_addr) & mask); + xfree (interp_name); + return 1; + } +@@ -1517,113 +1534,131 @@ enable_break (struct svr4_info *info) + static void + svr4_special_symbol_handling (void) + { ++ svr4_relocate_main_executable (); + } + +-/* Relocate the main executable. This function should be called upon +- stopping the inferior process at the entry point to the program. +- The entry point from BFD is compared to the PC and if they are +- different, the main executable is relocated by the proper amount. ++/* Decide if the objfile needs to be relocated. As indicated above, ++ we will only be here when execution is stopped at the beginning ++ of the program. Relocation is necessary if the address at which ++ we are presently stopped differs from the start address stored in ++ the executable AND there's no interpreter section. The condition ++ regarding the interpreter section is very important because if ++ there *is* an interpreter section, execution will begin there ++ instead. When there is an interpreter section, the start address ++ is (presumably) used by the interpreter at some point to start ++ execution of the program. ++ ++ If there is an interpreter, it is normal for it to be set to an ++ arbitrary address at the outset. The job of finding it is ++ handled in enable_break(). ++ ++ So, to summarize, relocations are necessary when there is no ++ interpreter section and the start address obtained from the ++ executable is different from the address at which GDB is ++ currently stopped. + +- As written it will only attempt to relocate executables which +- lack interpreter sections. It seems likely that only dynamic +- linker executables will get relocated, though it should work +- properly for a position-independent static executable as well. */ ++ [ The astute reader will note that we also test to make sure that ++ the executable in question has the DYNAMIC flag set. It is my ++ opinion that this test is unnecessary (undesirable even). It ++ was added to avoid inadvertent relocation of an executable ++ whose e_type member in the ELF header is not ET_DYN. There may ++ be a time in the future when it is desirable to do relocations ++ on other types of files as well in which case this condition ++ should either be removed or modified to accomodate the new file ++ type. (E.g, an ET_EXEC executable which has been built to be ++ position-independent could safely be relocated by the OS if ++ desired. It is true that this violates the ABI, but the ABI ++ has been known to be bent from time to time.) - Kevin, Nov 2000. ] ++ */ + +-static void +-svr4_relocate_main_executable (void) ++static CORE_ADDR ++svr4_static_exec_displacement (void) + { + asection *interp_sect; + struct regcache *regcache + = get_thread_arch_regcache (inferior_ptid, target_gdbarch); + CORE_ADDR pc = regcache_read_pc (regcache); + +- /* Decide if the objfile needs to be relocated. As indicated above, +- we will only be here when execution is stopped at the beginning +- of the program. Relocation is necessary if the address at which +- we are presently stopped differs from the start address stored in +- the executable AND there's no interpreter section. The condition +- regarding the interpreter section is very important because if +- there *is* an interpreter section, execution will begin there +- instead. When there is an interpreter section, the start address +- is (presumably) used by the interpreter at some point to start +- execution of the program. +- +- If there is an interpreter, it is normal for it to be set to an +- arbitrary address at the outset. The job of finding it is +- handled in enable_break(). +- +- So, to summarize, relocations are necessary when there is no +- interpreter section and the start address obtained from the +- executable is different from the address at which GDB is +- currently stopped. +- +- [ The astute reader will note that we also test to make sure that +- the executable in question has the DYNAMIC flag set. It is my +- opinion that this test is unnecessary (undesirable even). It +- was added to avoid inadvertent relocation of an executable +- whose e_type member in the ELF header is not ET_DYN. There may +- be a time in the future when it is desirable to do relocations +- on other types of files as well in which case this condition +- should either be removed or modified to accomodate the new file +- type. (E.g, an ET_EXEC executable which has been built to be +- position-independent could safely be relocated by the OS if +- desired. It is true that this violates the ABI, but the ABI +- has been known to be bent from time to time.) - Kevin, Nov 2000. ] +- */ +- + interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); + if (interp_sect == NULL + && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0 + && (exec_entry_point (exec_bfd, &exec_ops) != pc)) ++ return pc - exec_entry_point (exec_bfd, &exec_ops); ++ ++ return 0; ++} ++ ++/* We relocate all of the sections by the same amount. This ++ behavior is mandated by recent editions of the System V ABI. ++ According to the System V Application Binary Interface, ++ Edition 4.1, page 5-5: ++ ++ ... Though the system chooses virtual addresses for ++ individual processes, it maintains the segments' relative ++ positions. Because position-independent code uses relative ++ addressesing between segments, the difference between ++ virtual addresses in memory must match the difference ++ between virtual addresses in the file. The difference ++ between the virtual address of any segment in memory and ++ the corresponding virtual address in the file is thus a ++ single constant value for any one executable or shared ++ object in a given process. This difference is the base ++ address. One use of the base address is to relocate the ++ memory image of the program during dynamic linking. ++ ++ The same language also appears in Edition 4.0 of the System V ++ ABI and is left unspecified in some of the earlier editions. */ ++ ++static CORE_ADDR ++svr4_exec_displacement (void) ++{ ++ int found; ++ CORE_ADDR entry_point; ++ ++ if (exec_bfd == NULL) ++ return 0; ++ ++ if (target_auxv_search (¤t_target, AT_ENTRY, &entry_point) == 1) ++ return entry_point - exec_entry_point (exec_bfd, ¤t_target); ++ ++ return svr4_static_exec_displacement (); ++} ++ ++/* Relocate the main executable. This function should be called upon ++ stopping the inferior process at the entry point to the program. ++ The entry point from BFD is compared to the AT_ENTRY of AUXV and if they are ++ different, the main executable is relocated by the proper amount. */ ++ ++static void ++svr4_relocate_main_executable (void) ++{ ++ CORE_ADDR displacement = svr4_exec_displacement (); ++ ++ /* Even if DISPLACEMENT is 0 still try to relocate it as this is a new ++ difference of in-memory vs. in-file addresses and we could already ++ relocate the executable at this function to improper address before. */ ++ ++ if (symfile_objfile) + { +- struct cleanup *old_chain; + struct section_offsets *new_offsets; +- int i, changed; +- CORE_ADDR displacement; +- +- /* It is necessary to relocate the objfile. The amount to +- relocate by is simply the address at which we are stopped +- minus the starting address from the executable. +- +- We relocate all of the sections by the same amount. This +- behavior is mandated by recent editions of the System V ABI. +- According to the System V Application Binary Interface, +- Edition 4.1, page 5-5: +- +- ... Though the system chooses virtual addresses for +- individual processes, it maintains the segments' relative +- positions. Because position-independent code uses relative +- addressesing between segments, the difference between +- virtual addresses in memory must match the difference +- between virtual addresses in the file. The difference +- between the virtual address of any segment in memory and +- the corresponding virtual address in the file is thus a +- single constant value for any one executable or shared +- object in a given process. This difference is the base +- address. One use of the base address is to relocate the +- memory image of the program during dynamic linking. +- +- The same language also appears in Edition 4.0 of the System V +- ABI and is left unspecified in some of the earlier editions. */ +- +- displacement = pc - exec_entry_point (exec_bfd, &exec_ops); +- changed = 0; +- +- new_offsets = xcalloc (symfile_objfile->num_sections, +- sizeof (struct section_offsets)); +- old_chain = make_cleanup (xfree, new_offsets); ++ int i; ++ ++ new_offsets = alloca (symfile_objfile->num_sections ++ * sizeof (*new_offsets)); + + for (i = 0; i < symfile_objfile->num_sections; i++) +- { +- if (displacement != ANOFFSET (symfile_objfile->section_offsets, i)) +- changed = 1; +- new_offsets->offsets[i] = displacement; +- } ++ new_offsets->offsets[i] = displacement; + +- if (changed) +- objfile_relocate (symfile_objfile, new_offsets); ++ objfile_relocate (symfile_objfile, new_offsets); ++ } ++ else if (exec_bfd) ++ { ++ asection *asect; + +- do_cleanups (old_chain); ++ for (asect = exec_bfd->sections; asect != NULL; asect = asect->next) ++ exec_set_section_address (bfd_get_filename (exec_bfd), asect->index, ++ bfd_section_vma (exec_bfd, asect) ++ + displacement); + } + } + +@@ -1635,7 +1670,7 @@ svr4_relocate_main_executable (void) + + SYNOPSIS + +- void svr4_solib_create_inferior_hook () ++ void svr4_solib_create_inferior_hook (int from_tty) + + DESCRIPTION + +@@ -1680,7 +1715,7 @@ svr4_relocate_main_executable (void) + */ + + static void +-svr4_solib_create_inferior_hook (void) ++svr4_solib_create_inferior_hook (int from_tty) + { + struct inferior *inf; + struct thread_info *tp; +@@ -1689,12 +1724,13 @@ svr4_solib_create_inferior_hook (void) + info = get_svr4_info (PIDGET (inferior_ptid)); + + /* Relocate the main executable if necessary. */ +- svr4_relocate_main_executable (); ++ if (current_inferior ()->attach_flag == 0) ++ svr4_relocate_main_executable (); + + if (!svr4_have_link_map_offsets ()) + return; + +- if (!enable_break (info)) ++ if (!enable_break (info, from_tty)) + return; + + #if defined(_SCO_DS) +@@ -1910,8 +1946,19 @@ elf_lookup_lib_symbol (const struct objfile *objfile, + const char *name, + const domain_enum domain) + { +- if (objfile->obfd == NULL +- || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1) ++ bfd *abfd; ++ ++ if (objfile == symfile_objfile) ++ abfd = exec_bfd; ++ else ++ { ++ /* OBJFILE should have been passed as the non-debug one. */ ++ gdb_assert (objfile->separate_debug_objfile_backlink == NULL); ++ ++ abfd = objfile->obfd; ++ } ++ ++ if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1) + return NULL; + + return lookup_global_symbol_from_objfile (objfile, name, domain); +diff --git a/gdb/solib-target.c b/gdb/solib-target.c +index 07415e4..d160a70 100644 +--- a/gdb/solib-target.c ++++ b/gdb/solib-target.c +@@ -306,7 +306,7 @@ solib_target_special_symbol_handling (void) + } + + static void +-solib_target_solib_create_inferior_hook (void) ++solib_target_solib_create_inferior_hook (int from_tty) + { + /* Nothing needed. */ + } +diff --git a/gdb/solib.c b/gdb/solib.c +index 3574e62..7ea3663 100644 +--- a/gdb/solib.c ++++ b/gdb/solib.c +@@ -998,7 +998,7 @@ clear_solib (void) + + SYNOPSIS + +- void solib_create_inferior_hook () ++ void solib_create_inferior_hook (int from_tty) + + DESCRIPTION + +@@ -1008,10 +1008,10 @@ clear_solib (void) + SOLIB_CREATE_INFERIOR_HOOK. */ + + void +-solib_create_inferior_hook (void) ++solib_create_inferior_hook (int from_tty) + { + struct target_so_ops *ops = solib_ops (target_gdbarch); +- ops->solib_create_inferior_hook(); ++ ops->solib_create_inferior_hook (from_tty); + } + + /* GLOBAL FUNCTION +@@ -1087,7 +1087,6 @@ reload_shared_libraries (char *ignored, int from_tty, + struct cmd_list_element *e) + { + no_shared_libraries (NULL, from_tty); +- solib_add (NULL, from_tty, NULL, auto_solib_add); + /* Creating inferior hooks here has two purposes. First, if we reload + shared libraries then the address of solib breakpoint we've computed + previously might be no longer valid. For example, if we forgot to set +@@ -1102,9 +1101,19 @@ reload_shared_libraries (char *ignored, int from_tty, + #ifdef SOLIB_CREATE_INFERIOR_HOOK + SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid)); + #else +- solib_create_inferior_hook (); ++ solib_create_inferior_hook (from_tty); + #endif + } ++ ++ /* Sometimes the platform-specific hook loads initial shared ++ libraries, and sometimes it doesn't. If it doesn't FROM_TTY will be ++ incorrectly 0 but such solib targets should be fixed anyway. If we ++ made all the inferior hook methods consistent, this call could be ++ removed. Call it only after the solib target has been initialized by ++ solib_create_inferior_hook. */ ++ ++ solib_add (NULL, 0, NULL, auto_solib_add); ++ + /* We have unloaded and then reloaded debug info for all shared libraries. + However, frames may still reference them, for example a frame's + unwinder might still point of DWARF FDE structures that are now freed. +diff --git a/gdb/solib.h b/gdb/solib.h +index ccc5b63..abe5e19 100644 +--- a/gdb/solib.h ++++ b/gdb/solib.h +@@ -41,7 +41,7 @@ extern int solib_read_symbols (struct so_list *, int); + addresses to which they are linked, and sufficient information to + read in their symbols at a later time. */ + +-extern void solib_create_inferior_hook (void); ++extern void solib_create_inferior_hook (int from_tty); + + /* If ADDR lies in a shared library, return its name. */ + +diff --git a/gdb/solist.h b/gdb/solist.h +index 005e8f7..9724fe7 100644 +--- a/gdb/solist.h ++++ b/gdb/solist.h +@@ -87,7 +87,7 @@ struct target_so_ops + void (*clear_solib) (void); + + /* Target dependent code to run after child process fork. */ +- void (*solib_create_inferior_hook) (void); ++ void (*solib_create_inferior_hook) (int from_tty); + + /* Do additional symbol handling, lookup, etc. after symbols + for a shared object have been loaded. */ +diff --git a/gdb/symfile.c b/gdb/symfile.c +index c31b72a..6d7fa10 100644 +--- a/gdb/symfile.c ++++ b/gdb/symfile.c +@@ -536,40 +536,151 @@ place_section (bfd *abfd, asection *sect, void *obj) + arg->lowest = start_addr + bfd_get_section_size (sect); + } + +-/* Parse the user's idea of an offset for dynamic linking, into our idea +- of how to represent it for fast symbol reading. This is the default +- version of the sym_fns.sym_offsets function for symbol readers that +- don't need to do anything special. It allocates a section_offsets table +- for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */ ++/* Build (allocate and populate) struct section_addr_info with absolute ++ addresses from OBJFILE->OBFD and OBJFILE->SECTION_OFFSETS. */ ++ ++struct section_addr_info * ++build_section_addr_info_from_objfile (struct objfile *objfile) ++{ ++ struct target_section *sections = NULL, *sections_end; ++ struct target_section *p; ++ int addr_bit = gdbarch_addr_bit (objfile->gdbarch); ++ CORE_ADDR mask = CORE_ADDR_MAX; ++ struct section_addr_info *retval; ++ struct cleanup *my_cleanups; ++ ++ if (build_section_table (objfile->obfd, §ions, §ions_end)) ++ error (_("Can't find the file sections in `%s': %s"), ++ bfd_get_filename (objfile->obfd), bfd_errmsg (bfd_get_error ())); ++ my_cleanups = make_cleanup (xfree, sections); ++ ++ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) ++ mask = ((CORE_ADDR) 1 << addr_bit) - 1; ++ ++ for (p = sections; p < sections_end; p++) ++ { ++ CORE_ADDR baseaddr; ++ ++ gdb_assert (p->the_bfd_section->index < objfile->num_sections); ++ baseaddr = ANOFFSET (objfile->section_offsets, ++ p->the_bfd_section->index); ++ ++ p->addr = (p->addr + baseaddr) & mask; ++ p->endaddr = (p->endaddr + baseaddr) & mask; ++ } ++ ++ retval = build_section_addr_info_from_section_table (sections, sections_end); ++ ++ do_cleanups (my_cleanups); ++ ++ return retval; ++} ++ ++/* Store struct section_addr_info as prepared (made relative and with SECTINDEX ++ filled-in) by addr_info_make_relative into SECTION_OFFSETS of NUM_SECTIONS ++ entries. */ + + void +-default_symfile_offsets (struct objfile *objfile, +- struct section_addr_info *addrs) ++relative_addr_info_to_section_offsets (struct section_offsets *section_offsets, ++ int num_sections, ++ struct section_addr_info *addrs) + { + int i; + +- objfile->num_sections = bfd_count_sections (objfile->obfd); +- objfile->section_offsets = (struct section_offsets *) +- obstack_alloc (&objfile->objfile_obstack, +- SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); +- memset (objfile->section_offsets, 0, +- SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); ++ memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections)); + +- /* Now calculate offsets for section that were specified by the +- caller. */ ++ /* Now calculate offsets for section that were specified by the caller. */ + for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + { +- struct other_sections *osp ; ++ struct other_sections *osp; + +- osp = &addrs->other[i] ; ++ osp = &addrs->other[i]; + if (osp->addr == 0) + continue; + + /* Record all sections in offsets */ + /* The section_offsets in the objfile are here filled in using + the BFD index. */ +- (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr; ++ section_offsets->offsets[osp->sectindex] = osp->addr; ++ } ++} ++ ++/* Relativize absolute addresses in ADDRS into offsets based on ABFD. Fill-in ++ also SECTINDEXes there. */ ++ ++void ++addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) ++{ ++ asection *lower_sect; ++ asection *sect; ++ CORE_ADDR lower_offset; ++ int i; ++ ++ /* Find lowest loadable section to be used as starting point for ++ continguous sections. FIXME!! won't work without call to find ++ .text first, but this assumes text is lowest section. */ ++ lower_sect = bfd_get_section_by_name (abfd, ".text"); ++ if (lower_sect == NULL) ++ bfd_map_over_sections (abfd, find_lowest_section, &lower_sect); ++ if (lower_sect == NULL) ++ { ++ warning (_("no loadable sections found in added symbol-file %s"), ++ bfd_get_filename (abfd)); ++ lower_offset = 0; ++ } ++ else ++ lower_offset = bfd_section_vma (bfd_get_filename (abfd), lower_sect); ++ ++ /* Calculate offsets for the loadable sections. ++ FIXME! Sections must be in order of increasing loadable section ++ so that contiguous sections can use the lower-offset!!! ++ ++ Adjust offsets if the segments are not contiguous. ++ If the section is contiguous, its offset should be set to ++ the offset of the highest loadable section lower than it ++ (the loadable section directly below it in memory). ++ this_offset = lower_offset = lower_addr - lower_orig_addr */ ++ ++ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) ++ { ++ if (addrs->other[i].addr != 0) ++ { ++ sect = bfd_get_section_by_name (abfd, addrs->other[i].name); ++ if (sect) ++ { ++ addrs->other[i].addr -= bfd_section_vma (abfd, sect); ++ lower_offset = addrs->other[i].addr; ++ /* This is the index used by BFD. */ ++ addrs->other[i].sectindex = sect->index; ++ } ++ else ++ { ++ warning (_("section %s not found in %s"), addrs->other[i].name, ++ bfd_get_filename (abfd)); ++ addrs->other[i].addr = 0; ++ } ++ } ++ else ++ addrs->other[i].addr = lower_offset; + } ++} ++ ++/* Parse the user's idea of an offset for dynamic linking, into our idea ++ of how to represent it for fast symbol reading. This is the default ++ version of the sym_fns.sym_offsets function for symbol readers that ++ don't need to do anything special. It allocates a section_offsets table ++ for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */ ++ ++void ++default_symfile_offsets (struct objfile *objfile, ++ struct section_addr_info *addrs) ++{ ++ objfile->num_sections = bfd_count_sections (objfile->obfd); ++ objfile->section_offsets = (struct section_offsets *) ++ obstack_alloc (&objfile->objfile_obstack, ++ SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); ++ relative_addr_info_to_section_offsets (objfile->section_offsets, ++ objfile->num_sections, addrs); + + /* For relocatable files, all loadable sections will start at zero. + The zero is meaningless, so try to pick arbitrary addresses such +@@ -803,65 +914,8 @@ syms_from_objfile (struct objfile *objfile, + + We no longer warn if the lowest section is not a text segment (as + happens for the PA64 port. */ +- if (!mainline && addrs && addrs->other[0].name) +- { +- asection *lower_sect; +- asection *sect; +- CORE_ADDR lower_offset; +- int i; +- +- /* Find lowest loadable section to be used as starting point for +- continguous sections. FIXME!! won't work without call to find +- .text first, but this assumes text is lowest section. */ +- lower_sect = bfd_get_section_by_name (objfile->obfd, ".text"); +- if (lower_sect == NULL) +- bfd_map_over_sections (objfile->obfd, find_lowest_section, +- &lower_sect); +- if (lower_sect == NULL) +- { +- warning (_("no loadable sections found in added symbol-file %s"), +- objfile->name); +- lower_offset = 0; +- } +- else +- lower_offset = bfd_section_vma (objfile->obfd, lower_sect); +- +- /* Calculate offsets for the loadable sections. +- FIXME! Sections must be in order of increasing loadable section +- so that contiguous sections can use the lower-offset!!! +- +- Adjust offsets if the segments are not contiguous. +- If the section is contiguous, its offset should be set to +- the offset of the highest loadable section lower than it +- (the loadable section directly below it in memory). +- this_offset = lower_offset = lower_addr - lower_orig_addr */ +- +- for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) +- { +- if (addrs->other[i].addr != 0) +- { +- sect = bfd_get_section_by_name (objfile->obfd, +- addrs->other[i].name); +- if (sect) +- { +- addrs->other[i].addr +- -= bfd_section_vma (objfile->obfd, sect); +- lower_offset = addrs->other[i].addr; +- /* This is the index used by BFD. */ +- addrs->other[i].sectindex = sect->index ; +- } +- else +- { +- warning (_("section %s not found in %s"), +- addrs->other[i].name, +- objfile->name); +- addrs->other[i].addr = 0; +- } +- } +- else +- addrs->other[i].addr = lower_offset; +- } +- } ++ if (addrs && addrs->other[0].name) ++ addr_info_make_relative (addrs, objfile->obfd); + + /* Initialize symbol reading routines for this objfile, allow complaints to + appear for this new file, and record how verbose to be, then do the +@@ -959,7 +1013,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, + struct objfile *objfile; + struct partial_symtab *psymtab; + char *debugfile = NULL; +- struct section_addr_info *orig_addrs = NULL; + struct cleanup *my_cleanups; + const char *name = bfd_get_filename (abfd); + const int from_tty = add_flags & SYMFILE_VERBOSE; +@@ -981,12 +1034,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, + objfile->flags |= OBJF_MAIN; + discard_cleanups (my_cleanups); + +- if (addrs) +- { +- orig_addrs = copy_section_addr_info (addrs); +- make_cleanup_free_section_addr_info (orig_addrs); +- } +- + /* We either created a new mapped symbol table, mapped an existing + symbol table file which has not had initial symbol reading + performed, or need to read an unmapped symbol table. */ +@@ -1033,18 +1080,17 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, + `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'. */ + if (!has_any_debug_symbols (objfile)) + debugfile = find_separate_debug_file (objfile); ++ + if (debugfile) + { +- if (addrs != NULL) +- { +- objfile->separate_debug_objfile +- = symbol_file_add (debugfile, add_flags, orig_addrs, flags); +- } +- else +- { +- objfile->separate_debug_objfile +- = symbol_file_add (debugfile, add_flags, NULL, flags); +- } ++ struct section_addr_info *objfile_addrs; ++ ++ objfile_addrs = build_section_addr_info_from_objfile (objfile); ++ make_cleanup (xfree, objfile_addrs); ++ ++ objfile->separate_debug_objfile = symbol_file_add (debugfile, add_flags, ++ objfile_addrs, flags); ++ + objfile->separate_debug_objfile->separate_debug_objfile_backlink + = objfile; + +diff --git a/gdb/symfile.h b/gdb/symfile.h +index bf9d9e7..bff6bd8 100644 +--- a/gdb/symfile.h ++++ b/gdb/symfile.h +@@ -181,6 +181,16 @@ struct sym_fns + + }; + ++extern struct section_addr_info * ++ build_section_addr_info_from_objfile (struct objfile *objfile); ++ ++extern void relative_addr_info_to_section_offsets ++ (struct section_offsets *section_offsets, int num_sections, ++ struct section_addr_info *addrs); ++ ++extern void addr_info_make_relative (struct section_addr_info *addrs, ++ bfd *abfd); ++ + /* The default version of sym_fns.sym_offsets for readers that don't + do anything special. */ + +diff --git a/gdb/symtab.c b/gdb/symtab.c +index 82e0163..01117e3 100644 +--- a/gdb/symtab.c ++++ b/gdb/symtab.c +@@ -1449,7 +1449,12 @@ lookup_objfile_from_block (const struct block *block) + /* Go through SYMTABS. */ + ALL_SYMTABS (obj, s) + if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK)) +- return obj; ++ { ++ if (obj->separate_debug_objfile_backlink) ++ obj = obj->separate_debug_objfile_backlink; ++ ++ return obj; ++ } + + return NULL; + } +diff --git a/gdb/testsuite/gdb.base/break-interp-lib.c b/gdb/testsuite/gdb.base/break-interp-lib.c +new file mode 100644 +index 0000000..9ca943e +--- /dev/null ++++ b/gdb/testsuite/gdb.base/break-interp-lib.c +@@ -0,0 +1,40 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2009 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 . */ ++ ++#include ++#include ++#include ++#include ++ ++void ++libfunc (const char *action) ++{ ++ assert (action != NULL); ++ ++ if (strcmp (action, "segv") == 0) ++ raise (SIGSEGV); ++ ++ if (strcmp (action, "sleep") == 0) ++ { ++ puts ("sleeping"); ++ fflush (stdout); ++ ++ sleep (60); ++ } ++ ++ assert (0); ++} +diff --git a/gdb/testsuite/gdb.base/break-interp-main.c b/gdb/testsuite/gdb.base/break-interp-main.c +new file mode 100644 +index 0000000..e12ec2b +--- /dev/null ++++ b/gdb/testsuite/gdb.base/break-interp-main.c +@@ -0,0 +1,30 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2009 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 . */ ++ ++#include ++ ++extern void libfunc (const char *action); ++ ++int ++main (int argc, char **argv) ++{ ++ assert (argc == 2); ++ ++ libfunc (argv[1]); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/break-interp.exp b/gdb/testsuite/gdb.base/break-interp.exp +new file mode 100644 +index 0000000..52f460c +--- /dev/null ++++ b/gdb/testsuite/gdb.base/break-interp.exp +@@ -0,0 +1,545 @@ ++# Copyright 2009 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 . ++ ++# This test only works on GNU/Linux. ++if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_tests]} { ++ continue ++} ++ ++set test "break-interp" ++set binprefix ${objdir}/${subdir}/${test} ++# Only to get the $interp_system name. ++set srcfile_test "start.c" ++set binfile_test ${test}-test ++set binfile_lib ${objdir}/${subdir}/${test}.so ++set srcfile "${test}-main.c" ++set srcfile_lib "${test}-lib.c" ++ ++if [get_compiler_info ${binfile_lib}] { ++ return -1 ++} ++ ++# Use -soname so that it is listed with " => " by ldd and this testcase makes ++# a copy of ${binfile_lib} for each prelink variant. ++ ++if {[gdb_compile_shlib ${srcdir}/${subdir}/${srcfile_lib} ${binfile_lib} [list debug additional_flags=-Wl,-soname,${test}.so]] != ""} { ++ return -1 ++} ++ ++if {[build_executable ${test}.exp $binfile_test ${srcfile_test} {}] == -1} { ++ return -1 ++} ++ ++# Return the interpreter filename string. ++# Return "" if no interpreter was found. ++proc section_get {exec section} { ++ global objdir ++ global subdir ++ set tmp "${objdir}/${subdir}/break-interp.interp" ++ set objcopy_program [transform objcopy] ++ ++ set command "exec $objcopy_program -O binary --set-section-flags $section=A --change-section-address $section=0 -j $section $exec $tmp" ++ verbose -log "command is $command" ++ set result [catch $command output] ++ verbose -log "result is $result" ++ verbose -log "output is $output" ++ if {$result == 1} { ++ return "" ++ } ++ set fi [open $tmp] ++ fconfigure $fi -translation binary ++ set data [read $fi] ++ close $fi ++ #file delete $tmp ++ # .interp has size $len + 1 but .gnu_debuglink contains garbage after \000. ++ set len [string first \000 $data] ++ if {$len < 0} { ++ verbose -log "section $section not found" ++ return "" ++ } ++ set retval [string range $data 0 [expr $len - 1]] ++ verbose -log "section $section is <$retval>" ++ return $retval ++} ++ ++# Note: The separate debug info file content build-id/crc32 are not verified ++# contrary to the GDB search algorithm skipping non-matching ones. ++proc system_debug_get {exec} { ++ global debug_root ++ ++ set exec_build_id_debug [build_id_debug_filename_get $exec] ++ set debug_base "[file tail $exec].debug" ++ set exec_dir [file dirname $exec] ++ ++ # isfile returns 1 even for symlinks to files. ++ set retval $debug_root/$exec_build_id_debug ++ if [file isfile $retval] { ++ return $retval ++ } ++ set retval $exec_dir/$debug_base ++ if [file isfile $retval] { ++ return $retval ++ } ++ set retval $exec_dir/.debug/$debug_base ++ if [file isfile $retval] { ++ return $retval ++ } ++ set retval $debug_root/$exec_dir/$debug_base ++ if [file isfile $retval] { ++ return $retval ++ } ++ return "" ++} ++ ++gdb_exit ++gdb_start ++set debug_root "" ++set test "show debug-file-directory" ++gdb_test_multiple $test $test { ++ -re "The directory where separate debug symbols are searched for is \"(.*)\".\r\n$gdb_prompt $" { ++ set debug_root $expect_out(1,string) ++ } ++} ++ ++set interp_system [section_get ${objdir}/${subdir}/$binfile_test .interp] ++set interp_system_debug [system_debug_get $interp_system] ++verbose -log "$interp_system has debug $interp_system_debug" ++ ++proc prelinkNO_run {arg} { ++ set command "exec /usr/sbin/prelink -uN $arg" ++ verbose -log "command is $command" ++ set result [catch $command output] ++ verbose -log "result is $result" ++ verbose -log "output is $output" ++ return [list $result $output] ++} ++ ++proc prelinkNO {arg {name {}}} { ++ if {$name == ""} { ++ set name [file tail $arg] ++ } ++ set test "unprelink $name" ++ set run [prelinkNO_run $arg] ++ set result [lindex $run 0] ++ set output [lindex $run 1] ++ if {$result == 0 && $output == ""} { ++ verbose -log "$name has been now unprelinked" ++ set run [prelinkNO_run $arg] ++ set result [lindex $run 0] ++ set output [lindex $run 1] ++ } ++ # Last line does miss the trailing \n. ++ if {$result == 1 && [regexp {^(/usr/sbin/prelink: [^ ]* does not have .gnu.prelink_undo section\n?)*$} $output]} { ++ pass $test ++ return 1 ++ } else { ++ fail $test ++ return 0 ++ } ++} ++ ++proc prelinkYES {arg {name ""}} { ++ if {$name == ""} { ++ set name [file tail $arg] ++ } ++ set test "prelink $name" ++ set command "exec /usr/sbin/prelink -qNR --no-exec-shield $arg" ++ verbose -log "command is $command" ++ set result [catch $command output] ++ verbose -log "result is $result" ++ verbose -log "output is $output" ++ if {$result == 0 && $output == ""} { ++ pass $test ++ return 1 ++ } else { ++ fail $test ++ return 0 ++ } ++} ++ ++# Resolve symlinks. ++proc symlink_resolve {file} { ++ set loop 0 ++ while {[file type $file] == "link"} { ++ set target [file readlink $file] ++ if {[file pathtype $target] == "relative"} { ++ set src2 [file dirname $file]/$target ++ } else { ++ set src2 $target ++ } ++ verbose -log "Resolved symlink $file targetting $target as $src2" ++ set file $src2 ++ ++ set loop [expr $loop + 1] ++ if {$loop > 30} { ++ fail "Looping symlink resolution for $file" ++ return "" ++ } ++ } ++ return $file ++} ++ ++proc copy {src dest} { ++ set src [symlink_resolve $src] ++ # Test name would contain build-id hash for symlink-unresolved $src. ++ set test "copy [file tail $src] to [file tail $dest]" ++ set command "file copy -force $src $dest" ++ verbose -log "command is $command" ++ if [catch $command] { ++ fail $test ++ return 0 ++ } else { ++ pass $test ++ return 1 ++ } ++} ++ ++proc strip_debug {dest} { ++ set test "strip [file tail $dest]" ++ set strip_program [transform strip] ++ set command "exec $strip_program --strip-debug $dest" ++ verbose -log "command is $command" ++ if [catch $command] { ++ fail $test ++ return 0 ++ } else { ++ pass $test ++ return 1 ++ } ++} ++ ++# `runto' does not check we stopped really at the function we specified. ++proc reach {func command} { ++ global gdb_prompt ++ ++ if [gdb_breakpoint $func allow-pending] { ++ set test "reach $func" ++ gdb_test_multiple $command $test { ++ -re "Breakpoint \[0-9\]+, $func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" { ++ pass $test ++ } ++ -re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in $func \\(\\)( from .*)?\r\n$gdb_prompt $" { ++ pass $test ++ } ++ } ++ } ++} ++ ++proc test_core {file} { ++ global srcdir subdir gdb_prompt ++ ++ set corefile [core_find $file {} "segv"] ++ if {$corefile == ""} { ++ return ++ } ++ ++ gdb_exit ++ gdb_start ++ # Clear it to never find any separate debug infos in $debug_root. ++ gdb_test "set debug-file-directory" "" "set debug-file-directory for core" ++ gdb_reinitialize_dir $srcdir/$subdir ++ gdb_load $file ++ ++ # Do not check the binary filename as it may be truncated. ++ gdb_test "core-file $corefile" "Core was generated by .*\r\n#0 .*" "core loaded" ++ ++ # Check there is no "argc=can't compute CFA for this frame". ++ gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain \\((argc=2,.*)?\\).*" "core main bt" ++} ++ ++proc test_attach {file} { ++ global board_info ++ ++ gdb_exit ++ ++ set test "sleep function started" ++ ++ set command "${file} sleep" ++ set res [remote_spawn host $command]; ++ if { $res < 0 || $res == "" } { ++ perror "Spawning $command failed." ++ fail $test ++ return ++ } ++ set pid [exp_pid -i $res] ++ gdb_expect { ++ -re "sleeping\r\n" { ++ pass $test ++ } ++ eof { ++ fail "$test (eof)" ++ return ++ } ++ timeout { ++ fail "$test (timeout)" ++ return ++ } ++ } ++ ++ gdb_exit ++ gdb_start ++ gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach" ++ # Check there is no "argc=can't compute CFA for this frame". ++ gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain \\((argc=2,.*)?\\).*" "attach main bt" ++ gdb_exit ++ ++ remote_exec host "kill -9 $pid" ++} ++ ++proc test_ld {file ifmain trynosym} { ++ global srcdir subdir gdb_prompt ++ ++ # First test normal `file'-command loaded $FILE with symbols. ++ ++ gdb_exit ++ gdb_start ++ # Clear it to never find any separate debug infos in $debug_root. ++ gdb_test "set debug-file-directory" ++ gdb_reinitialize_dir $srcdir/$subdir ++ gdb_load $file ++ ++ reach "dl_main" "run segv" ++ ++ gdb_test "bt" "#0 +\[^\r\n\]*\\mdl_main\\M.*" "dl bt" ++ ++ if $ifmain { ++ reach "main" continue ++ ++ reach "libfunc" continue ++ ++ # Check there is no "argc=can't compute CFA for this frame". ++ gdb_test "bt" "#0 +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#1 +\[^\r\n\]*\\mmain \\((argc=2,.*)?\\).*" "main bt" ++ ++ test_core $file ++ ++ test_attach $file ++ } ++ ++ if !$trynosym { ++ return ++ } ++ ++ global pf_prefix ++ set old_ldprefix $pf_prefix ++ lappend pf_prefix "symbol-less:" ++ ++ # Test also `exec-file'-command loaded $FILE - therefore without symbols. ++ # SYMBOL_OBJFILE is not available and only EXEC_BFD must be used. ++ ++ gdb_exit ++ gdb_start ++ # Clear it to never find any separate debug infos in $debug_root. ++ gdb_test "set debug-file-directory" ++ gdb_reinitialize_dir $srcdir/$subdir ++ ++ # Test no (error) message has been printed by `exec-file'. ++ set escapedfile [string_to_regexp $file] ++ gdb_test "exec-file $file" "exec-file $escapedfile" "load" ++ ++ if $ifmain { ++ reach "dl_main" run ++ ++ set test "info files" ++ set entrynohex "" ++ gdb_test_multiple $test $test { ++ -re "\r\n\[\t \]*Entry point:\[\t \]*0x(\[0-9a-f\]+)\r\n.*$gdb_prompt $" { ++ set entrynohex $expect_out(1,string) ++ pass $test ++ } ++ } ++ if {$entrynohex != ""} { ++ gdb_test "break *0x$entrynohex" "" "break at entry point" ++ gdb_test "continue" "\r\nBreakpoint \[0-9\]+, 0x0*$entrynohex in .*" "entry point reached" ++ } ++ } else { ++ # There is no symbol to break at ld.so. Moreover it can exit with an ++ # error code. ++ gdb_test "run" "Program exited (normally|with code \[0-9\]+)\\." "ld.so exit" ++ } ++ ++ set pf_prefix $old_ldprefix ++} ++ ++# Create separate binaries for each testcase - to make the possible reported ++# problem reproducible after the whole test run finishes. ++ ++set old_ldprefix $pf_prefix ++foreach ldprelink {NO YES} { ++ foreach ldsepdebug {NO IN SEP} { ++ # Skip running the ldsepdebug test if we do not have system separate ++ # debug info available. ++ if {$interp_system_debug == "" && $ldsepdebug == "SEP"} { ++ continue ++ } ++ ++ set ldname "LDprelink${ldprelink}debug${ldsepdebug}" ++ set interp $binprefix-$ldname ++ ++ # prelink needs to always prelink all the dependencies to do any file ++ # modifications of its files. ld.so also needs all the dependencies to ++ # be prelinked to omit the relocation process. In-memory file offsets ++ # are not dependent whether ld.so went the prelink way or through the ++ # relocation process. ++ # ++ # For GDB we are not interested whether prelink succeeds as it is ++ # transparent to GDB. GDB is being tested for differences of file ++ # offsets vs. in-memory offsets. So we have to prelink even ld.so for ++ # the BIN modification to happen but we need to restore the original ++ # possibly unprelinked ld.so to test all the combinations for GDB. ++ set interp_saved ${interp}-saved ++ ++ set pf_prefix $old_ldprefix ++ lappend pf_prefix "$ldname:" ++ ++ if {$ldsepdebug == "NO"} { ++ copy $interp_system $interp ++ # Never call strip-debug before unprelink: ++ # prelink: ...: Section .note.gnu.build-id created after prelinking ++ if ![prelinkNO $interp] { ++ continue ++ } ++ strip_debug $interp ++ } elseif {$ldsepdebug == "IN" && $interp_system_debug == ""} { ++ copy $interp_system $interp ++ } elseif {$ldsepdebug == "IN" && $interp_system_debug != ""} { ++ copy $interp_system $interp ++ copy $interp_system_debug "${interp}.debug" ++ # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u ++ if {![prelinkNO $interp] || ![prelinkNO "${interp}.debug"]} { ++ continue ++ } ++ set test "eu-unstrip unprelinked:[file tail $interp_system] + [file tail $interp_system_debug] to [file tail $interp]" ++ set command "exec eu-unstrip -o $interp $interp ${interp}.debug" ++ verbose -log "command is $command" ++ if [catch $command] { ++ setup_xfail *-*-* ++ fail $test ++ continue ++ } else { ++ pass $test ++ } ++ } elseif {$ldsepdebug == "SEP" && $interp_system_debug == ""} { ++ copy $interp_system $interp ++ # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u ++ if ![prelinkNO $interp] { ++ continue ++ } ++ gdb_gnu_strip_debug $interp ++ } elseif {$ldsepdebug == "SEP" && $interp_system_debug != ""} { ++ copy $interp_system $interp ++ copy $interp_system_debug "${interp}.debug" ++ } ++ ++ if {$ldsepdebug == "SEP"} { ++ if ![prelinkNO "${interp}.debug"] { ++ continue ++ } ++ } else { ++ file delete "${interp}.debug" ++ } ++ ++ if ![prelink$ldprelink $interp] { ++ continue ++ } ++ test_ld $interp 0 [expr {$ldsepdebug == "NO"}] ++ ++ if ![copy $interp $interp_saved] { ++ continue ++ } ++ set old_binprefix $pf_prefix ++ foreach binprelink {NO YES} { ++ foreach binsepdebug {NO IN SEP} { ++ foreach binpie {NO YES} { ++ # This combination is not possible, non-PIE (fixed address) ++ # binary cannot be prelinked to any (other) address. ++ if {$binprelink == "YES" && $binpie == "NO"} { ++ continue ++ } ++ ++ set binname "BINprelink${binprelink}debug${binsepdebug}pie${binpie}" ++ set exec $binprefix-$binname ++ set dir ${exec}.d ++ ++ set pf_prefix $old_binprefix ++ lappend pf_prefix "$binname:" ++ ++ set opts "additional_flags=-Wl,--dynamic-linker,$interp,-rpath,$dir" ++ lappend opts "additional_flags=-Wl,$binfile_lib,-rpath,[file dirname $binfile_lib]" ++ if {$binsepdebug != "NO"} { ++ lappend opts {debug} ++ } ++ if {$binpie == "YES"} { ++ lappend opts {additional_flags=-fPIE -pie} ++ } ++ if {[build_executable ${test}.exp [file tail $exec] $srcfile $opts] == -1} { ++ continue; ++ } ++ if {$binsepdebug == "SEP"} { ++ gdb_gnu_strip_debug $exec ++ # Just a sanity check. As gdb_gnu_strip_debug uses the ++ # "[file dirname $exec]/.debug/[file tail $exec].debug" ++ # variant delete the higher-priority exec.debug file. ++ file delete "$exec.debug" ++ } ++ ++ # Supply a self-sufficent directory $dir with the required ++ # libraries. To make an executable properly prelinked all ++ # its dependencies on libraries must be also prelinked. If ++ # some of the system libraries is currently not prelinked ++ # we have no right to prelink (modify it) at its current ++ # system place. ++ ++ file delete -force $dir ++ file mkdir $dir ++ ++ set command "ldd $exec" ++ set result [catch "exec $command" output] ++ verbose -log "result of $command is $result" ++ verbose -log "output of $command is $output" ++ if {$result != 0 || $output == ""} { ++ fail $command ++ } else { ++ pass $command ++ } ++ ++ # gdb testsuite will put there also needless -lm. ++ set test "$command output contains libc" ++ set libc [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output] ++ if {[llength $libc] == 0} { ++ fail $test ++ } else { ++ pass $test ++ } ++ ++ set dests {} ++ for {set i 1} {$i < [llength $libc]} {incr i 2} { ++ set abspath [lindex $libc $i] ++ set dest "$dir/[file tail $abspath]" ++ copy $abspath $dest ++ lappend dests $dest ++ } ++ ++ if {[prelink$binprelink "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" $exec] ++ && [copy $interp_saved $interp]} { ++ test_ld $exec 1 [expr {$binsepdebug == "NO"}] ++ } ++ } ++ } ++ } ++ ++ file delete $interp_saved ++ } ++} ++set pf_prefix $old_ldprefix +diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp +index a1003e1..547a898 100644 +--- a/gdb/testsuite/gdb.base/corefile.exp ++++ b/gdb/testsuite/gdb.base/corefile.exp +@@ -42,65 +42,12 @@ if [get_compiler_info ${binfile}] { + return -1; + } + +-# Create a core file named "corefile" rather than just "core", to +-# avoid problems with sys admin types that like to regularly prune all +-# files named "core" from the system. +-# +-# Arbitrarily try setting the core size limit to "unlimited" since +-# this does not hurt on systems where the command does not work and +-# allows us to generate a core on systems where it does. +-# +-# Some systems append "core" to the name of the program; others append +-# the name of the program to "core"; still others (like Linux, as of +-# May 2003) create cores named "core.PID". In the latter case, we +-# could have many core files lying around, and it may be difficult to +-# tell which one is ours, so let's run the program in a subdirectory. +-set found 0 +-set coredir "${objdir}/${subdir}/coredir.[getpid]" +-file mkdir $coredir +-catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile}; true) >/dev/null 2>&1\"" +-# remote_exec host "${binfile}" +-foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" { +- if [remote_file build exists $i] { +- remote_exec build "mv $i ${objdir}/${subdir}/corefile" +- set found 1 +- } +-} +-# Check for "core.PID". +-if { $found == 0 } { +- set names [glob -nocomplain -directory $coredir core.*] +- if {[llength $names] == 1} { +- set corefile [file join $coredir [lindex $names 0]] +- remote_exec build "mv $corefile ${objdir}/${subdir}/corefile" +- set found 1 +- } +-} +-if { $found == 0 } { +- # The braindamaged HPUX shell quits after the ulimit -c above +- # without executing ${binfile}. So we try again without the +- # ulimit here if we didn't find a core file above. +- # Oh, I should mention that any "braindamaged" non-Unix system has +- # the same problem. I like the cd bit too, it's really neat'n stuff. +- catch "system \"(cd ${objdir}/${subdir}; ${binfile}; true) >/dev/null 2>&1\"" +- foreach i "${objdir}/${subdir}/core ${objdir}/${subdir}/core.coremaker.c ${binfile}.core" { +- if [remote_file build exists $i] { +- remote_exec build "mv $i ${objdir}/${subdir}/corefile" +- set found 1 +- } +- } ++set corefile [core_find $binfile {coremmap.data}] ++if {$corefile == ""} { ++ return 0; + } + +-# Try to clean up after ourselves. +-remote_file build delete [file join $coredir coremmap.data] +-remote_exec build "rmdir $coredir" +- +-if { $found == 0 } { +- warning "can't generate a core file - core tests suppressed - check ulimit -c" +- return 0 +-} +- +-# +-# Test that we can simply startup with a "-core=corefile" command line arg ++# Test that we can simply startup with a "-core=$corefile" command line arg + # and recognize that the core file is a valid, usable core file. + # To do this, we must shutdown the currently running gdb and restart + # with the -core args. We can't use gdb_start because it looks for +@@ -114,27 +61,27 @@ if { $found == 0 } { + + gdb_exit + if $verbose>1 then { +- send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$objdir/$subdir/corefile\n" ++ send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$corefile\n" + } + + set oldtimeout $timeout + set timeout [expr "$timeout + 60"] + verbose "Timeout is now $timeout seconds" 2 +-eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$objdir/$subdir/corefile" ++eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$corefile" + expect { + -re "Couldn't find .* registers in core file.*$gdb_prompt $" { +- fail "args: -core=corefile (couldn't find regs)" ++ fail "args: -core=[file tail $corefile] (couldn't find regs)" + } + -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { +- pass "args: -core=corefile" ++ pass "args: -core=[file tail $corefile]" + } + -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { +- pass "args: -core=corefile (with bad program name)" ++ pass "args: -core=[file tail $corefile] (with bad program name)" + } + -re ".*registers from core file: File in wrong format.* $" { +- fail "args: -core=corefile (could not read registers from core file)" ++ fail "args: -core=[file tail $corefile] (could not read registers from core file)" + } +- -re ".*$gdb_prompt $" { fail "args: -core=corefile" } ++ -re ".*$gdb_prompt $" { fail "args: -core=[file tail $corefile]" } + timeout { fail "(timeout) starting with -core" } + } + +@@ -147,22 +94,22 @@ expect { + close; + + if $verbose>1 then { +- send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$objdir/$subdir/corefile\n" ++ send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$corefile\n" + } + + +-eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$objdir/$subdir/corefile"; ++eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$corefile"; + expect { + -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { +- pass "args: execfile -core=corefile" ++ pass "args: execfile -core=[file tail $corefile]" + } + -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { +- pass "args: execfile -core=corefile (with bad program name)" ++ pass "args: execfile -core=[file tail $corefile] (with bad program name)" + } + -re ".*registers from core file: File in wrong format.* $" { +- fail "args: execfile -core=corefile (could not read registers from core file)" ++ fail "args: execfile -core=[file tail $corefile] (could not read registers from core file)" + } +- -re ".*$gdb_prompt $" { fail "args: execfile -core=corefile" } ++ -re ".*$gdb_prompt $" { fail "args: execfile -core=[file tail $corefile]" } + timeout { fail "(timeout) starting with -core" } + } + set timeout $oldtimeout +@@ -178,7 +125,7 @@ gdb_load ${binfile} + + # Test basic corefile recognition via core-file command. + +-send_gdb "core-file $objdir/$subdir/corefile\n" ++send_gdb "core-file $corefile\n" + gdb_expect { + -re ".* program is being debugged already.*y or n. $" { + # gdb_load may connect us to a gdbserver. +diff --git a/gdb/testsuite/gdb.base/pie-support.c b/gdb/testsuite/gdb.base/pie-support.c +deleted file mode 100644 +index 63768b9..0000000 +--- a/gdb/testsuite/gdb.base/pie-support.c ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* This testcase is part of GDB, the GNU debugger. +- +- Copyright 2009 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 . +- +-*/ +- +-#include +- +-void +-f1 (int a) +-{ +- printf ("a = %d\n", a); +-} +- +-int +-main (int argc, char *argv[]) +-{ +- f1 (1); +- +- return 0; +-} +diff --git a/gdb/testsuite/gdb.base/pie-support.exp b/gdb/testsuite/gdb.base/pie-support.exp +deleted file mode 100644 +index 7d118c0..0000000 +--- a/gdb/testsuite/gdb.base/pie-support.exp ++++ /dev/null +@@ -1,58 +0,0 @@ +-# Copyright 2009 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 . +- +-set testfile pie-support +-set srcfile ${testfile}.c +-set objfile ${objdir}/${subdir}/${testfile}.o +-set binfile ${objdir}/${subdir}/${testfile} +- +-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {quiet debug additional_flags=-fpie}] != "" } { +- untested "Couldn't compile test PIE object file." +- return -1 +-} +-if { [gdb_compile "${objfile}" "${binfile}" executable {quiet debug additional_flags=-pie}] != "" } { +- untested "Couldn't compile test PIE binary." +- return -1 +-} +- +-# Get things started. +- +-gdb_exit +-gdb_start +-gdb_reinitialize_dir $srcdir/$subdir +- +-if [is_remote host] { +- set binfile [remote_download host $binfile] +- if { $binfile == "" } { +- untested "Couldn't download remote test binary." +- return -1 +- } +-} +- +-# The file command used to kill the remote target. For the benefit +-# of the testsuite, preserve this behavior. +-send_gdb "kill\n" +-gdb_expect 120 { +- -re "Kill the program being debugged. .y or n. $" { +- send_gdb "y\n" +- verbose "\t\tKilling previous program being debugged" +- exp_continue +- } +- -re "$gdb_prompt $" { +- # OK. +- } +-} +- +-gdb_test "file $binfile" "current binary is a PIE.*" "correctly detected PIE binary" +diff --git a/gdb/testsuite/gdb.base/valgrind-db-attach.c b/gdb/testsuite/gdb.base/valgrind-db-attach.c +new file mode 100644 +index 0000000..5faaaac +--- /dev/null ++++ b/gdb/testsuite/gdb.base/valgrind-db-attach.c +@@ -0,0 +1,30 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2009 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 . */ ++ ++#include ++ ++int main() ++{ ++ void *p; ++ ++ p = malloc (1); ++ if (p == NULL) ++ return 1; ++ free (p); ++ free (p); /* double-free */ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/valgrind-db-attach.exp b/gdb/testsuite/gdb.base/valgrind-db-attach.exp +new file mode 100644 +index 0000000..ac06fd3 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/valgrind-db-attach.exp +@@ -0,0 +1,74 @@ ++# Copyright 2009 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 . ++ ++set test valgrind-db-attach ++set srcfile $test.c ++set executable $test ++set binfile ${objdir}/${subdir}/${executable} ++if {[build_executable $test.exp $executable $srcfile {debug}] == -1} { ++ return -1 ++} ++ ++gdb_exit ++ ++# remote_spawn breaks the command on each whitespace despite possible quoting. ++# Use backslash-escaped whitespace there instead: ++ ++set db_command "--db-command=$GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts] %f %p" ++regsub -all " " $db_command "\\ " db_command ++ ++set test "spawn valgrind" ++set cmd "valgrind --db-attach=yes $db_command $binfile" ++set res [remote_spawn host $cmd]; ++if { $res < 0 || $res == "" } { ++ verbose -log "Spawning $cmd failed." ++ setup_xfail *-*-* ++ fail $test ++ return -1 ++} ++pass $test ++# Declare GDB now as running. ++set gdb_spawn_id -1 ++ ++set test "valgrind started" ++# The trailing '.' differs for different memcheck versions. ++gdb_test_multiple "" $test { ++ -re "Memcheck, a memory error detector\\.?\r\n" { ++ pass $test ++ } ++ -re "valgrind: failed to start tool 'memcheck' for platform '.*': No such file or directory" { ++ setup_xfail *-*-* ++ fail $test ++ return -1 ++ } ++} ++ ++set double_free [gdb_get_line_number "double-free"] ++ ++gdb_test_multiple "" $test { ++ -re "Invalid free\\(\\) / delete / delete\\\[\\\]\r\n.*: main \\(${srcfile}:$double_free\\)\r\n.*---- Attach to debugger \\? --- \[^\r\n\]* ---- " { ++ send_gdb "y\r" ++ } ++ -re "---- Attach to debugger \\? --- \[^\r\n\]* ---- " { ++ send_gdb "n\r" ++ exp_continue ++ } ++} ++ ++# Initialization from default_gdb_start. ++gdb_test "set height 0" ++gdb_test "set width 0" ++ ++gdb_test "bt" "in main \\(.*\\) at .*${srcfile}:$double_free" +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges.exp +index 61e1fe4..9109030 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-ranges.exp ++++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges.exp +@@ -55,6 +55,12 @@ gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + ++# Test also objfile->psymtabs_addrmap relocations for -fPIE -pie builds below. ++# On some targets it may possibly fail but the program is being started only ++# for the PIE build so try it anyway. ++ ++runto_main ++ + # Correct output: + # Line 39 of "../.././gdb/testsuite/gdb.dwarf2/dw2-ranges.S" starts at address 0x4 and ends at 0x8. + # Wrong output: +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +index d0c3493..fbf9124 100644 +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -2778,6 +2778,11 @@ proc gdb_gnu_strip_debug { dest args } { + return 1 + } + ++ # Workaround PR binutils/10802: ++ # Preserve the 'x' bit also for PIEs (Position Independent Executables). ++ set perm [file attributes ${dest} -permissions] ++ file attributes ${stripped_file} -permissions $perm ++ + # Get rid of everything but the debug info, and store result in debug_file + # This will be in the .debug subdirectory, see above. + set result [catch "exec $strip_to_file_program --only-keep-debug ${dest} -o ${debug_file}" output] +@@ -2814,7 +2819,12 @@ proc gdb_gnu_strip_debug { dest args } { + return 1 + } + +- return 0 ++ # Workaround PR binutils/10802: ++ # Preserve the 'x' bit also for PIEs (Position Independent Executables). ++ set perm [file attributes ${stripped_file} -permissions] ++ file attributes ${dest} -permissions $perm ++ ++ return 0 + } + + # Test the output of GDB_COMMAND matches the pattern obtained +@@ -3043,3 +3053,70 @@ if {[info exists TRANSCRIPT]} { + return [uplevel real_send_gdb $args] + } + } ++ ++proc core_find {binfile {deletefiles {}} {arg ""}} { ++ global objdir subdir ++ ++ set destcore "$binfile.core" ++ file delete $destcore ++ ++ # Create a core file named "$destcore" rather than just "core", to ++ # avoid problems with sys admin types that like to regularly prune all ++ # files named "core" from the system. ++ # ++ # Arbitrarily try setting the core size limit to "unlimited" since ++ # this does not hurt on systems where the command does not work and ++ # allows us to generate a core on systems where it does. ++ # ++ # Some systems append "core" to the name of the program; others append ++ # the name of the program to "core"; still others (like Linux, as of ++ # May 2003) create cores named "core.PID". In the latter case, we ++ # could have many core files lying around, and it may be difficult to ++ # tell which one is ours, so let's run the program in a subdirectory. ++ set found 0 ++ set coredir "${objdir}/${subdir}/coredir.[getpid]" ++ file mkdir $coredir ++ catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile} ${arg}; true) >/dev/null 2>&1\"" ++ # remote_exec host "${binfile}" ++ foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" { ++ if [remote_file build exists $i] { ++ remote_exec build "mv $i $destcore" ++ set found 1 ++ } ++ } ++ # Check for "core.PID". ++ if { $found == 0 } { ++ set names [glob -nocomplain -directory $coredir core.*] ++ if {[llength $names] == 1} { ++ set corefile [file join $coredir [lindex $names 0]] ++ remote_exec build "mv $corefile $destcore" ++ set found 1 ++ } ++ } ++ if { $found == 0 } { ++ # The braindamaged HPUX shell quits after the ulimit -c above ++ # without executing ${binfile}. So we try again without the ++ # ulimit here if we didn't find a core file above. ++ # Oh, I should mention that any "braindamaged" non-Unix system has ++ # the same problem. I like the cd bit too, it's really neat'n stuff. ++ catch "system \"(cd ${objdir}/${subdir}; ${binfile}; true) >/dev/null 2>&1\"" ++ foreach i "${objdir}/${subdir}/core ${objdir}/${subdir}/core.coremaker.c ${binfile}.core" { ++ if [remote_file build exists $i] { ++ remote_exec build "mv $i $destcore" ++ set found 1 ++ } ++ } ++ } ++ ++ # Try to clean up after ourselves. ++ foreach deletefile $deletefiles { ++ remote_file build delete [file join $coredir $deletefile] ++ } ++ remote_exec build "rmdir $coredir" ++ ++ if { $found == 0 } { ++ warning "can't generate a core file - core tests suppressed - check ulimit -c" ++ return "" ++ } ++ return $destcore ++} diff --git a/gdb-archer.patch b/gdb-archer.patch index 619eef9..330c50d 100644 --- a/gdb-archer.patch +++ b/gdb-archer.patch @@ -2,7 +2,7 @@ http://sourceware.org/gdb/wiki/ProjectArcher http://sourceware.org/gdb/wiki/ArcherBranchManagement GIT snapshot: -commit 6817a81cd411acc9579f04dcc105e9bce72859ff +commit 16276c1aad1366b92e687c72cab30192280e1906 branch `archer' - the merge of branches: archer-tromey-call-frame-cfa @@ -12245,10 +12245,22 @@ index a84003f..924c1c5 100644 default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */ default_symfile_segments, /* sym_segments: Get segment information from diff --git a/gdb/objfiles.c b/gdb/objfiles.c -index 8dcca70..4b25a5a 100644 +index 8dcca70..e5442ca 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c -@@ -731,6 +731,20 @@ have_partial_symbols (void) +@@ -634,6 +634,11 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) + } + } + ++ /* Alread QUICK_ADDRMAP tiself assumes all sections have the same offset. */ ++ if (objfile->quick_addrmap) ++ addrmap_relocate (objfile->quick_addrmap, ++ ANOFFSET (delta, SECT_OFF_TEXT (objfile))); ++ + { + struct partial_symbol **psym; + +@@ -731,6 +736,20 @@ have_partial_symbols (void) if (objfile_has_partial_symbols (ofp)) return 1; } diff --git a/gdb-readline-6.0-signal.patch b/gdb-readline-6.0-signal.patch new file mode 100644 index 0000000..0873bea --- /dev/null +++ b/gdb-readline-6.0-signal.patch @@ -0,0 +1,312 @@ +http://sourceware.org/ml/gdb-patches/2009-11/msg00596.html +Subject: [gdb FYI-patch] callback-mode readline-6.0 regression + +Hi Chet, + +FSF GDB currently ships bundled with readline-5.2 which works fine. +But using --with-system-readline and readline-6.0-patchlevel4 has +a regression: + +readline-5.2: Run `gdb -nx -q' and type CTRL-C: +(gdb) Quit +(gdb) _ + +readline-6.0: Run `gdb -nx -q' and type CTRL-C: +(gdb) _ + = nothing happens (it gets buffered and executed later) + (It does also FAIL on gdb.gdb/selftest.exp.) + +It is because GDB waits in its own poll() mainloop and readline uses via +rl_callback_handler_install and rl_callback_handler_remove. This way the +readline internal variable _rl_interrupt_immediately remains 0 and CTRL-C gets +only stored to _rl_caught_signal but not executed. + +Seen in rl_signal_handler even if _rl_interrupt_immediately is set and +_rl_handle_signal is called then the signal is still stored to +_rl_caught_signal. In the _rl_interrupt_immediately case it should not be +stored when it was already processed. + +rl_signal_handler does `_rl_interrupt_immediately = 0;' - while I am not aware +of its meaning it breaks the nest-counting of other routines which do +`_rl_interrupt_immediately++;' and `_rl_interrupt_immediately--;' possibly +creating problematic `_rl_interrupt_immediately == -1'. + +`_rl_interrupt_immediately' is an internal variable, how it could be accessed +by a readline application? (OK, maybe it should not be used.) + +Attaching a current GDB-side patch but it must access readline internal +variable _rl_caught_signal and it is generally just a workaround. Could you +please include support for signals in this asynchronous mode in readline-6.1? +I find it would be enough to make RL_CHECK_SIGNALS public? + + +GDB: No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu. +But this is not a patch intended to be accepted. + + +Thanks, +Jan + + +gdb/ +2009-11-29 Jan Kratochvil + + * config.in, configure: Regenerate. + * configure.ac (for readline_echoing_p): Move inside $LIBS change. + (for _rl_caught_signal): New. + * event-loop.c: Include readline/readline.h. + (gdb_do_one_event) [HAVE_READLINE_CAUGHT_SIGNAL]: New. + +gdb/testsuite/ +2009-11-29 Jan Kratochvil + + * gdb.gdb/selftest.exp (backtrace through signal handler): Move before + SIGINT pass, drop the timeout case. + (send SIGINT signal to child process): Use gdb_test. + (backtrace through readline handler): New. + +--- a/gdb/config.in ++++ b/gdb/config.in +@@ -351,6 +351,9 @@ + /* Define if Python interpreter is being linked in. */ + #undef HAVE_PYTHON + ++/* readline-6.0 workaround of blocked signals. */ ++#undef HAVE_READLINE_CAUGHT_SIGNAL ++ + /* Define to 1 if you have the `realpath' function. */ + #undef HAVE_REALPATH + +--- a/gdb/configure.ac ++++ b/gdb/configure.ac +@@ -539,17 +539,25 @@ if test "$with_system_readline" = yes; then + # readline-6.0 started to use the name `_rl_echoing_p'. + # `$(READLINE_DIR)/' of bundled readline would not resolve in configure. + +- AC_MSG_CHECKING([for readline_echoing_p]) + save_LIBS=$LIBS + LIBS="$LIBS $READLINE" ++ AC_MSG_CHECKING([for readline_echoing_p]) + AC_LINK_IFELSE(AC_LANG_PROGRAM(,[[extern int readline_echoing_p; + return readline_echoing_p;]]), + [READLINE_ECHOING_P=yes], + [READLINE_ECHOING_P=no + AC_DEFINE([readline_echoing_p], [_rl_echoing_p], + [readline-6.0 started to use different name.])]) +- LIBS="$save_LIBS" + AC_MSG_RESULT([$READLINE_ECHOING_P]) ++ AC_MSG_CHECKING([for _rl_caught_signal]) ++ AC_LINK_IFELSE(AC_LANG_PROGRAM(,[[extern int volatile _rl_caught_signal; ++ return _rl_caught_signal;]]), ++ [READLINE_CAUGHT_SIGNAL=yes ++ AC_DEFINE([HAVE_READLINE_CAUGHT_SIGNAL],, ++ [readline-6.0 workaround of blocked signals.])], ++ [READLINE_CAUGHT_SIGNAL=no]) ++ AC_MSG_RESULT([$READLINE_CAUGHT_SIGNAL]) ++ LIBS="$save_LIBS" + else + READLINE='$(READLINE_DIR)/libreadline.a' + READLINE_DEPS='$(READLINE)' +--- a/gdb/event-loop.c ++++ b/gdb/event-loop.c +@@ -37,6 +37,7 @@ + #include "exceptions.h" + #include "gdb_assert.h" + #include "gdb_select.h" ++#include "readline/readline.h" + + /* Data point to pass to the event handler. */ + typedef union event_data +@@ -411,6 +412,9 @@ gdb_do_one_event (void *data) + static int event_source_head = 0; + const int number_of_sources = 3; + int current = 0; ++#ifdef HAVE_READLINE_CAUGHT_SIGNAL ++ extern int volatile _rl_caught_signal; ++#endif + + /* Any events already waiting in the queue? */ + if (process_event ()) +@@ -455,6 +459,16 @@ gdb_do_one_event (void *data) + if (gdb_wait_for_event (1) < 0) + return -1; + ++#ifdef HAVE_READLINE_CAUGHT_SIGNAL ++ if (async_command_editing_p && RL_ISSTATE (RL_STATE_CALLBACK) ++ && _rl_caught_signal) ++ { ++ /* Call RL_CHECK_SIGNALS this way. */ ++ rl_callback_handler_remove (); ++ rl_callback_handler_install (NULL, input_handler); ++ } ++#endif ++ + /* Handle any new events occurred while waiting. */ + if (process_event ()) + return 1; +--- a/gdb/testsuite/gdb.gdb/selftest.exp ++++ b/gdb/testsuite/gdb.gdb/selftest.exp +@@ -464,31 +464,42 @@ GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\ + fail "$description (timeout)" + } + } +- +- set description "send SIGINT signal to child process" +- send_gdb "signal SIGINT\n" +- gdb_expect { +- -re "Continuing with signal SIGINT.*$gdb_prompt $" { ++ ++ # get a stack trace with the poll function ++ # ++ # This fails on some linux systems for unknown reasons. On the ++ # systems where it fails, sometimes it works fine when run manually. ++ # The testsuite failures may not be limited to just aout systems. ++ setup_xfail "i*86-pc-linuxaout-gnu" ++ set description "backtrace through signal handler" ++ gdb_test_multiple "backtrace" $description { ++ -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { + pass "$description" + } + -re ".*$gdb_prompt $" { ++ # On the alpha, we hit the infamous problem about gdb ++ # being unable to get the frame pointer (mentioned in ++ # gdb/README). As it is intermittent, there is no way to ++ # XFAIL it which will give us an XPASS if the problem goes ++ # away. ++ setup_xfail "alpha*-*-osf*" + fail "$description" + } +- timeout { +- fail "$description (timeout)" +- } + } + +- # get a stack trace ++ gdb_test "signal SIGINT" "Continuing with signal SIGINT.*" \ ++ "send SIGINT signal to child process" ++ ++ # get a stack trace being redelivered by readline + # + # This fails on some linux systems for unknown reasons. On the + # systems where it fails, sometimes it works fine when run manually. + # The testsuite failures may not be limited to just aout systems. ++ # Optional system readline may not have symbols to be shown. + setup_xfail "i*86-pc-linuxaout-gnu" +- set description "backtrace through signal handler" +- send_gdb "backtrace\n" +- gdb_expect { +- -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { ++ set description "backtrace through readline handler" ++ gdb_test_multiple "backtrace" $description { ++ -re "#0.*gdb_do_one_event.*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { + pass "$description" + } + -re ".*$gdb_prompt $" { +@@ -500,9 +510,6 @@ GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\ + setup_xfail "alpha*-*-osf*" + fail "$description" + } +- timeout { +- fail "$description (timeout)" +- } + } + + +--- gdb-7.0/gdb/configure 2009-12-07 18:53:30.000000000 +0100 ++++ gdb-7.0-x/gdb/configure 2009-12-07 18:53:14.000000000 +0100 +@@ -9201,15 +9201,11 @@ if test "$with_system_readline" = yes; t + # readline-6.0 started to use the name `_rl_echoing_p'. + # `$(READLINE_DIR)/' of bundled readline would not resolve in configure. + +- echo "$as_me:$LINENO: checking for readline_echoing_p" >&5 +-echo $ECHO_N "checking for readline_echoing_p... $ECHO_C" >&6 + save_LIBS=$LIBS + LIBS="$LIBS $READLINE" +- cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ +-_ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline_echoing_p" >&5 ++$as_echo_n "checking for readline_echoing_p... " >&6; } ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -9221,45 +9217,45 @@ extern int readline_echoing_p; + return 0; + } + _ACEOF +-rm -f conftest.$ac_objext conftest$ac_exeext +-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 +- (eval $ac_link) 2>conftest.er1 +- ac_status=$? +- grep -v '^ *+' conftest.er1 >conftest.err +- rm -f conftest.er1 +- cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 +- (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" +- || test ! -s conftest.err' +- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 +- (exit $ac_status); }; } && +- { ac_try='test -s conftest$ac_exeext' +- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 +- (exit $ac_status); }; }; then ++if ac_fn_c_try_link "$LINENO"; then : + READLINE_ECHOING_P=yes + else +- echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 ++ READLINE_ECHOING_P=no + +-READLINE_ECHOING_P=no ++$as_echo "#define readline_echoing_p _rl_echoing_p" >>confdefs.h ++ ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_ECHOING_P" >&5 ++$as_echo "$READLINE_ECHOING_P" >&6; } ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _rl_caught_signal" >&5 ++$as_echo_n "checking for _rl_caught_signal... " >&6; } ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ + +-cat >>confdefs.h <<\_ACEOF +-#define readline_echoing_p _rl_echoing_p ++int ++main () ++{ ++extern int volatile _rl_caught_signal; ++ return _rl_caught_signal; ++ ; ++ return 0; ++} + _ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ READLINE_CAUGHT_SIGNAL=yes ++ ++$as_echo "#define HAVE_READLINE_CAUGHT_SIGNAL /**/" >>confdefs.h + ++else ++ READLINE_CAUGHT_SIGNAL=no + fi +-rm -f conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_CAUGHT_SIGNAL" >&5 ++$as_echo "$READLINE_CAUGHT_SIGNAL" >&6; } + LIBS="$save_LIBS" +- echo "$as_me:$LINENO: result: $READLINE_ECHOING_P" >&5 +-echo "${ECHO_T}$READLINE_ECHOING_P" >&6 + else + READLINE='$(READLINE_DIR)/libreadline.a' + READLINE_DEPS='$(READLINE)' diff --git a/gdb-x86_64-i386-syscall-restart.patch b/gdb-x86_64-i386-syscall-restart.patch new file mode 100644 index 0000000..d5d6b10 --- /dev/null +++ b/gdb-x86_64-i386-syscall-restart.patch @@ -0,0 +1,121 @@ +http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html +Subject: [patch] Fix syscall restarts for amd64->i386 biarch + +Hi, + +tested only on recent Linux kernels, it should apply also on vanilla ones. +There were various changes of the kernels behavior in the past. + +FSF GDB HEAD state: +kernel debugger inferior state +x86_64 x86_64 x86_64 PASS +x86_64 x86_64 i386 FAIL without this patch, PASS with this patch +x86_64 i386 i386 PASS on recent kernels + (FAIL: kernel-2.6.31.5-127.fc12.x86_64 - Fedora 12) + (PASS: kernel-2.6.32-0.55.rc8.git1.fc13.x86_64) +i386 i386 i386 PASS + + +Currently gdb.base/interrupt.exp fails on amd64 host running under +--target_board unix/-m32 with: + continue + Continuing. + Unknown error 512 + +: +/* + * These should never be seen by user programs. To return one of ERESTART* + * codes, signal_pending() MUST be set. Note that ptrace can observe these + * at syscall exit tracing, but they will never be left for the debugged user + * process to see. + */ +#define ERESTARTSYS 512 + +"Unknown error 512" printed above is printed by the inferior itself, not by GDB. + +It is because GDB reads it as 0xfffffffffffffe00 but writes it back as +0xfffffe00. ++ /* Sign-extend %eax as during return from a syscall it is being checked ++ for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by ++ interrupt.exp. */ + + +Quote of Roland McGrath from IRC: + +roland: in the user_regset model, there are 64-bit user_regset flavors and +32-bit user_regset flavors, so at the kabi level the (kernel) caller can say +what it means: calls on the 32-bit user_regset flavor will behave as if on +a 32-bit kernel/userland. in ptrace, there is no way for x86_64 ptrace calls +to say "i think of the inferior as being 32 bits, so act accordingly" (tho ppc +and/or sparc have ptr +roland: ace requests that do that iirc) +roland: ergo 64-bit ptrace callers must either save/restore full 64-bits so +the kernel's sign-extension choices are preserved, or else grok magic ways to +expand stored 32-bit register contents to 64-bit values to stuff via 64-bit +ptrace +[...] +roland: there is a "32-bit-flavored task", but it's not really true that it +has 32-bit registers. there is no 32-bit-only userland condition. any task +can always ljmp to the 64-bit code segment and run 64-bit insns including +a 64-bit syscall +roland: so a 64-bit debugger should see and be able to fiddle the full +registers. it can even change cs via ptrace to force the inferior into +running 32 or 64 bit code. + + +Saving whole 64bits for i386 targets on x86_64 hosts does not much match the +GDB architecture as `struct type' for these registers still should be 32bit +etc. Therefore provided just this exception. + +The problem is reproducible only if one does an inferior call during the +interruption to do full inferior save/restore from GDB regcache. + +Regression tested on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu. + + +Thanks, +Jan + + +gdb/ +2009-11-29 Jan Kratochvil + + * amd64-nat.c (amd64_collect_native_gregset): Do not pre-clear %eax. + Sign extend it afterwards. + +--- a/gdb/amd64-nat.c ++++ b/gdb/amd64-nat.c +@@ -131,9 +131,9 @@ amd64_collect_native_gregset (const struct regcache *regcache, + { + num_regs = amd64_native_gregset32_num_regs; + +- /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and ++ /* Make sure %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and + %eip get zero-extended to 64 bits. */ +- for (i = 0; i <= I386_EIP_REGNUM; i++) ++ for (i = I386_ECX_REGNUM; i <= I386_EIP_REGNUM; i++) + { + if (regnum == -1 || regnum == i) + memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8); +@@ -159,4 +159,20 @@ amd64_collect_native_gregset (const struct regcache *regcache, + regcache_raw_collect (regcache, i, regs + offset); + } + } ++ ++ if (gdbarch_ptr_bit (gdbarch) == 32) ++ { ++ /* Sign-extend %eax as during return from a syscall it is being checked ++ for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by ++ interrupt.exp. */ ++ ++ int i = I386_EAX_REGNUM; ++ ++ if (regnum == -1 || regnum == i) ++ { ++ void *ptr = regs + amd64_native_gregset_reg_offset (gdbarch, i); ++ ++ *(int64_t *) ptr = *(int32_t *) ptr; ++ } ++ } + } + diff --git a/gdb.spec b/gdb.spec index 0b5305c..a906cfc 100644 --- a/gdb.spec +++ b/gdb.spec @@ -14,7 +14,7 @@ Version: 7.0 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 8%{?_with_upstream:.upstream}%{?dist} +Release: 9%{?_with_upstream:.upstream}%{?dist} License: GPLv3+ Group: Development/Debuggers @@ -92,14 +92,12 @@ Patch118: gdb-6.3-gstack-20050411.patch # VSYSCALL and PIE Patch122: gdb-6.3-test-pie-20050107.patch -Patch124: gdb-6.3-pie-20050110.patch +Patch124: gdb-archer-pie.patch +Patch389: gdb-archer-pie-addons.patch # Get selftest working with sep-debug-info Patch125: gdb-6.3-test-self-20050110.patch -# Fix for non-threaded watchpoints. -Patch128: gdb-6.3-nonthreaded-wp-20050117.patch - # Test support of multiple destructors just like multiple constructors Patch133: gdb-6.3-test-dtorfix-20050121.patch @@ -377,6 +375,12 @@ Patch387: gdb-bz539590-gnu-ifunc.patch # Fix bp conditionals [bp_location-accel] regression (Phil Muldoon, BZ 538626). Patch388: gdb-bz538626-bp_location-accel-bp-cond.patch +# Fix callback-mode readline-6.0 regression for CTRL-C. +Patch390: gdb-readline-6.0-signal.patch + +# Fix syscall restarts for amd64->i386 biarch. +Patch391: gdb-x86_64-i386-syscall-restart.patch + BuildRequires: ncurses-devel texinfo gettext flex bison expat-devel Requires: readline BuildRequires: readline-devel @@ -475,6 +479,7 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch383 -p1 %patch384 -p1 %patch385 -p1 +%patch124 -p1 %patch1 -p1 %patch3 -p1 @@ -486,7 +491,6 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch118 -p1 %patch122 -p1 %patch125 -p1 -%patch128 -p1 %patch133 -p1 %patch136 -p1 %patch140 -p1 @@ -579,7 +583,9 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch382 -p1 %patch387 -p1 %patch388 -p1 -%patch124 -p1 +%patch389 -p1 +%patch390 -p1 +%patch391 -p1 find -name "*.orig" | xargs rm -f ! find -name "*.rej" # Should not happen. @@ -884,6 +890,16 @@ fi %endif %changelog +* Mon Dec 7 2009 Jan Kratochvil - 7.0-9.fc12 +- Replace the PIE (Position Indepdent Executable) support patch by a new one. +- Drop gdb-6.3-nonthreaded-wp-20050117.patch as fuzzy + redundant. +- Fix callback-mode readline-6.0 regression for CTRL-C. +- Fix syscall restarts for amd64->i386 biarch. +- Various testsuite results stability fixes. +- Fix crash on reading stabs on 64bit (BZ 537837). +- archer-jankratochvil-fedora12 commit: 16276c1aad1366b92e687c72cab30192280e1906 +- archer-jankratochvil-pie-fedora12 ct: 2ae60b5156d43aabfe5757940eaf7b4370fb05d2 + * Thu Dec 3 2009 Jan Kratochvil - 7.0-8.fc12 - Fix slowness/hang when printing some variables (Sami Wagiaalla, BZ 541093). - archer-jankratochvil-fedora12 commit: 6817a81cd411acc9579f04dcc105e9bce72859ff