]> git.pld-linux.org Git - packages/gdb.git/blame - gdb-bz614659-prelink-dynbss.patch
- updated (performance fixes).
[packages/gdb.git] / gdb-bz614659-prelink-dynbss.patch
CommitLineData
51a5ef0f
PS
1http://sourceware.org/ml/gdb-patches/2010-07/msg00237.html
2Subject: [patch] Fix regression on prelinked executables
3
4Hi,
5
6there is a regression since gdb-7.0 for a combination of:
7 * prelinked
8 * main executable
9 * using separate debug info
10 * using copy relocations
11
12It is since a patch for both PIE and (AFAIK) OSX support:
13 [commit] syms_from_objfile: Relativize also MAINLINE
14 http://sourceware.org/ml/gdb-patches/2010-01/msg00080.html
15
16which started to use problematic addr_info_make_relative even for main
17executables. prelink<->gdb discussion at:
18 https://bugzilla.redhat.com/show_bug.cgi?id=614659
19
20Currently in the unfortunately executables GDB has invalid displcement for
21symbols in .bss:
22 int bssvar, *bssvarp = &bssvar;
23 (gdb) p &bssvar
24 $1 = (int *) 0x600b54
25 (gdb) p bssvarp
26 $2 = (int *) 0x600b50
27
28<abstract-higher-point-of-view>
29addr_info_make_relative could just simply subtract entry point address and
30provide single CORE_ADDR objfile->offset (instead of the current
31section_offsets array with offsets specific for each section). Linux systems
32use always single offset for the whole objfile. AFAIK these per-section
33offsets are there for some embedded targets. Curiously GDB already uses at
34many places
35 baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
36instead of using offset for the appropriate section at that place and nobody
37complains.
38</abstract-higher-point-of-view>
39
40No regressions on {x86_64,x86_64-m32,i686}-fedora13-linux-gnu.
41
42Proposing for the gdb-7.2 branch. I had problems fixing up my crashing X.
43
44
45Thanks,
46Jan
47
48
49gdb/
502010-07-15 Jan Kratochvil <jan.kratochvil@redhat.com>
51
52 * symfile.c (addr_section_name): New function.
53 (addrs_section_compar): Use it.
54 (addr_info_make_relative): Use it. Move variable sect_name into a more
55 inner block. Make ".dynbss" and ".sdynbss" checks more strict.
56
57gdb/testsuite/
582010-07-15 Jan Kratochvil <jan.kratochvil@redhat.com>
59
60 * gdb.base/prelink-lib.c (copyreloc): New initialized variable.
61 * gdb.base/prelink.c (copyreloc, bssvar, bssvarp): New variables.
62 (main): Use copyreloc.
63 * gdb.base/prelink.exp (split debug of executable)
64 (.dynbss vs. .bss address shift): New tests.
65
66--- a/gdb/symfile.c
67+++ b/gdb/symfile.c
68@@ -547,6 +547,23 @@ relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
69 }
70 }
71
72+/* Transform section name S for a name comparison. prelink can split section
73+ `.bss' into two sections `.dynbss' and `.bss' (in this order). Similarly
74+ prelink can split `.sbss' into `.sdynbss' and `.sbss'. Use virtual address
75+ of the new `.dynbss' (`.sdynbss') section as the adjacent new `.bss'
76+ (`.sbss') section has invalid (increased) virtual address. */
77+
78+static const char *
79+addr_section_name (const char *s)
80+{
81+ if (strcmp (s, ".dynbss") == 0)
82+ return ".bss";
83+ if (strcmp (s, ".sdynbss") == 0)
84+ return ".sbss";
85+
86+ return s;
87+}
88+
89 /* qsort comparator for addrs_section_sort. Sort entries in ascending order by
90 their (name, sectindex) pair. sectindex makes the sort by name stable. */
91
92@@ -557,7 +574,7 @@ addrs_section_compar (const void *ap, const void *bp)
93 const struct other_sections *b = *((struct other_sections **) bp);
94 int retval, a_idx, b_idx;
95
96- retval = strcmp (a->name, b->name);
97+ retval = strcmp (addr_section_name (a->name), addr_section_name (b->name));
98 if (retval)
99 return retval;
100
101@@ -641,14 +658,16 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
102
103 while (*addrs_sorted)
104 {
105- const char *sect_name = (*addrs_sorted)->name;
106+ const char *sect_name = addr_section_name ((*addrs_sorted)->name);
107
108 while (*abfd_addrs_sorted
109- && strcmp ((*abfd_addrs_sorted)->name, sect_name) < 0)
110+ && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
111+ sect_name) < 0)
112 abfd_addrs_sorted++;
113
114 if (*abfd_addrs_sorted
115- && strcmp ((*abfd_addrs_sorted)->name, sect_name) == 0)
116+ && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
117+ sect_name) == 0)
118 {
119 int index_in_addrs;
120
121@@ -676,7 +695,6 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
122
123 for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
124 {
125- const char *sect_name = addrs->other[i].name;
126 struct other_sections *sect = addrs_to_abfd_addrs[i];
127
128 if (sect)
129@@ -694,6 +712,9 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
130 }
131 else
132 {
133+ /* addr_section_name transformation is not used for SECT_NAME. */
134+ const char *sect_name = addrs->other[i].name;
135+
136 /* This section does not exist in ABFD, which is normally
137 unexpected and we want to issue a warning.
138
139@@ -704,12 +725,20 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
140 a warning. Shared libraries contain just the section
141 ".gnu.liblist" but it is not marked as loadable there. There is
142 no other way to identify them than by their name as the sections
143- created by prelink have no special flags. */
144+ created by prelink have no special flags.
145+
146+ For the sections `.bss' and `.sbss' see addr_section_name. */
147
148 if (!(strcmp (sect_name, ".gnu.liblist") == 0
149 || strcmp (sect_name, ".gnu.conflict") == 0
150- || strcmp (sect_name, ".dynbss") == 0
151- || strcmp (sect_name, ".sdynbss") == 0))
152+ || (strcmp (sect_name, ".bss") == 0
153+ && i > 0
154+ && strcmp (addrs->other[i - 1].name, ".dynbss") == 0
155+ && addrs_to_abfd_addrs[i - 1] != NULL)
156+ || (strcmp (sect_name, ".sbss") == 0
157+ && i > 0
158+ && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0
159+ && addrs_to_abfd_addrs[i - 1] != NULL)))
160 warning (_("section %s not found in %s"), sect_name,
161 bfd_get_filename (abfd));
162
163--- a/gdb/testsuite/gdb.base/prelink-lib.c
164+++ b/gdb/testsuite/gdb.base/prelink-lib.c
165@@ -16,6 +16,8 @@
166 along with this program. If not, see <http://www.gnu.org/licenses/>.
167 */
168
169+int copyreloc = 1;
170+
171 int
172 g (void (*p)(void))
173 {
174--- a/gdb/testsuite/gdb.base/prelink.c
175+++ b/gdb/testsuite/gdb.base/prelink.c
176@@ -18,6 +18,11 @@
177
178 #include <stdio.h>
179
180+extern int copyreloc;
181+
182+/* Test GDB itself finds `&bssvar' right. */
183+static int bssvar, *bssvarp = &bssvar;
184+
185 extern void (*h (void)) (void (*)(void));
186
187 int
188@@ -25,5 +30,6 @@ main (void)
189 {
190 void (*f) (void (*)(void)) = h ();
191 printf ("%p\n", f);
192+ printf ("%d\n", copyreloc);
193 f (0);
194 }
195--- a/gdb/testsuite/gdb.base/prelink.exp
196+++ b/gdb/testsuite/gdb.base/prelink.exp
197@@ -57,6 +57,13 @@ if {$prelink_args == ""} {
198 return -1
199 }
200
201+set test "split debug of executable"
202+if [gdb_gnu_strip_debug $binfile] {
203+ fail $test
204+} else {
205+ pass $test
206+}
207+
208 if ![prelink_yes $prelink_args] {
209 # Maybe we don't have prelink.
210 return -1
211@@ -105,3 +112,5 @@ clean_restart $executable
212 gdb_test_no_output "set verbose on"
213
214 gdb_test "core-file $objdir/$subdir/prelink.core" "Using PIC \\(Position Independent Code\\) prelink displacement 0x\[^0\]\[0-9a-f\]* for \[^\r\n\]*[file tail ${libfile}].*" "seen displacement message"
215+
216+gdb_test "p &bssvar == bssvarp" " = 1" ".dynbss vs. .bss address shift"
217
This page took 0.582723 seconds and 4 git commands to generate.