]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | 2007-11-02 Jan Kratochvil <jan.kratochvil@redhat.com> |
2 | ||
3 | Port to GDB-6.7.1. | |
4 | ||
5 | 2007-11-02 Jan Kratochvil <jan.kratochvil@redhat.com> | |
6 | ||
7 | Port to post-GDB-6.7.1 multi-PC breakpoints. | |
8 | ||
9 | 2007-11-09 Jan Kratochvil <jan.kratochvil@redhat.com> | |
10 | ||
11 | * solib-svr4.c (svr4_current_sos): Fix segfault on NULL EXEC_BFD. | |
12 | ||
13 | 2008-02-24 Jan Kratochvil <jan.kratochvil@redhat.com> | |
14 | ||
15 | Port to GDB-6.8pre. | |
16 | ||
17 | 2008-02-27 Jan Kratochvil <jan.kratochvil@redhat.com> | |
18 | ||
19 | Port to gdb-6.7.50.20080227. | |
20 | ||
21 | 2008-06-01 Jan Kratochvil <jan.kratochvil@redhat.com> | |
22 | ||
23 | Fix crash on a watchpoint update on an inferior stop. | |
24 | ||
25 | 2008-09-01 Jan Kratochvil <jan.kratochvil@redhat.com> | |
26 | ||
27 | Fix scan_dyntag() for binaries provided by valgrind (BZ 460319). | |
28 | ||
29 | Index: gdb-6.8.50.20090302/gdb/amd64-tdep.c | |
30 | =================================================================== | |
31 | --- gdb-6.8.50.20090302.orig/gdb/amd64-tdep.c 2009-03-07 00:30:09.000000000 +0100 | |
32 | +++ gdb-6.8.50.20090302/gdb/amd64-tdep.c 2009-03-07 00:30:12.000000000 +0100 | |
33 | @@ -36,6 +36,7 @@ | |
34 | #include "regcache.h" | |
35 | #include "regset.h" | |
36 | #include "symfile.h" | |
37 | +#include "exceptions.h" | |
38 | ||
39 | #include "gdb_assert.h" | |
40 | ||
41 | @@ -1586,16 +1587,28 @@ amd64_analyze_stack_align (CORE_ADDR pc, | |
42 | Any function that doesn't start with this sequence will be assumed | |
43 | to have no prologue and thus no valid frame pointer in %rbp. */ | |
44 | ||
45 | -static CORE_ADDR | |
46 | -amd64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, | |
47 | - struct amd64_frame_cache *cache) | |
48 | +struct amd64_analyze_prologue_data | |
49 | + { | |
50 | + CORE_ADDR pc, current_pc; | |
51 | + struct amd64_frame_cache *cache; | |
52 | + CORE_ADDR retval; | |
53 | + }; | |
54 | + | |
55 | +static int | |
56 | +amd64_analyze_prologue_1 (void *data_pointer) | |
57 | { | |
58 | + struct amd64_analyze_prologue_data *data = data_pointer; | |
59 | + CORE_ADDR pc = data->pc, current_pc = data->current_pc; | |
60 | + struct amd64_frame_cache *cache = data->cache; | |
61 | static gdb_byte proto[3] = { 0x48, 0x89, 0xe5 }; /* movq %rsp, %rbp */ | |
62 | gdb_byte buf[3]; | |
63 | gdb_byte op; | |
64 | ||
65 | if (current_pc <= pc) | |
66 | - return current_pc; | |
67 | + { | |
68 | + data->retval = current_pc; | |
69 | + return 1; | |
70 | + } | |
71 | ||
72 | pc = amd64_analyze_stack_align (pc, current_pc, cache); | |
73 | ||
74 | @@ -1610,18 +1623,57 @@ amd64_analyze_prologue (CORE_ADDR pc, CO | |
75 | ||
76 | /* If that's all, return now. */ | |
77 | if (current_pc <= pc + 1) | |
78 | - return current_pc; | |
79 | + { | |
80 | + data->retval = current_pc; | |
81 | + return 1; | |
82 | + } | |
83 | ||
84 | /* Check for `movq %rsp, %rbp'. */ | |
85 | read_memory (pc + 1, buf, 3); | |
86 | if (memcmp (buf, proto, 3) != 0) | |
87 | - return pc + 1; | |
88 | + { | |
89 | + data->retval = pc + 1; | |
90 | + return 1; | |
91 | + } | |
92 | ||
93 | /* OK, we actually have a frame. */ | |
94 | cache->frameless_p = 0; | |
95 | - return pc + 4; | |
96 | + data->retval = pc + 4; | |
97 | + return 1; | |
98 | } | |
99 | ||
100 | + data->retval = pc; | |
101 | + return 1; | |
102 | +} | |
103 | + | |
104 | +/* Catch memory read errors and return just PC in such case. | |
105 | + It occurs very early on enable_break->new_symfile_objfile-> | |
106 | + ->breakpoint_re_set->decode_line_1->decode_variable_1-> | |
107 | + ->find_function_start_sal */ | |
108 | + | |
109 | +static CORE_ADDR | |
110 | +amd64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, | |
111 | + struct amd64_frame_cache *cache) | |
112 | +{ | |
113 | + int status; | |
114 | + struct amd64_analyze_prologue_data data; | |
115 | + struct ui_file *saved_gdb_stderr; | |
116 | + | |
117 | + /* Suppress error messages. */ | |
118 | + saved_gdb_stderr = gdb_stderr; | |
119 | + gdb_stderr = ui_file_new (); | |
120 | + | |
121 | + data.pc = pc; | |
122 | + data.current_pc = current_pc; | |
123 | + data.cache = cache; | |
124 | + status = catch_errors (amd64_analyze_prologue_1, &data, "", RETURN_MASK_ALL); | |
125 | + | |
126 | + /* Stop suppressing error messages. */ | |
127 | + ui_file_delete (gdb_stderr); | |
128 | + gdb_stderr = saved_gdb_stderr; | |
129 | + | |
130 | + if (status) | |
131 | + return data.retval; | |
132 | return pc; | |
133 | } | |
134 | ||
135 | Index: gdb-6.8.50.20090302/gdb/auxv.c | |
136 | =================================================================== | |
137 | --- gdb-6.8.50.20090302.orig/gdb/auxv.c 2009-03-07 00:30:06.000000000 +0100 | |
138 | +++ gdb-6.8.50.20090302/gdb/auxv.c 2009-03-07 00:30:12.000000000 +0100 | |
139 | @@ -81,7 +81,7 @@ procfs_xfer_auxv (struct target_ops *ops | |
140 | Return 1 if an entry was read into *TYPEP and *VALP. */ | |
141 | static int | |
142 | default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, | |
143 | - gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) | |
144 | + gdb_byte *endptr, ULONGEST *typep, CORE_ADDR *valp) | |
145 | { | |
146 | const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) | |
147 | / TARGET_CHAR_BIT; | |
148 | @@ -108,7 +108,7 @@ default_auxv_parse (struct target_ops *o | |
149 | Return 1 if an entry was read into *TYPEP and *VALP. */ | |
150 | int | |
151 | target_auxv_parse (struct target_ops *ops, gdb_byte **readptr, | |
152 | - gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) | |
153 | + gdb_byte *endptr, ULONGEST *typep, CORE_ADDR *valp) | |
154 | { | |
155 | struct target_ops *t; | |
156 | for (t = ops; t != NULL; t = t->beneath) | |
157 | @@ -123,9 +123,10 @@ target_auxv_parse (struct target_ops *op | |
158 | an error getting the information. On success, return 1 after | |
159 | storing the entry's value field in *VALP. */ | |
160 | int | |
161 | -target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp) | |
162 | +target_auxv_search (struct target_ops *ops, ULONGEST match, CORE_ADDR *valp) | |
163 | { | |
164 | - CORE_ADDR type, val; | |
165 | + CORE_ADDR val; | |
166 | + ULONGEST at_type; | |
167 | gdb_byte *data; | |
168 | LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data); | |
169 | gdb_byte *ptr = data; | |
170 | @@ -135,10 +136,10 @@ target_auxv_search (struct target_ops *o | |
171 | return n; | |
172 | ||
173 | while (1) | |
174 | - switch (target_auxv_parse (ops, &ptr, data + n, &type, &val)) | |
175 | + switch (target_auxv_parse (ops, &ptr, data + n, &at_type, &val)) | |
176 | { | |
177 | case 1: /* Here's an entry, check it. */ | |
178 | - if (type == match) | |
179 | + if (at_type == match) | |
180 | { | |
181 | xfree (data); | |
182 | *valp = val; | |
183 | @@ -161,7 +162,8 @@ target_auxv_search (struct target_ops *o | |
184 | int | |
185 | fprint_target_auxv (struct ui_file *file, struct target_ops *ops) | |
186 | { | |
187 | - CORE_ADDR type, val; | |
188 | + CORE_ADDR val; | |
189 | + ULONGEST at_type; | |
190 | gdb_byte *data; | |
191 | LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, | |
192 | &data); | |
193 | @@ -171,13 +173,13 @@ fprint_target_auxv (struct ui_file *file | |
194 | if (len <= 0) | |
195 | return len; | |
196 | ||
197 | - while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0) | |
198 | + while (target_auxv_parse (ops, &ptr, data + len, &at_type, &val) > 0) | |
199 | { | |
200 | const char *name = "???"; | |
201 | const char *description = ""; | |
202 | enum { dec, hex, str } flavor = hex; | |
203 | ||
204 | - switch (type) | |
205 | + switch (at_type) | |
206 | { | |
207 | #define TAG(tag, text, kind) \ | |
208 | case tag: name = #tag; description = text; flavor = kind; break | |
209 | @@ -232,7 +234,7 @@ fprint_target_auxv (struct ui_file *file | |
210 | } | |
211 | ||
212 | fprintf_filtered (file, "%-4s %-20s %-30s ", | |
213 | - plongest (type), name, description); | |
214 | + plongest (at_type), name, description); | |
215 | switch (flavor) | |
216 | { | |
217 | case dec: | |
218 | @@ -254,7 +256,7 @@ fprint_target_auxv (struct ui_file *file | |
219 | break; | |
220 | } | |
221 | ++ents; | |
222 | - if (type == AT_NULL) | |
223 | + if (at_type == AT_NULL) | |
224 | break; | |
225 | } | |
226 | ||
227 | Index: gdb-6.8.50.20090302/gdb/auxv.h | |
228 | =================================================================== | |
229 | --- gdb-6.8.50.20090302.orig/gdb/auxv.h 2009-01-03 06:57:50.000000000 +0100 | |
230 | +++ gdb-6.8.50.20090302/gdb/auxv.h 2009-03-07 00:30:12.000000000 +0100 | |
231 | @@ -36,14 +36,14 @@ struct target_ops; /* Forward declarati | |
232 | Return 1 if an entry was read into *TYPEP and *VALP. */ | |
233 | extern int target_auxv_parse (struct target_ops *ops, | |
234 | gdb_byte **readptr, gdb_byte *endptr, | |
235 | - CORE_ADDR *typep, CORE_ADDR *valp); | |
236 | + ULONGEST *typep, CORE_ADDR *valp); | |
237 | ||
238 | /* Extract the auxiliary vector entry with a_type matching MATCH. | |
239 | Return zero if no such entry was found, or -1 if there was | |
240 | an error getting the information. On success, return 1 after | |
241 | storing the entry's value field in *VALP. */ | |
242 | extern int target_auxv_search (struct target_ops *ops, | |
243 | - CORE_ADDR match, CORE_ADDR *valp); | |
244 | + ULONGEST match, CORE_ADDR *valp); | |
245 | ||
246 | /* Print the contents of the target's AUXV on the specified file. */ | |
247 | extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops); | |
248 | Index: gdb-6.8.50.20090302/gdb/breakpoint.c | |
249 | =================================================================== | |
250 | --- gdb-6.8.50.20090302.orig/gdb/breakpoint.c 2009-03-07 00:30:10.000000000 +0100 | |
251 | +++ gdb-6.8.50.20090302/gdb/breakpoint.c 2009-03-07 00:30:12.000000000 +0100 | |
252 | @@ -3920,7 +3920,8 @@ describe_other_breakpoints (CORE_ADDR pc | |
253 | printf_filtered (" (thread %d)", b->thread); | |
254 | printf_filtered ("%s%s ", | |
255 | ((b->enable_state == bp_disabled || | |
256 | - b->enable_state == bp_call_disabled) | |
257 | + b->enable_state == bp_call_disabled || | |
258 | + b->enable_state == bp_startup_disabled) | |
259 | ? " (disabled)" | |
260 | : b->enable_state == bp_permanent | |
261 | ? " (permanent)" | |
262 | @@ -5008,6 +5009,61 @@ create_catchpoint (int tempflag, char *c | |
263 | return b; | |
264 | } | |
265 | ||
266 | +void | |
267 | +disable_breakpoints_at_startup (int silent) | |
268 | +{ | |
269 | + struct breakpoint *b; | |
270 | + int disabled_startup_breaks = 0; | |
271 | + | |
272 | + if (bfd_get_start_address (exec_bfd) != entry_point_address ()) | |
273 | + { | |
274 | + ALL_BREAKPOINTS (b) | |
275 | + { | |
276 | + if (((b->type == bp_breakpoint) || | |
277 | + (b->type == bp_hardware_breakpoint)) && | |
278 | + b->enable_state == bp_enabled && | |
279 | + !b->loc->duplicate) | |
280 | + { | |
281 | + b->enable_state = bp_startup_disabled; | |
282 | + if (!silent) | |
283 | + { | |
284 | + if (!disabled_startup_breaks) | |
285 | + { | |
286 | + target_terminal_ours_for_output (); | |
287 | + warning ("Temporarily disabling breakpoints:"); | |
288 | + } | |
289 | + disabled_startup_breaks = 1; | |
290 | + warning ("breakpoint #%d addr 0x%s", b->number, paddr_nz(b->loc->address)); | |
291 | + } | |
292 | + } | |
293 | + } | |
294 | + } | |
295 | +} | |
296 | + | |
297 | +/* Try to reenable any breakpoints after startup. */ | |
298 | +void | |
299 | +re_enable_breakpoints_at_startup (void) | |
300 | +{ | |
301 | + struct breakpoint *b; | |
302 | + | |
303 | + if (bfd_get_start_address (exec_bfd) != entry_point_address ()) | |
304 | + { | |
305 | + ALL_BREAKPOINTS (b) | |
306 | + if (b->enable_state == bp_startup_disabled) | |
307 | + { | |
308 | + char buf[1]; | |
309 | + | |
310 | + /* Do not reenable the breakpoint if the shared library | |
311 | + is still not mapped in. */ | |
312 | + if (target_read_memory (b->loc->address, buf, 1) == 0) | |
313 | + { | |
314 | + /*printf ("enabling breakpoint at 0x%s\n", paddr_nz(b->loc->address));*/ | |
315 | + b->enable_state = bp_enabled; | |
316 | + } | |
317 | + } | |
318 | + } | |
319 | +} | |
320 | + | |
321 | static void | |
322 | create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, | |
323 | struct breakpoint_ops *ops) | |
324 | Index: gdb-6.8.50.20090302/gdb/breakpoint.h | |
325 | =================================================================== | |
326 | --- gdb-6.8.50.20090302.orig/gdb/breakpoint.h 2009-03-07 00:30:06.000000000 +0100 | |
327 | +++ gdb-6.8.50.20090302/gdb/breakpoint.h 2009-03-07 00:30:12.000000000 +0100 | |
328 | @@ -127,6 +127,7 @@ enum enable_state | |
329 | automatically enabled and reset when the call | |
330 | "lands" (either completes, or stops at another | |
331 | eventpoint). */ | |
332 | + bp_startup_disabled, | |
333 | bp_permanent /* There is a breakpoint instruction hard-wired into | |
334 | the target's code. Don't try to write another | |
335 | breakpoint instruction on top of it, or restore | |
336 | @@ -847,6 +848,10 @@ extern void remove_thread_event_breakpoi | |
337 | ||
338 | extern void disable_breakpoints_in_shlibs (void); | |
339 | ||
340 | +extern void disable_breakpoints_at_startup (int silent); | |
341 | + | |
342 | +extern void re_enable_breakpoints_at_startup (void); | |
343 | + | |
344 | /* This function returns TRUE if ep is a catchpoint. */ | |
345 | extern int ep_is_catchpoint (struct breakpoint *); | |
346 | ||
347 | Index: gdb-6.8.50.20090302/gdb/dwarf2read.c | |
348 | =================================================================== | |
349 | --- gdb-6.8.50.20090302.orig/gdb/dwarf2read.c 2009-03-07 00:30:10.000000000 +0100 | |
350 | +++ gdb-6.8.50.20090302/gdb/dwarf2read.c 2009-03-07 00:30:12.000000000 +0100 | |
351 | @@ -1413,7 +1413,7 @@ dwarf2_build_psymtabs (struct objfile *o | |
352 | else | |
353 | dwarf2_per_objfile->loc_buffer = NULL; | |
354 | ||
355 | - if (mainline | |
356 | + if ((mainline == 1) | |
357 | || (objfile->global_psymbols.size == 0 | |
358 | && objfile->static_psymbols.size == 0)) | |
359 | { | |
360 | Index: gdb-6.8.50.20090302/gdb/elfread.c | |
361 | =================================================================== | |
362 | --- gdb-6.8.50.20090302.orig/gdb/elfread.c 2009-03-07 00:30:06.000000000 +0100 | |
363 | +++ gdb-6.8.50.20090302/gdb/elfread.c 2009-03-07 00:30:12.000000000 +0100 | |
364 | @@ -680,7 +680,7 @@ elf_symfile_read (struct objfile *objfil | |
365 | /* If we are reinitializing, or if we have never loaded syms yet, | |
366 | set table to empty. MAINLINE is cleared so that *_read_psymtab | |
367 | functions do not all also re-initialize the psymbol table. */ | |
368 | - if (mainline) | |
369 | + if (mainline == 1) | |
370 | { | |
371 | init_psymbol_list (objfile, 0); | |
372 | mainline = 0; | |
373 | Index: gdb-6.8.50.20090302/gdb/infrun.c | |
374 | =================================================================== | |
375 | --- gdb-6.8.50.20090302.orig/gdb/infrun.c 2009-03-07 00:30:10.000000000 +0100 | |
376 | +++ gdb-6.8.50.20090302/gdb/infrun.c 2009-03-07 00:30:12.000000000 +0100 | |
377 | @@ -3354,6 +3354,11 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME ( | |
378 | #endif | |
379 | target_terminal_inferior (); | |
380 | ||
381 | + /* For PIE executables, we dont really know where the | |
382 | + breakpoints are going to be until we start up the | |
383 | + inferior. */ | |
384 | + re_enable_breakpoints_at_startup (); | |
385 | + | |
386 | /* If requested, stop when the dynamic linker notifies | |
387 | gdb of events. This allows the user to get control | |
388 | and place breakpoints in initializer routines for | |
389 | Index: gdb-6.8.50.20090302/gdb/objfiles.c | |
390 | =================================================================== | |
391 | --- gdb-6.8.50.20090302.orig/gdb/objfiles.c 2009-03-07 00:30:06.000000000 +0100 | |
392 | +++ gdb-6.8.50.20090302/gdb/objfiles.c 2009-03-07 00:30:12.000000000 +0100 | |
393 | @@ -51,6 +51,9 @@ | |
394 | #include "arch-utils.h" | |
395 | #include "exec.h" | |
396 | ||
397 | +#include "auxv.h" | |
398 | +#include "elf/common.h" | |
399 | + | |
400 | /* Prototypes for local functions */ | |
401 | ||
402 | static void objfile_alloc_data (struct objfile *objfile); | |
403 | @@ -271,7 +274,19 @@ init_entry_point_info (struct objfile *o | |
404 | CORE_ADDR | |
405 | entry_point_address (void) | |
406 | { | |
407 | - return symfile_objfile ? symfile_objfile->ei.entry_point : 0; | |
408 | + int ret; | |
409 | + CORE_ADDR entry_addr; | |
410 | + | |
411 | + /* Find the address of the entry point of the program from the | |
412 | + auxv vector. */ | |
413 | + ret = target_auxv_search (¤t_target, AT_ENTRY, &entry_addr); | |
414 | + if (ret == 1) | |
415 | + return entry_addr; | |
416 | + /*if (ret == 0 || ret == -1)*/ | |
417 | + else | |
418 | + { | |
419 | + return symfile_objfile ? symfile_objfile->ei.entry_point : 0; | |
420 | + } | |
421 | } | |
422 | ||
423 | /* Create the terminating entry of OBJFILE's minimal symbol table. | |
424 | @@ -443,6 +458,9 @@ free_objfile (struct objfile *objfile) | |
425 | if (objfile == rt_common_objfile) | |
426 | rt_common_objfile = NULL; | |
427 | ||
428 | + if (objfile == symfile_objfile) | |
429 | + symfile_objfile = NULL; | |
430 | + | |
431 | /* Before the symbol table code was redone to make it easier to | |
432 | selectively load and remove information particular to a specific | |
433 | linkage unit, gdb used to do these things whenever the monolithic | |
434 | Index: gdb-6.8.50.20090302/gdb/solib-svr4.c | |
435 | =================================================================== | |
436 | --- gdb-6.8.50.20090302.orig/gdb/solib-svr4.c 2009-03-07 00:30:09.000000000 +0100 | |
437 | +++ gdb-6.8.50.20090302/gdb/solib-svr4.c 2009-03-07 00:30:12.000000000 +0100 | |
438 | @@ -45,6 +45,7 @@ | |
439 | #include "exec.h" | |
440 | #include "auxv.h" | |
441 | #include "exceptions.h" | |
442 | +#include "command.h" | |
443 | ||
444 | static struct link_map_offsets *svr4_fetch_link_map_offsets (void); | |
445 | static int svr4_have_link_map_offsets (void); | |
446 | @@ -287,7 +288,9 @@ static CORE_ADDR main_lm_addr; | |
447 | ||
448 | /* Local function prototypes */ | |
449 | ||
450 | +#if 0 | |
451 | static int match_main (char *); | |
452 | +#endif | |
453 | ||
454 | static CORE_ADDR bfd_lookup_symbol (bfd *, char *); | |
455 | ||
456 | @@ -521,10 +524,12 @@ scan_dyntag (int dyntag, bfd *abfd, CORE | |
457 | int arch_size, step, sect_size; | |
458 | long dyn_tag; | |
459 | CORE_ADDR dyn_ptr, dyn_addr; | |
460 | + CORE_ADDR reloc_addr = 0; | |
461 | gdb_byte *bufend, *bufstart, *buf; | |
462 | Elf32_External_Dyn *x_dynp_32; | |
463 | Elf64_External_Dyn *x_dynp_64; | |
464 | struct bfd_section *sect; | |
465 | + int ret; | |
466 | ||
467 | if (abfd == NULL) | |
468 | return 0; | |
469 | @@ -532,19 +537,81 @@ scan_dyntag (int dyntag, bfd *abfd, CORE | |
470 | if (arch_size == -1) | |
471 | return 0; | |
472 | ||
473 | + /* The auxv vector based relocatable files reading is limited to the main | |
474 | + executable. */ | |
475 | + gdb_assert (abfd == exec_bfd || ptr == NULL); | |
476 | + | |
477 | + if (ptr != NULL) | |
478 | + { | |
479 | + CORE_ADDR entry_addr; | |
480 | + | |
481 | + /* Find the address of the entry point of the program from the | |
482 | + auxv vector. */ | |
483 | + ret = target_auxv_search (¤t_target, AT_ENTRY, &entry_addr); | |
484 | + | |
485 | + if (ret == 0 || ret == -1) | |
486 | + { | |
487 | + /* No auxv info, maybe an older kernel. Fake our way through. */ | |
488 | + entry_addr = bfd_get_start_address (exec_bfd); | |
489 | + | |
490 | + if (debug_solib) | |
491 | + fprintf_unfiltered (gdb_stdlog, | |
492 | + "elf_locate_base: program entry address not found. Using bfd's 0x%s for %s\n", | |
493 | + paddr_nz (entry_addr), exec_bfd->filename); | |
494 | + } | |
495 | + else | |
496 | + { | |
497 | + if (debug_solib) | |
498 | + fprintf_unfiltered (gdb_stdlog, | |
499 | + "elf_locate_base: found program entry address 0x%s for %s\n", | |
500 | + paddr_nz (entry_addr), exec_bfd->filename); | |
501 | + } | |
502 | + reloc_addr = entry_addr - bfd_get_start_address (exec_bfd); | |
503 | + if (debug_solib) | |
504 | + fprintf_unfiltered (gdb_stdlog, | |
505 | + "elf_locate_base: expected relocation offset 0x%s for %s\n", | |
506 | + paddr_nz (reloc_addr), exec_bfd->filename); | |
507 | + } | |
508 | + | |
509 | /* Find the start address of the .dynamic section. */ | |
510 | sect = bfd_get_section_by_name (abfd, ".dynamic"); | |
511 | if (sect == NULL) | |
512 | - return 0; | |
513 | + { | |
514 | + if (debug_solib) | |
515 | + fprintf_unfiltered (gdb_stdlog, | |
516 | + "elf_locate_base: .dynamic section not found in %s -- return now\n", | |
517 | + exec_bfd->filename); | |
518 | + return 0; | |
519 | + } | |
520 | + else | |
521 | + { | |
522 | + if (debug_solib) | |
523 | + fprintf_unfiltered (gdb_stdlog, | |
524 | + "elf_locate_base: .dynamic section found in %s\n", | |
525 | + exec_bfd->filename); | |
526 | + } | |
527 | + | |
528 | dyn_addr = bfd_section_vma (abfd, sect); | |
529 | + if (debug_solib) | |
530 | + fprintf_unfiltered (gdb_stdlog, | |
531 | + "elf_locate_base: .dynamic addr 0x%s\n", | |
532 | + paddr_nz (dyn_addr)); | |
533 | ||
534 | /* Read in .dynamic from the BFD. We will get the actual value | |
535 | from memory later. */ | |
536 | sect_size = bfd_section_size (abfd, sect); | |
537 | buf = bufstart = alloca (sect_size); | |
538 | + if (debug_solib) | |
539 | + fprintf_unfiltered (gdb_stdlog, | |
540 | + "elf_locate_base: read in .dynamic section\n"); | |
541 | if (!bfd_get_section_contents (abfd, sect, | |
542 | buf, 0, sect_size)) | |
543 | - return 0; | |
544 | + { | |
545 | + if (debug_solib) | |
546 | + fprintf_unfiltered (gdb_stdlog, | |
547 | + "elf_locate_base: couldn't read .dynamic section -- return now\n"); | |
548 | + return 0; | |
549 | + } | |
550 | ||
551 | /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ | |
552 | step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) | |
553 | @@ -565,26 +632,105 @@ scan_dyntag (int dyntag, bfd *abfd, CORE | |
554 | dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); | |
555 | dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr); | |
556 | } | |
557 | - if (dyn_tag == DT_NULL) | |
558 | + | |
559 | + /* Verify RELOC_ADDR makes sense - it does not have to for valgrind which | |
560 | + supplies us a specially crafted executable in /proc/PID/fd/X while | |
561 | + /proc/PID/auxv corresponds to a different executable (.../memcheck). */ | |
562 | + if (reloc_addr) | |
563 | + { | |
564 | + gdb_byte tag_buf[8]; | |
565 | + CORE_ADDR tag_addr; | |
566 | + | |
567 | + tag_addr = dyn_addr + (buf - bufstart) + reloc_addr; | |
568 | + if (target_read_memory (tag_addr, tag_buf, arch_size / 8) == 0) | |
569 | + { | |
570 | + if (memcmp (tag_buf, buf, arch_size / 8) != 0) | |
571 | + { | |
572 | + if (debug_solib) | |
573 | + fprintf_unfiltered (gdb_stdlog, | |
574 | + "elf_locate_base: tag at offset 0x%lx does not match," | |
575 | + " dropping relocation offset %s\n", | |
576 | + (unsigned long) (buf - bufstart), paddr_nz (reloc_addr)); | |
577 | + reloc_addr = 0; | |
578 | + } | |
579 | + } | |
580 | + else | |
581 | + { | |
582 | + if (debug_solib) | |
583 | + fprintf_unfiltered (gdb_stdlog, | |
584 | + "elf_locate_base: tag at offset 0x%lx is not readable," | |
585 | + " dropping relocation offset %s\n", | |
586 | + (unsigned long) (buf - bufstart), paddr_nz (reloc_addr)); | |
587 | + reloc_addr = 0; | |
588 | + } | |
589 | + } | |
590 | + | |
591 | + if (dyn_tag == DT_NULL) | |
592 | return 0; | |
593 | - if (dyn_tag == dyntag) | |
594 | - { | |
595 | - /* If requested, try to read the runtime value of this .dynamic | |
596 | - entry. */ | |
597 | - if (ptr) | |
598 | - { | |
599 | - struct type *ptr_type; | |
600 | - gdb_byte ptr_buf[8]; | |
601 | - CORE_ADDR ptr_addr; | |
602 | - | |
603 | - ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; | |
604 | - ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; | |
605 | - if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0) | |
606 | - dyn_ptr = extract_typed_address (ptr_buf, ptr_type); | |
607 | - *ptr = dyn_ptr; | |
608 | - } | |
609 | - return 1; | |
610 | - } | |
611 | + if (dyn_tag == dyntag) | |
612 | + { | |
613 | + /* If requested, try to read the runtime value of this .dynamic | |
614 | + entry. */ | |
615 | + if (ptr) | |
616 | + { | |
617 | + gdb_byte ptr_buf[8]; | |
618 | + CORE_ADDR ptr_addr; | |
619 | + int got; | |
620 | + | |
621 | + ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; | |
622 | + if (ptr != NULL) | |
623 | + { | |
624 | + if (debug_solib) | |
625 | + fprintf_unfiltered (gdb_stdlog, | |
626 | + "elf_locate_base: unrelocated ptr addr 0x%s\n", | |
627 | + paddr_nz (ptr_addr)); | |
628 | + ptr_addr += reloc_addr; | |
629 | + if (debug_solib) | |
630 | + fprintf_unfiltered (gdb_stdlog, | |
631 | + "elf_locate_base: relocated ptr addr 0x%s" | |
632 | + " (relocation offset %s) for %s\n", | |
633 | + paddr_nz (ptr_addr), paddr_nz (reloc_addr), | |
634 | + exec_bfd->filename); | |
635 | + } | |
636 | + got = target_read_memory (ptr_addr, ptr_buf, arch_size / 8); | |
637 | + if (got != 0 && reloc_addr) | |
638 | + { | |
639 | + ptr_addr -= reloc_addr; | |
640 | + if (debug_solib) | |
641 | + fprintf_unfiltered (gdb_stdlog, | |
642 | + "elf_locate_base: unrelocated back to ptr addr 0x%s" | |
643 | + " as the memory was unreable for %s\n", | |
644 | + paddr_nz (ptr_addr), exec_bfd->filename); | |
645 | + got = target_read_memory (ptr_addr, ptr_buf, arch_size / 8); | |
646 | + } | |
647 | + | |
648 | + if (got == 0) | |
649 | + { | |
650 | + struct type *ptr_type; | |
651 | + | |
652 | + ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; | |
653 | + dyn_ptr = extract_typed_address (ptr_buf, ptr_type); | |
654 | + if (ptr != NULL) | |
655 | + { | |
656 | + if (debug_solib) | |
657 | + fprintf_unfiltered (gdb_stdlog, | |
658 | + "elf_locate_base: Tag entry has value 0x%s -- return now\n", | |
659 | + paddr_nz (dyn_ptr)); | |
660 | + } | |
661 | + } | |
662 | + else | |
663 | + { | |
664 | + if (ptr != NULL) | |
665 | + { | |
666 | + if (debug_solib) | |
667 | + fprintf_unfiltered (gdb_stdlog, | |
668 | + "elf_locate_base: Couldn't read tag entry value -- return now\n"); | |
669 | + } | |
670 | + } | |
671 | + *ptr = dyn_ptr; | |
672 | + } | |
673 | + return 1; | |
674 | + } | |
675 | } | |
676 | ||
677 | return 0; | |
678 | @@ -774,6 +920,10 @@ solib_svr4_r_map (void) | |
679 | struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); | |
680 | struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; | |
681 | ||
682 | + if (debug_solib) | |
683 | + fprintf_unfiltered (gdb_stdlog, | |
684 | + "solib_svr4_r_map: read at 0x%s\n", | |
685 | + paddr_nz (debug_base + lmo->r_map_offset)); | |
686 | return read_memory_typed_address (debug_base + lmo->r_map_offset, ptr_type); | |
687 | } | |
688 | ||
689 | @@ -945,6 +1095,11 @@ svr4_current_sos (void) | |
690 | struct so_list *head = 0; | |
691 | struct so_list **link_ptr = &head; | |
692 | CORE_ADDR ldsomap = 0; | |
693 | + const char *filename = exec_bfd ? exec_bfd->filename : "<none>"; | |
694 | + | |
695 | + if (debug_solib) | |
696 | + fprintf_unfiltered (gdb_stdlog, | |
697 | + "svr4_current_sos: exec_bfd %s\n", filename); | |
698 | ||
699 | /* Always locate the debug struct, in case it has moved. */ | |
700 | debug_base = 0; | |
701 | @@ -953,10 +1108,19 @@ svr4_current_sos (void) | |
702 | /* If we can't find the dynamic linker's base structure, this | |
703 | must not be a dynamically linked executable. Hmm. */ | |
704 | if (! debug_base) | |
705 | - return svr4_default_sos (); | |
706 | + { | |
707 | + if (debug_solib) | |
708 | + fprintf_unfiltered (gdb_stdlog, | |
709 | + "svr4_current_sos: no DT_DEBUG found in %s -- return now\n", | |
710 | + filename); | |
711 | + return svr4_default_sos (); | |
712 | + } | |
713 | ||
714 | /* Walk the inferior's link map list, and build our list of | |
715 | `struct so_list' nodes. */ | |
716 | + if (debug_solib) | |
717 | + fprintf_unfiltered (gdb_stdlog, | |
718 | + "svr4_current_sos: walk link map in %s\n", filename); | |
719 | lm = solib_svr4_r_map (); | |
720 | ||
721 | while (lm) | |
722 | @@ -973,26 +1137,104 @@ svr4_current_sos (void) | |
723 | new->lm_info->lm = xzalloc (lmo->link_map_size); | |
724 | make_cleanup (xfree, new->lm_info->lm); | |
725 | ||
726 | + if (debug_solib) | |
727 | + fprintf_unfiltered (gdb_stdlog, | |
728 | + "svr4_current_sos: read lm at 0x%s\n", paddr_nz(lm)); | |
729 | read_memory (lm, new->lm_info->lm, lmo->link_map_size); | |
730 | ||
731 | lm = LM_NEXT (new); | |
732 | ||
733 | + if (debug_solib) | |
734 | + fprintf_unfiltered (gdb_stdlog, | |
735 | + "svr4_current_sos: is first link entry? %d\n", | |
736 | + IGNORE_FIRST_LINK_MAP_ENTRY (new)); | |
737 | + | |
738 | /* For SVR4 versions, the first entry in the link map is for the | |
739 | inferior executable, so we must ignore it. For some versions of | |
740 | SVR4, it has no name. For others (Solaris 2.3 for example), it | |
741 | does have a name, so we can no longer use a missing name to | |
742 | decide when to ignore it. */ | |
743 | - if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0) | |
744 | + if (exec_bfd != NULL && IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0) | |
745 | { | |
746 | - main_lm_addr = new->lm_info->lm_addr; | |
747 | - free_so (new); | |
748 | - } | |
749 | + /* It is the first link map entry, i.e. it is the main executable. */ | |
750 | + | |
751 | + if (bfd_get_start_address (exec_bfd) == entry_point_address ()) | |
752 | + { | |
753 | + /* Non-pie case, main executable has not been relocated. */ | |
754 | + main_lm_addr = new->lm_info->lm_addr; | |
755 | + free_so (new); | |
756 | + } | |
757 | + else | |
758 | + { | |
759 | + /* Pie case, main executable has been relocated. */ | |
760 | + struct so_list *gdb_solib; | |
761 | + | |
762 | + if (debug_solib) | |
763 | + fprintf_unfiltered (gdb_stdlog, | |
764 | + "svr4_current_sos: Processing first link map entry\n"); | |
765 | + strncpy (new->so_name, exec_bfd->filename, | |
766 | + SO_NAME_MAX_PATH_SIZE - 1); | |
767 | + new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; | |
768 | + strcpy (new->so_original_name, new->so_name); | |
769 | + /*new->main = 1;*/ | |
770 | + new->main_relocated = 0; | |
771 | + | |
772 | + if (debug_solib) | |
773 | + { | |
774 | + fprintf_unfiltered (gdb_stdlog, | |
775 | + "svr4_current_sos: Processing nameless DSO\n"); | |
776 | + fprintf_unfiltered (gdb_stdlog, | |
777 | + "svr4_current_sos: adding name %s\n", | |
778 | + new->so_name); | |
779 | + } | |
780 | + | |
781 | + for (gdb_solib = master_so_list (); | |
782 | + gdb_solib; | |
783 | + gdb_solib = gdb_solib->next) | |
784 | + { | |
785 | + if (debug_solib) | |
786 | + fprintf_unfiltered (gdb_stdlog, | |
787 | + "svr4_current_sos: compare gdb %s and new %s\n", | |
788 | + gdb_solib->so_name, new->so_name); | |
789 | + if (strcmp (gdb_solib->so_name, new->so_name) == 0) | |
790 | + if (gdb_solib->main_relocated) | |
791 | + { | |
792 | + if (debug_solib) | |
793 | + fprintf_unfiltered (gdb_stdlog, | |
794 | + "svr4_current_sos: found main relocated\n"); | |
795 | + break; | |
796 | + } | |
797 | + } | |
798 | + | |
799 | + if ((gdb_solib && !gdb_solib->main_relocated) || (!gdb_solib)) | |
800 | + { | |
801 | + add_to_target_sections (0 /*from_tty*/, ¤t_target, new); | |
802 | + new->main = 1; | |
803 | + } | |
804 | + | |
805 | + /* We need this in the list of shared libs we return because | |
806 | + solib_add_stub will loop through it and add the symbol file. */ | |
807 | + new->next = 0; | |
808 | + *link_ptr = new; | |
809 | + link_ptr = &new->next; | |
810 | + } | |
811 | + } /* End of IGNORE_FIRST_LINK_MAP_ENTRY */ | |
812 | else | |
813 | { | |
814 | + /* This is not the first link map entry, i.e. is not the main | |
815 | + executable. Note however that it could be the DSO supplied on | |
816 | + certain systems (i.e. Linux 2.6) containing information about | |
817 | + the vsyscall page. We must ignore such entry. This entry is | |
818 | + nameless (just like the one for the main executable, sigh). */ | |
819 | + | |
820 | int errcode; | |
821 | char *buffer; | |
822 | ||
823 | /* Extract this shared object's name. */ | |
824 | + if (debug_solib) | |
825 | + fprintf_unfiltered (gdb_stdlog, | |
826 | + "svr4_current_sos: read LM_NAME\n"); | |
827 | + | |
828 | target_read_string (LM_NAME (new), &buffer, | |
829 | SO_NAME_MAX_PATH_SIZE - 1, &errcode); | |
830 | if (errcode != 0) | |
831 | @@ -1000,47 +1242,60 @@ svr4_current_sos (void) | |
832 | safe_strerror (errcode)); | |
833 | else | |
834 | { | |
835 | - struct build_id *build_id; | |
836 | + if (debug_solib) | |
837 | + fprintf_unfiltered (gdb_stdlog, | |
838 | + "svr4_current_sos: LM_NAME is <%s>\n", | |
839 | + buffer); | |
840 | + /* The name could be empty, in which case it is the | |
841 | + system supplied DSO. */ | |
842 | + if (strcmp (buffer, "") == 0) | |
843 | + free_so (new); | |
844 | + else | |
845 | + { | |
846 | + struct build_id *build_id; | |
847 | ||
848 | - strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1); | |
849 | - new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; | |
850 | - /* May get overwritten below. */ | |
851 | - strcpy (new->so_name, new->so_original_name); | |
852 | + strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1); | |
853 | + new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; | |
854 | + /* May get overwritten below. */ | |
855 | + strcpy (new->so_name, new->so_original_name); | |
856 | ||
857 | - build_id = build_id_addr_get (LM_DYNAMIC_FROM_LINK_MAP (new)); | |
858 | - if (build_id != NULL) | |
859 | - { | |
860 | - char *name, *build_id_filename; | |
861 | + build_id = build_id_addr_get (LM_DYNAMIC_FROM_LINK_MAP (new)); | |
862 | + if (build_id != NULL) | |
863 | + { | |
864 | + char *name, *build_id_filename; | |
865 | + | |
866 | + /* Missing the build-id matching separate debug info file | |
867 | + would be handled while SO_NAME gets loaded. */ | |
868 | + name = build_id_to_filename (build_id, &build_id_filename, 0); | |
869 | + if (name != NULL) | |
870 | + { | |
871 | + strncpy (new->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); | |
872 | + new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; | |
873 | + xfree (name); | |
874 | + } | |
875 | + else | |
876 | + debug_print_missing (new->so_name, build_id_filename); | |
877 | + | |
878 | + xfree (build_id_filename); | |
879 | + xfree (build_id); | |
880 | + } | |
881 | ||
882 | - /* Missing the build-id matching separate debug info file | |
883 | - would be handled while SO_NAME gets loaded. */ | |
884 | - name = build_id_to_filename (build_id, &build_id_filename, 0); | |
885 | - if (name != NULL) | |
886 | + if (debug_solib) | |
887 | { | |
888 | - strncpy (new->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); | |
889 | - new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; | |
890 | - xfree (name); | |
891 | + fprintf_unfiltered (gdb_stdlog, | |
892 | + "svr4_current_sos: Processing DSO: %s\n", | |
893 | + new->so_name); | |
894 | + fprintf_unfiltered (gdb_stdlog, | |
895 | + "svr4_current_sos: first link entry %d\n", | |
896 | + IGNORE_FIRST_LINK_MAP_ENTRY (new)); | |
897 | } | |
898 | - else | |
899 | - debug_print_missing (new->so_name, build_id_filename); | |
900 | ||
901 | - xfree (build_id_filename); | |
902 | - xfree (build_id); | |
903 | + new->next = 0; | |
904 | + *link_ptr = new; | |
905 | + link_ptr = &new->next; | |
906 | } | |
907 | } | |
908 | - xfree (buffer); | |
909 | - | |
910 | - /* If this entry has no name, or its name matches the name | |
911 | - for the main executable, don't include it in the list. */ | |
912 | - if (! new->so_name[0] | |
913 | - || match_main (new->so_name)) | |
914 | - free_so (new); | |
915 | - else | |
916 | - { | |
917 | - new->next = 0; | |
918 | - *link_ptr = new; | |
919 | - link_ptr = &new->next; | |
920 | - } | |
921 | + xfree (buffer); | |
922 | } | |
923 | ||
924 | /* On Solaris, the dynamic linker is not in the normal list of | |
925 | @@ -1056,6 +1311,9 @@ svr4_current_sos (void) | |
926 | if (head == NULL) | |
927 | return svr4_default_sos (); | |
928 | ||
929 | + if (debug_solib) | |
930 | + fprintf_unfiltered (gdb_stdlog, "svr4_current_sos: ENDS %s\n", filename); | |
931 | + | |
932 | return head; | |
933 | } | |
934 | ||
935 | @@ -1087,7 +1345,7 @@ svr4_fetch_objfile_link_map (struct objf | |
936 | /* On some systems, the only way to recognize the link map entry for | |
937 | the main executable file is by looking at its name. Return | |
938 | non-zero iff SONAME matches one of the known main executable names. */ | |
939 | - | |
940 | +#if 0 | |
941 | static int | |
942 | match_main (char *soname) | |
943 | { | |
944 | @@ -1101,6 +1359,7 @@ match_main (char *soname) | |
945 | ||
946 | return (0); | |
947 | } | |
948 | +#endif | |
949 | ||
950 | /* Return 1 if PC lies in the dynamic symbol resolution code of the | |
951 | SVR4 run time loader. */ | |
952 | @@ -1251,15 +1510,29 @@ enable_break (void) | |
953 | /* Find the program interpreter; if not found, warn the user and drop | |
954 | into the old breakpoint at symbol code. */ | |
955 | interp_name = find_program_interpreter (); | |
956 | + | |
957 | + if (debug_solib) | |
958 | + fprintf_unfiltered (gdb_stdlog, | |
959 | + "enable_break: search for .interp in %s\n", | |
960 | + exec_bfd->filename); | |
961 | if (interp_name) | |
962 | { | |
963 | CORE_ADDR load_addr = 0; | |
964 | + CORE_ADDR load_addr_mask = -1L; | |
965 | int load_addr_found = 0; | |
966 | int loader_found_in_list = 0; | |
967 | struct so_list *so; | |
968 | bfd *tmp_bfd = NULL; | |
969 | struct target_ops *tmp_bfd_target; | |
970 | volatile struct gdb_exception ex; | |
971 | + int arch_size; | |
972 | + | |
973 | + /* For 32bit inferiors with 64bit GDB we may get LOAD_ADDR at 0xff...... | |
974 | + and thus overflowing its addition to the address while CORE_ADDR is | |
975 | + 64bit producing 0x1........ address invalid across GDB. */ | |
976 | + arch_size = bfd_get_arch_size (exec_bfd); | |
977 | + if (arch_size > 0 && arch_size < sizeof (1UL) * 8) | |
978 | + load_addr_mask = (1UL << arch_size) - 1; | |
979 | ||
980 | sym_addr = 0; | |
981 | ||
982 | @@ -1276,6 +1549,9 @@ enable_break (void) | |
983 | { | |
984 | tmp_bfd = solib_bfd_open (interp_name); | |
985 | } | |
986 | + if (debug_solib) | |
987 | + fprintf_unfiltered (gdb_stdlog, | |
988 | + "enable_break: opening %s\n", interp_name); | |
989 | if (tmp_bfd == NULL) | |
990 | goto bkpt_at_symbol; | |
991 | ||
992 | @@ -1329,16 +1605,16 @@ enable_break (void) | |
993 | interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); | |
994 | if (interp_sect) | |
995 | { | |
996 | - interp_text_sect_low = | |
997 | - bfd_section_vma (tmp_bfd, interp_sect) + load_addr; | |
998 | + interp_text_sect_low = (bfd_section_vma (tmp_bfd, interp_sect) | |
999 | + + load_addr) & load_addr_mask; | |
1000 | interp_text_sect_high = | |
1001 | interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); | |
1002 | } | |
1003 | interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); | |
1004 | if (interp_sect) | |
1005 | { | |
1006 | - interp_plt_sect_low = | |
1007 | - bfd_section_vma (tmp_bfd, interp_sect) + load_addr; | |
1008 | + interp_plt_sect_low = (bfd_section_vma (tmp_bfd, interp_sect) | |
1009 | + + load_addr) & load_addr_mask; | |
1010 | interp_plt_sect_high = | |
1011 | interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); | |
1012 | } | |
1013 | @@ -1373,7 +1649,11 @@ enable_break (void) | |
1014 | ||
1015 | if (sym_addr != 0) | |
1016 | { | |
1017 | - create_solib_event_breakpoint (load_addr + sym_addr); | |
1018 | + create_solib_event_breakpoint ((load_addr + sym_addr) | |
1019 | + & load_addr_mask); | |
1020 | + if (debug_solib) | |
1021 | + fprintf_unfiltered (gdb_stdlog, | |
1022 | + "enable_break: solib bp set\n"); | |
1023 | xfree (interp_name); | |
1024 | return 1; | |
1025 | } | |
1026 | @@ -1639,6 +1919,8 @@ svr4_solib_create_inferior_hook (void) | |
1027 | while (tp->stop_signal != TARGET_SIGNAL_TRAP); | |
1028 | inf->stop_soon = NO_STOP_QUIETLY; | |
1029 | #endif /* defined(_SCO_DS) */ | |
1030 | + | |
1031 | + disable_breakpoints_at_startup (1); | |
1032 | } | |
1033 | ||
1034 | static void | |
1035 | @@ -1820,6 +2102,75 @@ svr4_lp64_fetch_link_map_offsets (void) | |
1036 | ||
1037 | return lmp; | |
1038 | } | |
1039 | +void | |
1040 | +info_linkmap_command (char *cmd, int from_tty) | |
1041 | +{ | |
1042 | + CORE_ADDR lm; | |
1043 | + | |
1044 | + /* Make sure we've looked up the inferior's dynamic linker's base | |
1045 | + structure. */ | |
1046 | + if (! debug_base) | |
1047 | + { | |
1048 | + debug_base = locate_base (); | |
1049 | + | |
1050 | + /* If we can't find the dynamic linker's base structure, this | |
1051 | + must not be a dynamically linked executable. Hmm. */ | |
1052 | + if (! debug_base) | |
1053 | + { | |
1054 | + if (debug_solib) | |
1055 | + fprintf_unfiltered (gdb_stdlog, | |
1056 | + "svr4_print_linkmap: no DT_DEBUG found in %s -- return now\n", | |
1057 | + exec_bfd->filename); | |
1058 | + return; | |
1059 | + } | |
1060 | + } | |
1061 | + | |
1062 | + /* Walk the inferior's link map list, and print the info. */ | |
1063 | + | |
1064 | + lm = solib_svr4_r_map (); | |
1065 | + while (lm) | |
1066 | + { | |
1067 | + int errcode; | |
1068 | + char *buffer; | |
1069 | + CORE_ADDR load_addr; | |
1070 | + | |
1071 | + struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); | |
1072 | + struct so_list *new | |
1073 | + = (struct so_list *) xmalloc (sizeof (struct so_list)); | |
1074 | + struct cleanup *old_chain = make_cleanup (xfree, new); | |
1075 | + | |
1076 | + memset (new, 0, sizeof (*new)); | |
1077 | + | |
1078 | + new->lm_info = xmalloc (sizeof (struct lm_info)); | |
1079 | + make_cleanup (xfree, new->lm_info); | |
1080 | + | |
1081 | + new->lm_info->lm = xmalloc (lmo->link_map_size); | |
1082 | + make_cleanup (xfree, new->lm_info->lm); | |
1083 | + memset (new->lm_info->lm, 0, lmo->link_map_size); | |
1084 | + | |
1085 | + if (debug_solib) | |
1086 | + fprintf_unfiltered (gdb_stdlog, | |
1087 | + "svr4_print_linkmap: read lm at 0x%s\n", paddr_nz(lm)); | |
1088 | + read_memory (lm, new->lm_info->lm, lmo->link_map_size); | |
1089 | + | |
1090 | + lm = LM_NEXT (new); | |
1091 | + | |
1092 | + /* Load address. */ | |
1093 | + load_addr = LM_ADDR_CHECK (new, NULL); | |
1094 | + /* Shared object's name. */ | |
1095 | + target_read_string (LM_NAME (new), &buffer, | |
1096 | + SO_NAME_MAX_PATH_SIZE - 1, &errcode); | |
1097 | + make_cleanup (xfree, buffer); | |
1098 | + if (errcode != 0) | |
1099 | + { | |
1100 | + warning ("svr4_print_linkmap: Can't read pathname for load map: %s\n", | |
1101 | + safe_strerror (errcode)); | |
1102 | + } | |
1103 | + fprintf_filtered (gdb_stdout, "%-8s %-30s\n", paddr(load_addr), buffer); | |
1104 | + do_cleanups (old_chain); | |
1105 | + } | |
1106 | +} | |
1107 | + | |
1108 | \f | |
1109 | ||
1110 | struct target_so_ops svr4_so_ops; | |
1111 | @@ -1859,4 +2210,7 @@ _initialize_svr4_solib (void) | |
1112 | svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code; | |
1113 | svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol; | |
1114 | svr4_so_ops.same = svr4_same; | |
1115 | + | |
1116 | + add_info ("linkmap", info_linkmap_command, | |
1117 | + "Display the inferior's linkmap."); | |
1118 | } | |
1119 | Index: gdb-6.8.50.20090302/gdb/solib.c | |
1120 | =================================================================== | |
1121 | --- gdb-6.8.50.20090302.orig/gdb/solib.c 2009-02-21 17:14:49.000000000 +0100 | |
1122 | +++ gdb-6.8.50.20090302/gdb/solib.c 2009-03-07 00:30:12.000000000 +0100 | |
1123 | @@ -81,6 +81,8 @@ set_solib_ops (struct gdbarch *gdbarch, | |
1124 | ||
1125 | /* external data declarations */ | |
1126 | ||
1127 | +int debug_solib; | |
1128 | + | |
1129 | /* FIXME: gdbarch needs to control this variable, or else every | |
1130 | configuration needs to call set_solib_ops. */ | |
1131 | struct target_so_ops *current_target_so_ops; | |
1132 | @@ -104,6 +106,8 @@ The search path for loading non-absolute | |
1133 | value); | |
1134 | } | |
1135 | ||
1136 | +void add_to_target_sections (int, struct target_ops *, struct so_list *); | |
1137 | + | |
1138 | /* | |
1139 | ||
1140 | GLOBAL FUNCTION | |
1141 | @@ -426,10 +430,23 @@ free_so (struct so_list *so) | |
1142 | ||
1143 | if (so->abfd) | |
1144 | { | |
1145 | - bfd_filename = bfd_get_filename (so->abfd); | |
1146 | - if (! bfd_close (so->abfd)) | |
1147 | - warning (_("cannot close \"%s\": %s"), | |
1148 | - bfd_filename, bfd_errmsg (bfd_get_error ())); | |
1149 | + struct objfile *objfile; | |
1150 | + | |
1151 | + ALL_OBJFILES (objfile) | |
1152 | + if (objfile->obfd == so->abfd) | |
1153 | + { | |
1154 | + gdb_assert (objfile->flags & OBJF_KEEPBFD); | |
1155 | + objfile->flags &= ~OBJF_KEEPBFD; | |
1156 | + break; | |
1157 | + } | |
1158 | + | |
1159 | + if (!objfile) | |
1160 | + { | |
1161 | + bfd_filename = bfd_get_filename (so->abfd); | |
1162 | + if (! bfd_close (so->abfd)) | |
1163 | + warning (_("cannot close \"%s\": %s"), | |
1164 | + bfd_filename, bfd_errmsg (bfd_get_error ())); | |
1165 | + } | |
1166 | } | |
1167 | ||
1168 | if (bfd_filename) | |
1169 | @@ -460,15 +477,40 @@ symbol_add_stub (void *arg) | |
1170 | /* Have we already loaded this shared object? */ | |
1171 | ALL_OBJFILES (so->objfile) | |
1172 | { | |
1173 | - if (strcmp (so->objfile->name, so->so_name) == 0) | |
1174 | + /* Found an already loaded shared library. */ | |
1175 | + if (strcmp (so->objfile->name, so->so_name) == 0 | |
1176 | + && !so->main) | |
1177 | + return 1; | |
1178 | + /* Found an already loaded main executable. This could happen in | |
1179 | + two circumstances. | |
1180 | + First case: the main file has already been read in | |
1181 | + as the first thing that gdb does at startup, and the file | |
1182 | + hasn't been relocated properly yet. Therefor we need to read | |
1183 | + it in with the proper section info. | |
1184 | + Second case: it has been read in with the correct relocation, | |
1185 | + and therefore we need to skip it. */ | |
1186 | + if (strcmp (so->objfile->name, so->so_name) == 0 | |
1187 | + && so->main | |
1188 | + && so->main_relocated) | |
1189 | return 1; | |
1190 | } | |
1191 | ||
1192 | sap = build_section_addr_info_from_section_table (so->sections, | |
1193 | so->sections_end); | |
1194 | ||
1195 | - so->objfile = symbol_file_add_from_bfd (so->abfd, so->from_tty, | |
1196 | - sap, 0, OBJF_SHARED | OBJF_KEEPBFD); | |
1197 | + if (so->main) | |
1198 | + { | |
1199 | + if (debug_solib) | |
1200 | + fprintf_unfiltered (gdb_stdlog, | |
1201 | + "symbol_add_stub: adding symbols for main\n"); | |
1202 | + so->objfile = symbol_file_add_from_bfd (so->abfd, /*so->from_tty*/ 0, | |
1203 | + sap, 1, OBJF_KEEPBFD); | |
1204 | + so->main_relocated = 1; | |
1205 | + } | |
1206 | + else | |
1207 | + so->objfile = symbol_file_add_from_bfd (so->abfd, so->from_tty, | |
1208 | + sap, 0, OBJF_SHARED | OBJF_KEEPBFD); | |
1209 | + | |
1210 | free_section_addr_info (sap); | |
1211 | ||
1212 | return (1); | |
1213 | @@ -600,6 +642,10 @@ update_solib_list (int from_tty, struct | |
1214 | } | |
1215 | else | |
1216 | { | |
1217 | + if (debug_solib) | |
1218 | + fprintf_unfiltered (gdb_stdlog, | |
1219 | + "update_solib_list: compare gdb:%s and inferior:%s\n", | |
1220 | + gdb->so_original_name, i->so_original_name); | |
1221 | if (! strcmp (gdb->so_original_name, i->so_original_name)) | |
1222 | break; | |
1223 | } | |
1224 | @@ -654,28 +700,7 @@ update_solib_list (int from_tty, struct | |
1225 | /* Fill in the rest of each of the `struct so_list' nodes. */ | |
1226 | for (i = inferior; i; i = i->next) | |
1227 | { | |
1228 | - i->from_tty = from_tty; | |
1229 | - | |
1230 | - /* Fill in the rest of the `struct so_list' node. */ | |
1231 | - catch_errors (solib_map_sections, i, | |
1232 | - "Error while mapping shared library sections:\n", | |
1233 | - RETURN_MASK_ALL); | |
1234 | - | |
1235 | - /* If requested, add the shared object's sections to the TARGET's | |
1236 | - section table. Do this immediately after mapping the object so | |
1237 | - that later nodes in the list can query this object, as is needed | |
1238 | - in solib-osf.c. */ | |
1239 | - if (target) | |
1240 | - { | |
1241 | - int count = (i->sections_end - i->sections); | |
1242 | - if (count > 0) | |
1243 | - { | |
1244 | - int space = target_resize_to_sections (target, count); | |
1245 | - memcpy (target->to_sections + space, | |
1246 | - i->sections, | |
1247 | - count * sizeof (i->sections[0])); | |
1248 | - } | |
1249 | - } | |
1250 | + add_to_target_sections (from_tty, target, i); | |
1251 | ||
1252 | /* Notify any observer that the shared object has been | |
1253 | loaded now that we've added it to GDB's tables. */ | |
1254 | @@ -771,6 +796,41 @@ solib_add (char *pattern, int from_tty, | |
1255 | } | |
1256 | } | |
1257 | ||
1258 | +void | |
1259 | +add_to_target_sections (int from_tty, struct target_ops *target, struct so_list *solib) | |
1260 | +{ | |
1261 | + /* If this is set, then the sections have been already added to the | |
1262 | + target list. */ | |
1263 | + if (solib->main) | |
1264 | + return; | |
1265 | + | |
1266 | + solib->from_tty = from_tty; | |
1267 | + | |
1268 | + /* Fill in the rest of the `struct so_list' node. */ | |
1269 | + catch_errors (solib_map_sections, solib, | |
1270 | + "Error while mapping shared library sections:\n", | |
1271 | + RETURN_MASK_ALL); | |
1272 | + | |
1273 | + /* If requested, add the shared object's sections to the TARGET's | |
1274 | + section table. Do this immediately after mapping the object so | |
1275 | + that later nodes in the list can query this object, as is needed | |
1276 | + in solib-osf.c. */ | |
1277 | + if (target) | |
1278 | + { | |
1279 | + int count = (solib->sections_end - solib->sections); | |
1280 | + if (count > 0) | |
1281 | + { | |
1282 | + int space = target_resize_to_sections (target, count); | |
1283 | + if (debug_solib) | |
1284 | + fprintf_unfiltered (gdb_stdlog, | |
1285 | + "add_to_target_sections: add %s to to_sections\n", | |
1286 | + solib->so_original_name); | |
1287 | + memcpy (target->to_sections + space, | |
1288 | + solib->sections, | |
1289 | + count * sizeof (solib->sections[0])); | |
1290 | + } | |
1291 | + } | |
1292 | +} | |
1293 | ||
1294 | /* | |
1295 | ||
1296 | @@ -1089,4 +1149,12 @@ This takes precedence over the environme | |
1297 | reload_shared_libraries, | |
1298 | show_solib_search_path, | |
1299 | &setlist, &showlist); | |
1300 | + | |
1301 | + add_setshow_boolean_cmd ("solib", no_class, &debug_solib, | |
1302 | + _("\ | |
1303 | +Set debugging of GNU/Linux shlib module.\n"), _("\ | |
1304 | +Show debugging status of GNU/Linux shlib module.\n"), _("\ | |
1305 | +Enables printf debugging output of GNU/Linux shlib module.\n"), | |
1306 | + NULL, NULL, | |
1307 | + &setdebuglist, &showdebuglist); | |
1308 | } | |
1309 | Index: gdb-6.8.50.20090302/gdb/solist.h | |
1310 | =================================================================== | |
1311 | --- gdb-6.8.50.20090302.orig/gdb/solist.h 2009-02-04 09:42:11.000000000 +0100 | |
1312 | +++ gdb-6.8.50.20090302/gdb/solist.h 2009-03-07 00:30:12.000000000 +0100 | |
1313 | @@ -61,6 +61,8 @@ struct so_list | |
1314 | bfd *abfd; | |
1315 | char symbols_loaded; /* flag: symbols read in yet? */ | |
1316 | char from_tty; /* flag: print msgs? */ | |
1317 | + char main; /* flag: is this the main executable? */ | |
1318 | + char main_relocated; /* flag: has it been relocated yet? */ | |
1319 | struct objfile *objfile; /* objfile for loaded lib */ | |
1320 | struct section_table *sections; | |
1321 | struct section_table *sections_end; | |
1322 | @@ -149,4 +151,10 @@ struct symbol *solib_global_lookup (cons | |
1323 | const char *linkage_name, | |
1324 | const domain_enum domain); | |
1325 | ||
1326 | +/* Add the list of sections in so_list to the target to_sections. */ | |
1327 | +extern void add_to_target_sections (int, struct target_ops *, struct so_list *); | |
1328 | + | |
1329 | +/* Controls the printing of debugging output. */ | |
1330 | +extern int debug_solib; | |
1331 | + | |
1332 | #endif | |
1333 | Index: gdb-6.8.50.20090302/gdb/symfile-mem.c | |
1334 | =================================================================== | |
1335 | --- gdb-6.8.50.20090302.orig/gdb/symfile-mem.c 2009-03-07 00:30:08.000000000 +0100 | |
1336 | +++ gdb-6.8.50.20090302/gdb/symfile-mem.c 2009-03-07 00:30:12.000000000 +0100 | |
1337 | @@ -116,7 +116,7 @@ symbol_file_add_from_memory (struct bfd | |
1338 | } | |
1339 | ||
1340 | objf = symbol_file_add_from_bfd (nbfd, from_tty, | |
1341 | - sai, 0, OBJF_SHARED); | |
1342 | + sai, 2, OBJF_SHARED); | |
1343 | ||
1344 | /* This might change our ideas about frames already looked at. */ | |
1345 | reinit_frame_cache (); | |
1346 | Index: gdb-6.8.50.20090302/gdb/symfile.c | |
1347 | =================================================================== | |
1348 | --- gdb-6.8.50.20090302.orig/gdb/symfile.c 2009-03-07 00:30:09.000000000 +0100 | |
1349 | +++ gdb-6.8.50.20090302/gdb/symfile.c 2009-03-07 00:31:24.000000000 +0100 | |
1350 | @@ -47,6 +47,7 @@ | |
1351 | #include "readline/readline.h" | |
1352 | #include "gdb_assert.h" | |
1353 | #include "block.h" | |
1354 | +#include "varobj.h" | |
1355 | #include "observer.h" | |
1356 | #include "exec.h" | |
1357 | #include "parser-defs.h" | |
1358 | @@ -787,7 +788,7 @@ syms_from_objfile (struct objfile *objfi | |
1359 | ||
1360 | /* Now either addrs or offsets is non-zero. */ | |
1361 | ||
1362 | - if (mainline) | |
1363 | + if (mainline == 1) | |
1364 | { | |
1365 | /* We will modify the main symbol table, make sure that all its users | |
1366 | will be cleaned up if an error occurs during symbol reading. */ | |
1367 | @@ -815,7 +816,7 @@ syms_from_objfile (struct objfile *objfi | |
1368 | ||
1369 | We no longer warn if the lowest section is not a text segment (as | |
1370 | happens for the PA64 port. */ | |
1371 | - if (!mainline && addrs && addrs->other[0].name) | |
1372 | + if (/*!mainline &&*/ addrs && addrs->other[0].name) | |
1373 | { | |
1374 | asection *lower_sect; | |
1375 | asection *sect; | |
1376 | @@ -917,17 +918,21 @@ new_symfile_objfile (struct objfile *obj | |
1377 | /* If this is the main symbol file we have to clean up all users of the | |
1378 | old main symbol file. Otherwise it is sufficient to fixup all the | |
1379 | breakpoints that may have been redefined by this symbol file. */ | |
1380 | - if (mainline) | |
1381 | + if (mainline == 1) | |
1382 | { | |
1383 | /* OK, make it the "real" symbol file. */ | |
1384 | symfile_objfile = objfile; | |
1385 | ||
1386 | clear_symtab_users (); | |
1387 | } | |
1388 | - else | |
1389 | + else if (mainline == 0) | |
1390 | { | |
1391 | breakpoint_re_set (); | |
1392 | } | |
1393 | + else | |
1394 | + { | |
1395 | + /* Don't reset breakpoints or it will screw up PIE. */ | |
1396 | + } | |
1397 | ||
1398 | /* We're done reading the symbol file; finish off complaints. */ | |
1399 | clear_complaints (&symfile_complaints, 0, verbo); | |
1400 | @@ -980,7 +985,7 @@ symbol_file_add_with_addrs_or_offsets (b | |
1401 | /* Give user a chance to burp if we'd be | |
1402 | interactively wiping out any existing symbols. */ | |
1403 | ||
1404 | - if (mainline | |
1405 | + if (mainline == 1 | |
1406 | && from_tty | |
1407 | && (have_full_symbols () || have_partial_symbols ()) | |
1408 | && !query (_("Load new symbol table from \"%s\"? "), name)) | |
1409 | @@ -1175,6 +1180,10 @@ symbol_file_clear (int from_tty) | |
1410 | symfile_objfile->name) | |
1411 | : !query (_("Discard symbol table? ")))) | |
1412 | error (_("Not confirmed.")); | |
1413 | +#ifdef CLEAR_SOLIB | |
1414 | + CLEAR_SOLIB (); | |
1415 | +#endif | |
1416 | + | |
1417 | free_all_objfiles (); | |
1418 | ||
1419 | /* solib descriptors may have handles to objfiles. Since their | |
1420 | @@ -3275,6 +3284,8 @@ reread_symbols (void) | |
1421 | /* Discard cleanups as symbol reading was successful. */ | |
1422 | discard_cleanups (old_cleanups); | |
1423 | ||
1424 | + init_entry_point_info (objfile); | |
1425 | + | |
1426 | /* If the mtime has changed between the time we set new_modtime | |
1427 | and now, we *want* this to be out of date, so don't call stat | |
1428 | again now. */ | |
1429 | Index: gdb-6.8.50.20090302/gdb/target.h | |
1430 | =================================================================== | |
1431 | --- gdb-6.8.50.20090302.orig/gdb/target.h 2009-03-07 00:30:09.000000000 +0100 | |
1432 | +++ gdb-6.8.50.20090302/gdb/target.h 2009-03-07 00:30:12.000000000 +0100 | |
1433 | @@ -542,7 +542,7 @@ struct target_ops | |
1434 | Return -1 if there is insufficient buffer for a whole entry. | |
1435 | Return 1 if an entry was read into *TYPEP and *VALP. */ | |
1436 | int (*to_auxv_parse) (struct target_ops *ops, gdb_byte **readptr, | |
1437 | - gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp); | |
1438 | + gdb_byte *endptr, ULONGEST *typep, CORE_ADDR *valp); | |
1439 | ||
1440 | /* Search SEARCH_SPACE_LEN bytes beginning at START_ADDR for the | |
1441 | sequence of bytes in PATTERN with length PATTERN_LEN. |