diff --git a/gdb-dlopen-stap-probe-1of7.patch b/gdb-dlopen-stap-probe-1of7.patch new file mode 100644 index 0000000..cb74802 --- /dev/null +++ b/gdb-dlopen-stap-probe-1of7.patch @@ -0,0 +1,119 @@ +http://sourceware.org/ml/gdb-patches/2013-05/msg00625.html +Subject: [RFA 1/7] Probes API convenience patch + + +--uuKVzAmB+c+zQlhu +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This patch exposes part of the probes API in a more convenient +way. I've included it for completeness, but it has previously +been approved: + + http://www.cygwin.com/ml/gdb-patches/2012-07/msg00340.html + +--uuKVzAmB+c+zQlhu +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-1-convenience.patch" + +2013-05-16 Gary Benson + + * probe.h (get_probe_argument_count): New declaration. + (evaluate_probe_argument): Likewise. + * probe.c (get_probe_argument_count): New function. + (evaluate_probe_argument): Likewise. + (probe_safe_evaluate_at_pc): Use the above new functions. + +diff --git a/gdb/probe.h b/gdb/probe.h +index 8d44ca2..1d29b87 100644 +--- a/gdb/probe.h ++++ b/gdb/probe.h +@@ -214,6 +214,16 @@ extern void info_probes_for_ops (char *arg, int from_tty, + + extern struct cmd_list_element **info_probes_cmdlist_get (void); + ++/* Return the argument count of the specified probe. */ ++ ++extern unsigned get_probe_argument_count (struct probe *probe); ++ ++/* Evaluate argument N of the specified probe. N must be between 0 ++ inclusive and get_probe_argument_count exclusive. */ ++ ++extern struct value *evaluate_probe_argument (struct probe *probe, ++ unsigned n); ++ + /* A convenience function that finds a probe at the PC in FRAME and + evaluates argument N, with 0 <= N < number_of_args. If there is no + probe at that location, or if the probe does not have enough arguments, +diff --git a/gdb/probe.c b/gdb/probe.c +index 77f3b13..a61f4ea 100644 +--- a/gdb/probe.c ++++ b/gdb/probe.c +@@ -608,28 +608,55 @@ info_probes_command (char *arg, int from_tty) + + /* See comments in probe.h. */ + ++unsigned ++get_probe_argument_count (struct probe *probe) ++{ ++ const struct sym_probe_fns *probe_fns; ++ ++ gdb_assert (probe->objfile != NULL); ++ gdb_assert (probe->objfile->sf != NULL); ++ ++ probe_fns = probe->objfile->sf->sym_probe_fns; ++ ++ gdb_assert (probe_fns != NULL); ++ ++ return probe_fns->sym_get_probe_argument_count (probe); ++} ++ ++/* See comments in probe.h. */ ++ ++struct value * ++evaluate_probe_argument (struct probe *probe, unsigned n) ++{ ++ const struct sym_probe_fns *probe_fns; ++ ++ gdb_assert (probe->objfile != NULL); ++ gdb_assert (probe->objfile->sf != NULL); ++ ++ probe_fns = probe->objfile->sf->sym_probe_fns; ++ ++ gdb_assert (probe_fns != NULL); ++ ++ return probe_fns->sym_evaluate_probe_argument (probe, n); ++} ++ ++/* See comments in probe.h. */ ++ + struct value * + probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n) + { + struct probe *probe; +- const struct sym_probe_fns *probe_fns; + unsigned n_args; + + probe = find_probe_by_pc (get_frame_pc (frame)); + if (!probe) + return NULL; + +- gdb_assert (probe->objfile != NULL); +- gdb_assert (probe->objfile->sf != NULL); +- gdb_assert (probe->objfile->sf->sym_probe_fns != NULL); +- +- probe_fns = probe->objfile->sf->sym_probe_fns; +- n_args = probe_fns->sym_get_probe_argument_count (probe); +- ++ n_args = get_probe_argument_count (probe); + if (n >= n_args) + return NULL; + +- return probe_fns->sym_evaluate_probe_argument (probe, n); ++ return evaluate_probe_argument (probe, n); + } + + /* See comment in probe.h. */ + +--uuKVzAmB+c+zQlhu-- + diff --git a/gdb-dlopen-stap-probe-2of7.patch b/gdb-dlopen-stap-probe-2of7.patch new file mode 100644 index 0000000..3606cec --- /dev/null +++ b/gdb-dlopen-stap-probe-2of7.patch @@ -0,0 +1,198 @@ +http://sourceware.org/ml/gdb-patches/2013-05/msg00627.html +Subject: [RFA 2/7] API for inhibiting section map updates + + +--bPg9NdpM9EETxvqt +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This patch adds a couple of functions to allow section map updates +to be temporarily inhibited. Without this ability, the calls to +evaluate_probe_argument in svr4_handle_solib_event trigger a section +map update every time a group of shared objects are mapped, which +significantly affects performance. The updates are unnecessary in +this case as the sections in question are in the runtime linker and +so already in the section map. + +--bPg9NdpM9EETxvqt +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-2-inhibit-sm-updates.patch" + +2013-05-16 Gary Benson + + * objfiles.h (inhibit_section_map_updates): New function + declaration. + (resume_section_map_updates): Likewise. + (resume_section_map_updates_cleanup): Likewise. + * objfiles.c (objfile_pspace_info): Removed field + "objfiles_changed_p". New fields "new_objfiles_available", + "section_map_dirty" and "inhibit_updates". + (allocate_objfile): Set new_objfiles_available. + (free_objfile): Set section_map_dirty. + (objfile_relocate1): Likewise. + (in_plt_section): Likewise. + (find_pc_section): Update the conditions under which the + section map will be updated. + (inhibit_section_map_updates): New function. + (resume_section_map_updates): Likewise. + (resume_section_map_updates_cleanup): Likewise. + +diff --git a/gdb/objfiles.h b/gdb/objfiles.h +index 93149e2..0b7eea9 100644 +--- a/gdb/objfiles.h ++++ b/gdb/objfiles.h +@@ -501,6 +501,22 @@ extern int in_plt_section (CORE_ADDR, char *); + modules. */ + DECLARE_REGISTRY(objfile); + ++/* In normal use, the section map will be rebuilt by FIND_PC_SECTION ++ if objfiles have been added, removed or relocated since it was last ++ called. Calling INHIBIT_SECTION_MAP_UPDATES will inhibit this ++ behavior until RESUME_SECTION_MAP_UPDATES is called. If you call ++ INHIBIT_SECTION_MAP_UPDATES you must ensure that every call to ++ FIND_PC_SECTION in the inhibited region relates to a section that ++ is already in the section map and has not since been removed or ++ relocated. */ ++extern void inhibit_section_map_updates (void); ++ ++/* Resume automatically rebuilding the section map as required. */ ++extern void resume_section_map_updates (void); ++ ++/* Version of the above suitable for use as a cleanup. */ ++extern void resume_section_map_updates_cleanup (void *arg); ++ + extern void default_iterate_over_objfiles_in_search_order + (struct gdbarch *gdbarch, + iterate_over_objfiles_in_search_order_cb_ftype *cb, +diff --git a/gdb/objfiles.c b/gdb/objfiles.c +index 3e49ea2..3af1064 100644 +--- a/gdb/objfiles.c ++++ b/gdb/objfiles.c +@@ -67,9 +67,18 @@ struct objfile *rt_common_objfile; /* For runtime common symbols */ + + struct objfile_pspace_info + { +- int objfiles_changed_p; + struct obj_section **sections; + int num_sections; ++ ++ /* Nonzero if object files have been added since the section map ++ was last updated. */ ++ int new_objfiles_available; ++ ++ /* Nonzero if the section map MUST be updated before use. */ ++ int section_map_dirty; ++ ++ /* Nonzero if section map updates should be inhibited if possible. */ ++ int inhibit_updates; + }; + + /* Per-program-space data key. */ +@@ -317,7 +326,7 @@ allocate_objfile (bfd *abfd, int flags) + objfile->flags |= flags; + + /* Rebuild section map next time we need it. */ +- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1; ++ get_objfile_pspace_data (objfile->pspace)->new_objfiles_available = 1; + + return objfile; + } +@@ -646,7 +655,7 @@ free_objfile (struct objfile *objfile) + obstack_free (&objfile->objfile_obstack, 0); + + /* Rebuild section map next time we need it. */ +- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1; ++ get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1; + + xfree (objfile); + } +@@ -826,7 +835,7 @@ objfile_relocate1 (struct objfile *objfile, + } + + /* Rebuild section map next time we need it. */ +- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1; ++ get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1; + + /* Update the table in exec_ops, used to read memory. */ + ALL_OBJFILE_OSECTIONS (objfile, s) +@@ -1291,11 +1300,14 @@ static void + update_section_map (struct program_space *pspace, + struct obj_section ***pmap, int *pmap_size) + { ++ struct objfile_pspace_info *pspace_info; + int alloc_size, map_size, i; + struct obj_section *s, **map; + struct objfile *objfile; + +- gdb_assert (get_objfile_pspace_data (pspace)->objfiles_changed_p != 0); ++ pspace_info = get_objfile_pspace_data (current_program_space); ++ gdb_assert (pspace_info->section_map_dirty != 0 ++ || pspace_info->new_objfiles_available != 0); + + map = *pmap; + xfree (map); +@@ -1365,7 +1377,9 @@ find_pc_section (CORE_ADDR pc) + return s; + + pspace_info = get_objfile_pspace_data (current_program_space); +- if (pspace_info->objfiles_changed_p != 0) ++ if (pspace_info->section_map_dirty ++ || (pspace_info->new_objfiles_available ++ && !pspace_info->inhibit_updates)) + { + update_section_map (current_program_space, + &pspace_info->sections, +@@ -1373,7 +1387,8 @@ find_pc_section (CORE_ADDR pc) + + /* Don't need updates to section map until objfiles are added, + removed or relocated. */ +- pspace_info->objfiles_changed_p = 0; ++ pspace_info->new_objfiles_available = 0; ++ pspace_info->section_map_dirty = 0; + } + + /* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to +@@ -1414,14 +1429,38 @@ in_plt_section (CORE_ADDR pc, char *name) + } + + +-/* Set objfiles_changed_p so section map will be rebuilt next time it ++/* Set section_map_dirty so section map will be rebuilt next time it + is used. Called by reread_symbols. */ + + void + objfiles_changed (void) + { + /* Rebuild section map next time we need it. */ +- get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1; ++ get_objfile_pspace_data (current_program_space)->section_map_dirty = 1; ++} ++ ++/* See comments in objfiles.h. */ ++ ++void ++inhibit_section_map_updates (void) ++{ ++ get_objfile_pspace_data (current_program_space)->inhibit_updates = 1; ++} ++ ++/* See comments in objfiles.h. */ ++ ++void ++resume_section_map_updates (void) ++{ ++ get_objfile_pspace_data (current_program_space)->inhibit_updates = 0; ++} ++ ++/* See comments in objfiles.h. */ ++ ++void ++resume_section_map_updates_cleanup (void *arg) ++{ ++ resume_section_map_updates (); + } + + /* The default implementation for the "iterate_over_objfiles_in_search_order" + +--bPg9NdpM9EETxvqt-- + diff --git a/gdb-dlopen-stap-probe-3of7.patch b/gdb-dlopen-stap-probe-3of7.patch index 2337ded..93251ca 100644 --- a/gdb-dlopen-stap-probe-3of7.patch +++ b/gdb-dlopen-stap-probe-3of7.patch @@ -1,98 +1,314 @@ -2012-07-19 Gary Benson +http://sourceware.org/ml/gdb-patches/2013-05/msg00626.html +Subject: [RFA 3/7] New gdbserver functionality - * probe.h (get_probe_argument_count): New declaration. - (evaluate_probe_argument): Likewise. - * probe.c (get_probe_argument_count): New function. - (evaluate_probe_argument): Likewise. - (probe_safe_evaluate_at_pc): Use the above new functions. -diff --git a/gdb/probe.h b/gdb/probe.h -index 8d44ca2..1d29b87 100644 ---- a/gdb/probe.h -+++ b/gdb/probe.h -@@ -214,6 +214,16 @@ extern void info_probes_for_ops (char *arg, int from_tty, +--Kc9HNjpzOXVc7FFU +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This patch updates gdbserver to allow arguments to be passed in the +annex of qXfer:libraries-svr4:read to allow that function to transfer +partial lists of libraries. The ability of gdbserver to support +these arguments is indicated by a qSupported response containing +"augmented-libraries-svr4-read+". + +--Kc9HNjpzOXVc7FFU +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-3-gdbserver.patch" + +2013-05-16 Gary Benson + + * server.c (handle_query): Add "augmented-libraries-svr4-read+" + to qSupported response when appropriate. + (handle_qxfer_libraries_svr4): Allow qXfer:libraries-svr4:read + with nonzero-length annex. + * linux-low.c (linux_qxfer_libraries_svr4): Parse and handle + arguments supplied in annex. + +diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c +index 6bb36d8..0a8f68b 100644 +--- a/gdb/gdbserver/server.c ++++ b/gdb/gdbserver/server.c +@@ -1115,8 +1115,7 @@ handle_qxfer_libraries_svr4 (const char *annex, + if (writebuf != NULL) + return -2; - extern struct cmd_list_element **info_probes_cmdlist_get (void); +- if (annex[0] != '\0' || !target_running () +- || the_target->qxfer_libraries_svr4 == NULL) ++ if (!target_running () || the_target->qxfer_libraries_svr4 == NULL) + return -1; -+/* Return the argument count of the specified probe. */ -+ -+extern unsigned get_probe_argument_count (struct probe *probe); -+ -+/* Evaluate argument N of the specified probe. N must be between 0 -+ inclusive and get_probe_argument_count exclusive. */ -+ -+extern struct value *evaluate_probe_argument (struct probe *probe, -+ unsigned n); -+ - /* A convenience function that finds a probe at the PC in FRAME and - evaluates argument N, with 0 <= N < number_of_args. If there is no - probe at that location, or if the probe does not have enough arguments, -diff --git a/gdb/probe.c b/gdb/probe.c -index 77f3b13..a61f4ea 100644 ---- a/gdb/probe.c -+++ b/gdb/probe.c -@@ -632,28 +632,55 @@ info_probes_command (char *arg, int from_tty) + return the_target->qxfer_libraries_svr4 (annex, readbuf, writebuf, offset, len); +@@ -1743,7 +1742,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) + PBUFSIZ - 1); - /* See comments in probe.h. */ + if (the_target->qxfer_libraries_svr4 != NULL) +- strcat (own_buf, ";qXfer:libraries-svr4:read+"); ++ strcat (own_buf, ";qXfer:libraries-svr4:read+" ++ ";augmented-libraries-svr4-read+"); + else + { + /* We do not have any hook to indicate whether the non-SVR4 target +diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c +index 72c51e0..beb3b8f 100644 +--- a/gdb/gdbserver/linux-low.c ++++ b/gdb/gdbserver/linux-low.c +@@ -5677,6 +5677,12 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, + }; + const struct link_map_offsets *lmo; + unsigned int machine; ++ int ptr_size; ++ CORE_ADDR lm_addr = 0, lm_prev = 0; ++ int allocated = 1024; ++ char *p; ++ CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev; ++ int header_done = 0; -+unsigned -+get_probe_argument_count (struct probe *probe) -+{ -+ const struct sym_probe_fns *probe_fns; -+ -+ gdb_assert (probe->objfile != NULL); -+ gdb_assert (probe->objfile->sf != NULL); -+ -+ probe_fns = probe->objfile->sf->sym_probe_fns; -+ -+ gdb_assert (probe_fns != NULL); -+ -+ return probe_fns->sym_get_probe_argument_count (probe); -+} -+ -+/* See comments in probe.h. */ -+ -+struct value * -+evaluate_probe_argument (struct probe *probe, unsigned n) -+{ -+ const struct sym_probe_fns *probe_fns; -+ -+ gdb_assert (probe->objfile != NULL); -+ gdb_assert (probe->objfile->sf != NULL); -+ -+ probe_fns = probe->objfile->sf->sym_probe_fns; -+ -+ gdb_assert (probe_fns != NULL); -+ -+ return probe_fns->sym_evaluate_probe_argument (probe, n); -+} -+ -+/* See comments in probe.h. */ -+ - struct value * - probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n) - { - struct probe *probe; -- const struct sym_probe_fns *probe_fns; - unsigned n_args; + if (writebuf != NULL) + return -2; +@@ -5687,128 +5693,146 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, + xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid); + is_elf64 = elf_64_file_p (filename, &machine); + lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets; ++ ptr_size = is_elf64 ? 8 : 4; - probe = find_probe_by_pc (get_frame_pc (frame)); - if (!probe) - return NULL; +- if (priv->r_debug == 0) +- priv->r_debug = get_r_debug (pid, is_elf64); ++ if (annex[0] == '\0') ++ { ++ int r_version = 0; -- gdb_assert (probe->objfile != NULL); -- gdb_assert (probe->objfile->sf != NULL); -- gdb_assert (probe->objfile->sf->sym_probe_fns != NULL); +- /* We failed to find DT_DEBUG. Such situation will not change for this +- inferior - do not retry it. Report it to GDB as E01, see for the reasons +- at the GDB solib-svr4.c side. */ +- if (priv->r_debug == (CORE_ADDR) -1) +- return -1; ++ if (priv->r_debug == 0) ++ priv->r_debug = get_r_debug (pid, is_elf64); + +- if (priv->r_debug == 0) +- { +- document = xstrdup ("\n"); ++ /* We failed to find DT_DEBUG. Such situation will not change ++ for this inferior - do not retry it. Report it to GDB as ++ E01, see for the reasons at the GDB solib-svr4.c side. */ ++ if (priv->r_debug == (CORE_ADDR) -1) ++ return -1; ++ ++ if (priv->r_debug != 0) ++ { ++ if (linux_read_memory (priv->r_debug + lmo->r_version_offset, ++ (unsigned char *) &r_version, ++ sizeof (r_version)) != 0 ++ || r_version != 1) ++ { ++ warning ("unexpected r_debug version %d", r_version); ++ } ++ else if (read_one_ptr (priv->r_debug + lmo->r_map_offset, ++ &lm_addr, ptr_size) != 0) ++ { ++ warning ("unable to read r_map from 0x%lx", ++ (long) priv->r_debug + lmo->r_map_offset); ++ } ++ } + } + else + { +- int allocated = 1024; +- char *p; +- const int ptr_size = is_elf64 ? 8 : 4; +- CORE_ADDR lm_addr, lm_prev, l_name, l_addr, l_ld, l_next, l_prev; +- int r_version, header_done = 0; - -- probe_fns = probe->objfile->sf->sym_probe_fns; -- n_args = probe_fns->sym_get_probe_argument_count (probe); +- document = xmalloc (allocated); +- strcpy (document, "= n_args) - return NULL; +- r_version = 0; +- if (linux_read_memory (priv->r_debug + lmo->r_version_offset, +- (unsigned char *) &r_version, +- sizeof (r_version)) != 0 +- || r_version != 1) ++ while (annex[0] != '\0') + { +- warning ("unexpected r_debug version %d", r_version); +- goto done; ++ const char *sep; ++ CORE_ADDR *addrp; ++ int len; ++ ++ sep = strchr (annex, '='); ++ if (!sep) ++ break; ++ ++ len = sep - annex; ++ if (len == 5 && !strncmp (annex, "start", 5)) ++ addrp = &lm_addr; ++ else if (len == 4 && !strncmp (annex, "prev", 4)) ++ addrp = &lm_prev; ++ else ++ { ++ annex = strchr (sep, ';'); ++ if (!annex) ++ break; ++ annex++; ++ continue; ++ } ++ ++ annex = decode_address_to_semicolon (addrp, sep + 1); + } ++ } -- return probe_fns->sym_evaluate_probe_argument (probe, n); -+ return evaluate_probe_argument (probe, n); - } +- if (read_one_ptr (priv->r_debug + lmo->r_map_offset, +- &lm_addr, ptr_size) != 0) ++ document = xmalloc (allocated); ++ strcpy (document, "l_name_offset, ++ &l_name, ptr_size) == 0 ++ && read_one_ptr (lm_addr + lmo->l_addr_offset, ++ &l_addr, ptr_size) == 0 ++ && read_one_ptr (lm_addr + lmo->l_ld_offset, ++ &l_ld, ptr_size) == 0 ++ && read_one_ptr (lm_addr + lmo->l_prev_offset, ++ &l_prev, ptr_size) == 0 ++ && read_one_ptr (lm_addr + lmo->l_next_offset, ++ &l_next, ptr_size) == 0) ++ { ++ unsigned char libname[PATH_MAX]; ++ ++ if (lm_prev != l_prev) + { +- warning ("unable to read r_map from 0x%lx", +- (long) priv->r_debug + lmo->r_map_offset); +- goto done; ++ warning ("Corrupted shared library list: 0x%lx != 0x%lx", ++ (long) lm_prev, (long) l_prev); ++ break; + } - /* See comment in probe.h. */ +- lm_prev = 0; +- while (read_one_ptr (lm_addr + lmo->l_name_offset, +- &l_name, ptr_size) == 0 +- && read_one_ptr (lm_addr + lmo->l_addr_offset, +- &l_addr, ptr_size) == 0 +- && read_one_ptr (lm_addr + lmo->l_ld_offset, +- &l_ld, ptr_size) == 0 +- && read_one_ptr (lm_addr + lmo->l_prev_offset, +- &l_prev, ptr_size) == 0 +- && read_one_ptr (lm_addr + lmo->l_next_offset, +- &l_next, ptr_size) == 0) ++ /* Not checking for error because reading may stop before ++ we've got PATH_MAX worth of characters. */ ++ libname[0] = '\0'; ++ linux_read_memory (l_name, libname, sizeof (libname) - 1); ++ libname[sizeof (libname) - 1] = '\0'; ++ if (libname[0] != '\0') + { +- unsigned char libname[PATH_MAX]; ++ /* 6x the size for xml_escape_text below. */ ++ size_t len = 6 * strlen ((char *) libname); ++ char *name; + +- if (lm_prev != l_prev) ++ if (!header_done) + { +- warning ("Corrupted shared library list: 0x%lx != 0x%lx", +- (long) lm_prev, (long) l_prev); +- break; ++ /* Terminate `", +- name, (unsigned long) lm_addr, +- (unsigned long) l_addr, (unsigned long) l_ld); +- free (name); +- } +- else if (lm_prev == 0) +- { +- sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr); +- p = p + strlen (p); ++ document = xrealloc (document, 2 * allocated); ++ allocated *= 2; ++ p = document + document_len; + } + +- if (l_next == 0) +- break; +- +- lm_prev = lm_addr; +- lm_addr = l_next; ++ name = xml_escape_text ((char *) libname); ++ p += sprintf (p, "", ++ name, (unsigned long) lm_addr, ++ (unsigned long) l_addr, (unsigned long) l_ld); ++ free (name); + } +- done: +- if (!header_done) ++ else if (lm_prev == 0) + { +- /* Empty list; terminate `"); ++ sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr); ++ p = p + strlen (p); + } +- else +- strcpy (p, ""); ++ ++ lm_prev = lm_addr; ++ lm_addr = l_next; + } + ++ if (!header_done) ++ { ++ /* Empty list; terminate `"); ++ } ++ else ++ strcpy (p, ""); ++ + document_len = strlen (document); + if (offset < document_len) + document_len -= offset; + +--Kc9HNjpzOXVc7FFU-- + diff --git a/gdb-dlopen-stap-probe-4of7.patch b/gdb-dlopen-stap-probe-4of7.patch index 299931a..224c366 100644 --- a/gdb-dlopen-stap-probe-4of7.patch +++ b/gdb-dlopen-stap-probe-4of7.patch @@ -1,131 +1,146 @@ -2012-07-19 Gary Benson +http://sourceware.org/ml/gdb-patches/2013-05/msg00628.html +Subject: [RFA 4/7] GDB support for new gdbserver functionality - * solib-svr4.c (svr4_info): Move earlier. - (solib_svr4_pspace_data): Likewise. - (svr4_pspace_data_cleanup): Likewise. - (get_svr4_info): Likewise. -diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c -index 307e483..c88b9cb 100644 ---- a/gdb/solib-svr4.c -+++ b/gdb/solib-svr4.c -@@ -106,6 +106,59 @@ static const char * const main_name_list[] = - NULL - }; +--CaPKgh3XHpq3rEUV +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This patch adds client support for the new gdbserver functionality +provided by patch 3 of this series. + +--CaPKgh3XHpq3rEUV +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-4-remote.patch" + +2013-05-16 Gary Benson + + * target.h (target_ops): New field + "to_augmented_libraries_svr4_read". + (target_augmented_libraries_svr4_read): New macro. + * target.c (update_current_target): Handle + to_augmented_libraries_svr4_read. + * remote.c (remote_state): New field + "augmented_libraries_svr4_read". + (remote_augmented_libraries_svr4_read_feature): New function. + (remote_protocol_features): Add entry for + "augmented-libraries-svr4-read". + (remote_augmented_libraries_svr4_read): New function. + (init_remote_ops): Initialize + remote_ops.to_augmented_libraries_svr4_read. + +diff --git a/gdb/target.h b/gdb/target.h +index e937d39..a8587e8 100644 +--- a/gdb/target.h ++++ b/gdb/target.h +@@ -941,6 +941,10 @@ struct target_ops + (inclusive) to function END (exclusive). */ + void (*to_call_history_range) (ULONGEST begin, ULONGEST end, int flags); -+/* Per pspace SVR4 specific data. */ ++ /* Nonzero if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a ++ non-empty annex. */ ++ int (*to_augmented_libraries_svr4_read) (void); + -+struct svr4_info -+{ -+ CORE_ADDR debug_base; /* Base of dynamic linker structures. */ -+ -+ /* Validity flag for debug_loader_offset. */ -+ int debug_loader_offset_p; -+ -+ /* Load address for the dynamic linker, inferred. */ -+ CORE_ADDR debug_loader_offset; -+ -+ /* Name of the dynamic linker, valid if debug_loader_offset_p. */ -+ char *debug_loader_name; -+ -+ /* Load map address for the main executable. */ -+ CORE_ADDR main_lm_addr; -+ -+ CORE_ADDR interp_text_sect_low; -+ CORE_ADDR interp_text_sect_high; -+ CORE_ADDR interp_plt_sect_low; -+ CORE_ADDR interp_plt_sect_high; -+}; -+ -+/* Per-program-space data key. */ -+static const struct program_space_data *solib_svr4_pspace_data; -+ -+static void -+svr4_pspace_data_cleanup (struct program_space *pspace, void *arg) -+{ -+ struct svr4_info *info; -+ -+ info = program_space_data (pspace, solib_svr4_pspace_data); -+ xfree (info); -+} -+ -+/* Get the current svr4 data. If none is found yet, add it now. This -+ function always returns a valid object. */ -+ -+static struct svr4_info * -+get_svr4_info (void) -+{ -+ struct svr4_info *info; -+ -+ info = program_space_data (current_program_space, solib_svr4_pspace_data); -+ if (info != NULL) -+ return info; -+ -+ info = XZALLOC (struct svr4_info); -+ set_program_space_data (current_program_space, solib_svr4_pspace_data, info); -+ return info; -+} -+ - /* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent - the same shared library. */ + int to_magic; + /* Need sub-structure for target machine related rather than comm related? + */ +@@ -1809,6 +1813,9 @@ extern char *target_fileio_read_stralloc (const char *filename); + #define target_can_use_agent() \ + (*current_target.to_can_use_agent) () -@@ -291,59 +344,6 @@ lm_addr_check (struct so_list *so, bfd *abfd) - return so->lm_info->l_addr; ++#define target_augmented_libraries_svr4_read() \ ++ (*current_target.to_augmented_libraries_svr4_read) () ++ + /* Command logging facility. */ + + #define target_log_command(p) \ +diff --git a/gdb/target.c b/gdb/target.c +index 8653dac..519b97f 100644 +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -731,6 +731,7 @@ update_current_target (void) + INHERIT (to_traceframe_info, t); + INHERIT (to_use_agent, t); + INHERIT (to_can_use_agent, t); ++ INHERIT (to_augmented_libraries_svr4_read, t); + INHERIT (to_magic, t); + INHERIT (to_supports_evaluation_of_breakpoint_conditions, t); + INHERIT (to_can_run_breakpoint_commands, t); +@@ -975,6 +976,9 @@ update_current_target (void) + de_fault (to_can_use_agent, + (int (*) (void)) + return_zero); ++ de_fault (to_augmented_libraries_svr4_read, ++ (int (*) (void)) ++ return_zero); + de_fault (to_execution_direction, default_execution_direction); + + #undef de_fault +diff --git a/gdb/remote.c b/gdb/remote.c +index 51bf025..e1cf8a4 100644 +--- a/gdb/remote.c ++++ b/gdb/remote.c +@@ -343,6 +343,10 @@ struct remote_state + /* True if the stub can collect strings using tracenz bytecode. */ + int string_tracing; + ++ /* True if the stub supports qXfer:libraries-svr4:read with a ++ non-empty annex. */ ++ int augmented_libraries_svr4_read; ++ + /* Nonzero if the user has pressed Ctrl-C, but the target hasn't + responded to that. */ + int ctrlc_pending_p; +@@ -3931,6 +3935,16 @@ remote_string_tracing_feature (const struct protocol_feature *feature, + rs->string_tracing = (support == PACKET_ENABLE); } --/* Per pspace SVR4 specific data. */ -- --struct svr4_info --{ -- CORE_ADDR debug_base; /* Base of dynamic linker structures. */ -- -- /* Validity flag for debug_loader_offset. */ -- int debug_loader_offset_p; -- -- /* Load address for the dynamic linker, inferred. */ -- CORE_ADDR debug_loader_offset; -- -- /* Name of the dynamic linker, valid if debug_loader_offset_p. */ -- char *debug_loader_name; -- -- /* Load map address for the main executable. */ -- CORE_ADDR main_lm_addr; -- -- CORE_ADDR interp_text_sect_low; -- CORE_ADDR interp_text_sect_high; -- CORE_ADDR interp_plt_sect_low; -- CORE_ADDR interp_plt_sect_high; --}; -- --/* Per-program-space data key. */ --static const struct program_space_data *solib_svr4_pspace_data; -- --static void --svr4_pspace_data_cleanup (struct program_space *pspace, void *arg) --{ -- struct svr4_info *info; -- -- info = program_space_data (pspace, solib_svr4_pspace_data); -- xfree (info); --} -- --/* Get the current svr4 data. If none is found yet, add it now. This -- function always returns a valid object. */ -- --static struct svr4_info * --get_svr4_info (void) --{ -- struct svr4_info *info; -- -- info = program_space_data (current_program_space, solib_svr4_pspace_data); -- if (info != NULL) -- return info; -- -- info = XZALLOC (struct svr4_info); -- set_program_space_data (current_program_space, solib_svr4_pspace_data, info); -- return info; --} -- - /* Local function prototypes */ ++static void ++remote_augmented_libraries_svr4_read_feature ++ (const struct protocol_feature *feature, ++ enum packet_support support, const char *value) ++{ ++ struct remote_state *rs = get_remote_state (); ++ ++ rs->augmented_libraries_svr4_read = (support == PACKET_ENABLE); ++} ++ + static struct protocol_feature remote_protocol_features[] = { + { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 }, + { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet, +@@ -3941,6 +3955,8 @@ static struct protocol_feature remote_protocol_features[] = { + PACKET_qXfer_libraries }, + { "qXfer:libraries-svr4:read", PACKET_DISABLE, remote_supported_packet, + PACKET_qXfer_libraries_svr4 }, ++ { "augmented-libraries-svr4-read", PACKET_DISABLE, ++ remote_augmented_libraries_svr4_read_feature, -1 }, + { "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet, + PACKET_qXfer_memory_map }, + { "qXfer:spu:read", PACKET_DISABLE, remote_supported_packet, +@@ -11343,6 +11359,14 @@ remote_read_btrace (struct btrace_target_info *tinfo, + return btrace; + } - static int match_main (const char *); ++static int ++remote_augmented_libraries_svr4_read (void) ++{ ++ struct remote_state *rs = get_remote_state (); ++ ++ return rs->augmented_libraries_svr4_read; ++} ++ + static void + init_remote_ops (void) + { +@@ -11465,6 +11489,8 @@ Specify the serial device it is connected to\n\ + remote_ops.to_disable_btrace = remote_disable_btrace; + remote_ops.to_teardown_btrace = remote_teardown_btrace; + remote_ops.to_read_btrace = remote_read_btrace; ++ remote_ops.to_augmented_libraries_svr4_read = ++ remote_augmented_libraries_svr4_read; + } + + /* Set up the extended remote vector by making a copy of the standard + +--CaPKgh3XHpq3rEUV-- + diff --git a/gdb-dlopen-stap-probe-5of7.patch b/gdb-dlopen-stap-probe-5of7.patch index cb18cd6..2ea873d 100644 --- a/gdb-dlopen-stap-probe-5of7.patch +++ b/gdb-dlopen-stap-probe-5of7.patch @@ -1,17 +1,1089 @@ -2012-07-19 Gary Benson +http://sourceware.org/ml/gdb-patches/2013-05/msg00632.html +Subject: [RFA 5/7] Improved linker-debugger interface - * solib-svr4.c (svr4_info): Made debug_loader_offset_p a bitfield. -diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c -index c88b9cb..8e41f19 100644 ---- a/gdb/solib-svr4.c -+++ b/gdb/solib-svr4.c -@@ -113,7 +113,7 @@ struct svr4_info - CORE_ADDR debug_base; /* Base of dynamic linker structures. */ +--qse+WBH4guesipZ+ +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This patch implements the probes-based runtime linker interface. +It works as follows: + + - On inferior startup, GDB searches the dynamic linker for a + number of named probes. + + - If all probes are found, GDB sets a breakpoint on each one. + Otherwise, the standard function _dl_debug_state is used. + + - When using probes, a per-pspace list is maintained of all + libraries currently loaded by the inferior. It's updated + as necessary every time a solib event stop occurs. + + - When using probes, svr4_current_sos will return a copy of + the cached list. When not using probes the entire list + will be fetched from the inferior as before. + + - If any error occurs, GDB will print a warning and revert to + the standard interface. + +--qse+WBH4guesipZ+ +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-5-main-changes.patch" + +2013-05-16 Gary Benson + + * breakpoint.h (handle_solib_event): Moved function declaration + to solib.h. + * breakpoint.c (handle_solib_event): Moved function to solib.c. + (bpstat_stop_status): Pass new argument to handle_solib_event. + * solib.h (update_solib_breakpoints): New function declaration. + (handle_solib_event): Moved function declaration from + breakpoint.h. + * solib.c (update_solib_breakpoints): New function. + (handle_solib_event): Moved function from breakpoint.c. + Updated to call solib_ops->handle_event if not NULL. + * solist.h (target_so_ops): New fields "update_breakpoints" and + "handle_event". + * infrun.c (set_stop_on_solib_events): New function. + (_initialize_infrun): Use the above for "set + stop-on-solib-events". + (handle_inferior_event): Pass new argument to handle_solib_event. + * solib-svr4.c (probe.h): New include. + (svr4_free_library_list): New forward declaration. + (probe_action): New enum. + (probe_info): New struct. + (probe_info): New static variable. + (NUM_PROBES): New definition. + (svr4_info): New fields "using_xfer", "probes_table" and + "solib_list". + (free_probes_table): New function. + (free_solib_list): New function. + (svr4_pspace_data_cleanup): Free probes table and solib list. + (svr4_copy_library_list): New function. + (svr4_current_sos_via_xfer_libraries): New parameter "annex". + (svr4_read_so_list): New parameter "prev_lm". + (svr4_current_sos_direct): Renamed from "svr4_current_sos". + (svr4_current_sos): New function. + (probe_and_action): New struct. + (hash_probe_and_action): New function. + (equal_probe_and_action): Likewise. + (register_solib_event_probe): Likewise. + (solib_event_probe_at): Likewise. + (solib_event_probe_action): Likewise. + (solist_update_full): Likewise. + (solist_update_incremental): Likewise. + (disable_probes_interface_cleanup): Likewise. + (svr4_handle_solib_event): Likewise. + (svr4_update_solib_event_breakpoint): Likewise. + (svr4_update_solib_event_breakpoints): Likewise. + (svr4_create_solib_event_breakpoints): Likewise. + (enable_break): Free probes table before creating breakpoints. + Use svr4_create_solib_event_breakpoints to create breakpoints. + (svr4_solib_create_inferior_hook): Free the solib list. + (_initialize_svr4_solib): Initialise + svr4_so_ops.handle_solib_event and svr4_so_ops.update_breakpoints. + +Index: gdb-7.6/gdb/breakpoint.h +=================================================================== +--- gdb-7.6.orig/gdb/breakpoint.h 2013-05-19 16:16:20.551087270 +0200 ++++ gdb-7.6/gdb/breakpoint.h 2013-05-19 16:16:20.837086948 +0200 +@@ -1552,8 +1552,6 @@ extern int user_breakpoint_p (struct bre + /* Attempt to determine architecture of location identified by SAL. */ + extern struct gdbarch *get_sal_arch (struct symtab_and_line sal); - /* Validity flag for debug_loader_offset. */ -- int debug_loader_offset_p; -+ unsigned int debug_loader_offset_p : 1; +-extern void handle_solib_event (void); +- + extern void breakpoint_free_objfile (struct objfile *objfile); - /* Load address for the dynamic linker, inferred. */ - CORE_ADDR debug_loader_offset; + extern void breakpoints_relocate (struct objfile *objfile, +Index: gdb-7.6/gdb/solib.h +=================================================================== +--- gdb-7.6.orig/gdb/solib.h 2013-01-01 07:32:51.000000000 +0100 ++++ gdb-7.6/gdb/solib.h 2013-05-19 16:16:20.838086946 +0200 +@@ -90,4 +90,12 @@ extern CORE_ADDR gdb_bfd_lookup_symbol_f + void *), + void *data); + ++/* Enable or disable optional solib event breakpoints as appropriate. */ ++ ++extern void update_solib_breakpoints (void); ++ ++/* Handle an solib event by calling solib_add. */ ++ ++extern void handle_solib_event (void); ++ + #endif /* SOLIB_H */ +Index: gdb-7.6/gdb/solib.c +=================================================================== +--- gdb-7.6.orig/gdb/solib.c 2013-05-19 16:16:20.468087363 +0200 ++++ gdb-7.6/gdb/solib.c 2013-05-19 16:16:20.838086946 +0200 +@@ -1221,6 +1221,38 @@ no_shared_libraries (char *ignored, int + objfile_purge_solibs (); + } + ++/* See solib.h. */ ++ ++void ++update_solib_breakpoints (void) ++{ ++ struct target_so_ops *ops = solib_ops (target_gdbarch ()); ++ ++ if (ops->update_breakpoints != NULL) ++ ops->update_breakpoints (); ++} ++ ++/* See solib.h. */ ++ ++void ++handle_solib_event (void) ++{ ++ struct target_so_ops *ops = solib_ops (target_gdbarch ()); ++ ++ if (ops->handle_event != NULL) ++ ops->handle_event (); ++ ++ clear_program_space_solib_cache (current_inferior ()->pspace); ++ ++ /* Check for any newly added shared libraries if we're supposed to ++ be adding them automatically. Switch terminal for any messages ++ produced by breakpoint_re_set. */ ++ target_terminal_ours_for_output (); ++ solib_add (NULL, 0, ¤t_target, auto_solib_add); ++ target_terminal_inferior (); ++} ++ ++ + /* Reload shared libraries, but avoid reloading the same symbol file + we already have loaded. */ + +Index: gdb-7.6/gdb/solist.h +=================================================================== +--- gdb-7.6.orig/gdb/solist.h 2013-01-01 07:32:51.000000000 +0100 ++++ gdb-7.6/gdb/solist.h 2013-05-19 16:16:20.838086946 +0200 +@@ -148,6 +148,19 @@ struct target_so_ops + core file (in particular, for readonly sections). */ + int (*keep_data_in_core) (CORE_ADDR vaddr, + unsigned long size); ++ ++ /* Enable or disable optional solib event breakpoints as ++ appropriate. This should be called whenever ++ stop_on_solib_events is changed. This pointer can be ++ NULL, in which case no enabling or disabling is necessary ++ for this target. */ ++ void (*update_breakpoints) (void); ++ ++ /* Target-specific processing of solib events that will be ++ performed before solib_add is called. This pointer can be ++ NULL, in which case no specific preprocessing is necessary ++ for this target. */ ++ void (*handle_event) (void); + }; + + /* Free the memory associated with a (so_list *). */ +Index: gdb-7.6/gdb/infrun.c +=================================================================== +--- gdb-7.6.orig/gdb/infrun.c 2013-05-19 16:16:20.508087318 +0200 ++++ gdb-7.6/gdb/infrun.c 2013-05-19 16:16:20.840086944 +0200 +@@ -370,6 +370,16 @@ static struct symbol *step_start_functio + /* Nonzero if we want to give control to the user when we're notified + of shared library events by the dynamic linker. */ + int stop_on_solib_events; ++ ++/* Enable or disable optional shared library event breakpoints ++ as appropriate when the above flag is changed. */ ++ ++static void ++set_stop_on_solib_events (char *args, int from_tty, struct cmd_list_element *c) ++{ ++ update_solib_breakpoints (); ++} ++ + static void + show_stop_on_solib_events (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +@@ -7335,7 +7345,7 @@ Show stopping for shared library events. + If nonzero, gdb will give control to the user when the dynamic linker\n\ + notifies gdb of shared library events. The most common event of interest\n\ + to the user would be loading/unloading of a new library."), +- NULL, ++ set_stop_on_solib_events, + show_stop_on_solib_events, + &setlist, &showlist); + +Index: gdb-7.6/gdb/solib-svr4.c +=================================================================== +--- gdb-7.6.orig/gdb/solib-svr4.c 2013-05-19 16:16:20.468087363 +0200 ++++ gdb-7.6/gdb/solib-svr4.c 2013-05-19 16:21:40.285816084 +0200 +@@ -47,9 +47,12 @@ + #include "exceptions.h" + #include "gdb_bfd.h" + ++#include "probe.h" ++ + 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); ++static void svr4_free_library_list (void *p_list); + + /* Link map info to include in an allocated so_list entry. */ + +@@ -106,6 +109,55 @@ static const char * const main_name_lis + NULL + }; + ++/* What to do when a probe stop occurs. */ ++ ++enum probe_action ++ { ++ /* Something went seriously wrong. Stop using probes and ++ revert to using the older interface. */ ++ PROBES_INTERFACE_FAILED, ++ ++ /* No action is required. The shared object list is still ++ valid. */ ++ DO_NOTHING, ++ ++ /* The shared object list should be reloaded entirely. */ ++ FULL_RELOAD, ++ ++ /* Attempt to incrementally update the shared object list. If ++ the update fails or is not possible, fall back to reloading ++ the list in full. */ ++ UPDATE_OR_RELOAD, ++ }; ++ ++/* A probe's name and its associated action. */ ++ ++struct probe_info ++{ ++ /* The name of the probe. */ ++ const char *name; ++ ++ /* What to do when a probe stop occurs. */ ++ enum probe_action action; ++}; ++ ++/* A list of named probes and their associated actions. If all ++ probes are present in the dynamic linker then the probes-based ++ interface will be used. */ ++ ++static const struct probe_info probe_info[] = ++{ ++ { "init_start", DO_NOTHING }, ++ { "init_complete", FULL_RELOAD }, ++ { "map_start", DO_NOTHING }, ++ { "map_failed", DO_NOTHING }, ++ { "reloc_complete", UPDATE_OR_RELOAD }, ++ { "unmap_start", DO_NOTHING }, ++ { "unmap_complete", FULL_RELOAD }, ++}; ++ ++#define NUM_PROBES ARRAY_SIZE (probe_info) ++ + /* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent + the same shared library. */ + +@@ -313,17 +365,56 @@ struct svr4_info + CORE_ADDR interp_text_sect_high; + CORE_ADDR interp_plt_sect_low; + CORE_ADDR interp_plt_sect_high; ++ ++ /* Nonzero if the list of objects was last obtained from the target ++ via qXfer:libraries-svr4:read. */ ++ int using_xfer; ++ ++ /* Table mapping breakpoint addresses to probes and actions, used ++ by the probes-based interface. */ ++ htab_t probes_table; ++ ++ /* List of objects loaded into the inferior, used by the probes- ++ based interface. */ ++ struct so_list *solib_list; + }; + + /* Per-program-space data key. */ + static const struct program_space_data *solib_svr4_pspace_data; + ++/* Free the probes table. */ ++ ++static void ++free_probes_table (struct svr4_info *info) ++{ ++ if (info->probes_table == NULL) ++ return; ++ ++ htab_delete (info->probes_table); ++ info->probes_table = NULL; ++} ++ ++/* Free the solib list. */ ++ ++static void ++free_solib_list (struct svr4_info *info) ++{ ++ svr4_free_library_list (&info->solib_list); ++ info->solib_list = NULL; ++} ++ + static void + svr4_pspace_data_cleanup (struct program_space *pspace, void *arg) + { + struct svr4_info *info; + + info = program_space_data (pspace, solib_svr4_pspace_data); ++ if (info == NULL) ++ return; ++ ++ free_probes_table (info); ++ free_solib_list (info); ++ + xfree (info); + } + +@@ -982,6 +1073,36 @@ svr4_free_library_list (void *p_list) + } + } + ++/* Copy library list. */ ++ ++static struct so_list * ++svr4_copy_library_list (struct so_list *src) ++{ ++ struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); ++ struct so_list *dst = NULL; ++ struct so_list **link = &dst; ++ ++ while (src != NULL) ++ { ++ struct so_list *new; ++ ++ new = XZALLOC (struct so_list); ++ ++ memcpy (new, src, sizeof (struct so_list)); ++ ++ new->lm_info = xmalloc (lmo->link_map_size); ++ memcpy (new->lm_info, src->lm_info, lmo->link_map_size); ++ ++ new->next = NULL; ++ *link = new; ++ link = &new->next; ++ ++ src = src->next; ++ } ++ ++ return dst; ++} ++ + #ifdef HAVE_LIBEXPAT + + #include "xml-support.h" +@@ -1097,14 +1218,19 @@ svr4_parse_libraries (const char *docume + return 0; + } + +-/* Attempt to get so_list from target via qXfer:libraries:read packet. ++/* Attempt to get so_list from target via qXfer:libraries-svr4:read packet. + + Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such + case. Return 1 if *SO_LIST_RETURN contains the library list, it may be +- empty, caller is responsible for freeing all its entries. */ ++ empty, caller is responsible for freeing all its entries. ++ ++ Note that ANNEX must be NULL if the remote does not explicitly allow ++ qXfer:libraries-svr4:read packets with non-empty annexes. Support for ++ this can be checked using target_augmented_libraries_svr4_read (). */ + + static int +-svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list) ++svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list, ++ const char *annex) + { + char *svr4_library_document; + int result; +@@ -1113,7 +1239,7 @@ svr4_current_sos_via_xfer_libraries (str + /* Fetch the list of shared libraries. */ + svr4_library_document = target_read_stralloc (¤t_target, + TARGET_OBJECT_LIBRARIES_SVR4, +- NULL); ++ annex); + if (svr4_library_document == NULL) + return 0; + +@@ -1127,7 +1253,8 @@ svr4_current_sos_via_xfer_libraries (str + #else + + static int +-svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list) ++svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list, ++ const char *annex) + { + return 0; + } +@@ -1161,15 +1288,17 @@ svr4_default_sos (void) + return new; + } + +-/* Read the whole inferior libraries chain starting at address LM. Add the +- entries to the tail referenced by LINK_PTR_PTR. Ignore the first entry if +- IGNORE_FIRST and set global MAIN_LM_ADDR according to it. */ ++/* Read the whole inferior libraries chain starting at address LM. ++ Expect the first entry in the chain's previous entry to be PREV_LM. ++ Add the entries to the tail referenced by LINK_PTR_PTR. Ignore the ++ first entry if IGNORE_FIRST and set global MAIN_LM_ADDR according ++ to it. Returns nonzero upon success. */ + +-static void +-svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr, +- int ignore_first) ++static int ++svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, ++ struct so_list ***link_ptr_ptr, int ignore_first) + { +- CORE_ADDR prev_lm = 0, next_lm; ++ CORE_ADDR next_lm; + + for (; lm != 0; prev_lm = lm, lm = next_lm) + { +@@ -1185,7 +1314,7 @@ svr4_read_so_list (CORE_ADDR lm, struct + if (new->lm_info == NULL) + { + do_cleanups (old_chain); +- break; ++ return 0; + } + + next_lm = new->lm_info->l_next; +@@ -1196,7 +1325,7 @@ svr4_read_so_list (CORE_ADDR lm, struct + paddress (target_gdbarch (), prev_lm), + paddress (target_gdbarch (), new->lm_info->l_prev)); + do_cleanups (old_chain); +- break; ++ return 0; + } + + /* For SVR4 versions, the first entry in the link map is for the +@@ -1291,17 +1420,19 @@ svr4_read_so_list (CORE_ADDR lm, struct + **link_ptr_ptr = new; + *link_ptr_ptr = &new->next; + } ++ ++ return 1; + } + +-/* Implement the "current_sos" target_so_ops method. */ ++/* Read the full list of currently loaded shared objects directly from ++ the inferior. */ + + static struct so_list * +-svr4_current_sos (void) ++svr4_current_sos_direct (struct svr4_info *info) + { + CORE_ADDR lm; + struct so_list *head = NULL; + struct so_list **link_ptr = &head; +- struct svr4_info *info; + struct cleanup *back_to; + int ignore_first; + struct svr4_library_list library_list; +@@ -1314,19 +1445,16 @@ svr4_current_sos (void) + Unfortunately statically linked inferiors will also fall back through this + suboptimal code path. */ + +- if (svr4_current_sos_via_xfer_libraries (&library_list)) ++ info->using_xfer = svr4_current_sos_via_xfer_libraries (&library_list, ++ NULL); ++ if (info->using_xfer) + { + if (library_list.main_lm) +- { +- info = get_svr4_info (); +- info->main_lm_addr = library_list.main_lm; +- } ++ info->main_lm_addr = library_list.main_lm; + + return library_list.head ? library_list.head : svr4_default_sos (); + } + +- info = get_svr4_info (); +- + /* Always locate the debug struct, in case it has moved. */ + info->debug_base = 0; + locate_base (info); +@@ -1349,7 +1477,7 @@ svr4_current_sos (void) + `struct so_list' nodes. */ + lm = solib_svr4_r_map (info); + if (lm) +- svr4_read_so_list (lm, &link_ptr, ignore_first); ++ svr4_read_so_list (lm, 0, &link_ptr, ignore_first); + + /* On Solaris, the dynamic linker is not in the normal list of + shared objects, so make sure we pick it up too. Having +@@ -1357,7 +1485,7 @@ svr4_current_sos (void) + for skipping dynamic linker resolver code. */ + lm = solib_svr4_r_ldsomap (info); + if (lm) +- svr4_read_so_list (lm, &link_ptr, 0); ++ svr4_read_so_list (lm, 0, &link_ptr, 0); + + discard_cleanups (back_to); + +@@ -1367,6 +1495,22 @@ svr4_current_sos (void) + return head; + } + ++/* Implement the "current_sos" target_so_ops method. */ ++ ++static struct so_list * ++svr4_current_sos (void) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ ++ /* If we are using the probes interface and the solib list has ++ been cached then we simply return that. */ ++ if (info->solib_list != NULL) ++ return svr4_copy_library_list (info->solib_list); ++ ++ /* Otherwise obtain the solib list directly from the inferior. */ ++ return svr4_current_sos_direct (info); ++} ++ + /* Get the address of the link_map for a given OBJFILE. */ + + CORE_ADDR +@@ -1449,6 +1593,434 @@ exec_entry_point (struct bfd *abfd, stru + return gdbarch_addr_bits_remove (target_gdbarch (), addr); + } + ++/* A probe and its associated action. */ ++ ++struct probe_and_action ++{ ++ /* The probe. */ ++ struct probe *probe; ++ ++ /* The action. */ ++ enum probe_action action; ++}; ++ ++/* Returns a hash code for the probe_and_action referenced by p. */ ++ ++static hashval_t ++hash_probe_and_action (const void *p) ++{ ++ const struct probe_and_action *pa = p; ++ ++ return (hashval_t) pa->probe->address; ++} ++ ++/* Returns non-zero if the probe_and_actions referenced by p1 and p2 ++ are equal. */ ++ ++static int ++equal_probe_and_action (const void *p1, const void *p2) ++{ ++ const struct probe_and_action *pa1 = p1; ++ const struct probe_and_action *pa2 = p2; ++ ++ return pa1->probe->address == pa2->probe->address; ++} ++ ++/* Register a solib event probe and its associated action in the ++ probes table. */ ++ ++static void ++register_solib_event_probe (struct probe *probe, enum probe_action action) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ struct probe_and_action lookup, *pa; ++ void **slot; ++ ++ /* Create the probes table, if necessary. */ ++ if (info->probes_table == NULL) ++ { ++ info->probes_table = htab_create_alloc (1, hash_probe_and_action, ++ equal_probe_and_action, ++ xfree, xcalloc, xfree); ++ } ++ ++ lookup.probe = probe; ++ slot = htab_find_slot (info->probes_table, &lookup, INSERT); ++ gdb_assert (*slot == HTAB_EMPTY_ENTRY); ++ ++ pa = XCNEW (struct probe_and_action); ++ pa->probe = probe; ++ pa->action = action; ++ ++ *slot = pa; ++} ++ ++/* Get the solib event probe at the specified location, and the ++ action associated with it. Returns NULL if no solib event probe ++ was found. */ ++ ++static struct probe_and_action * ++solib_event_probe_at (struct svr4_info *info, CORE_ADDR address) ++{ ++ struct probe lookup_probe; ++ struct probe_and_action lookup; ++ void **slot; ++ ++ lookup_probe.address = address; ++ lookup.probe = &lookup_probe; ++ slot = htab_find_slot (info->probes_table, &lookup, NO_INSERT); ++ ++ if (slot == NULL) ++ return NULL; ++ ++ return (struct probe_and_action *) *slot; ++} ++ ++/* Decide what action to take when the specified solib event probe is ++ hit. */ ++ ++static enum probe_action ++solib_event_probe_action (struct probe_and_action *pa) ++{ ++ enum probe_action action; ++ unsigned probe_argc; ++ ++ action = pa->action; ++ if (action == DO_NOTHING || action == PROBES_INTERFACE_FAILED) ++ return action; ++ ++ gdb_assert (action == FULL_RELOAD || action == UPDATE_OR_RELOAD); ++ ++ /* Check that an appropriate number of arguments has been supplied. ++ We expect: ++ arg0: Lmid_t lmid (mandatory) ++ arg1: struct r_debug *debug_base (mandatory) ++ arg2: struct link_map *new (optional, for incremental updates) */ ++ probe_argc = get_probe_argument_count (pa->probe); ++ if (probe_argc == 2) ++ action = FULL_RELOAD; ++ else if (probe_argc < 2) ++ action = PROBES_INTERFACE_FAILED; ++ ++ return action; ++} ++ ++/* Populate the shared object list by reading the entire list of ++ shared objects from the inferior. Returns nonzero on success. */ ++ ++static int ++solist_update_full (struct svr4_info *info) ++{ ++ svr4_free_library_list (&info->solib_list); ++ info->solib_list = svr4_current_sos_direct (info); ++ ++ return 1; ++} ++ ++/* Update the shared object list starting from the link-map entry ++ passed by the linker in the probe's third argument. Returns ++ nonzero if the list was successfully updated, or zero to indicate ++ failure. */ ++ ++static int ++solist_update_incremental (struct svr4_info *info, CORE_ADDR lm) ++{ ++ struct so_list *tail; ++ CORE_ADDR prev_lm; ++ ++ /* Fall back to a full update if we haven't read anything yet. */ ++ if (info->solib_list == NULL) ++ return 0; ++ ++ /* Fall back to a full update if we are using a remote target ++ that does not support incremental transfers. */ ++ if (info->using_xfer && !target_augmented_libraries_svr4_read()) ++ return 0; ++ ++ /* Walk to the end of the list. */ ++ for (tail = info->solib_list; tail->next; tail = tail->next); ++ prev_lm = tail->lm_info->lm_addr; ++ ++ /* Read the new objects. */ ++ if (info->using_xfer) ++ { ++ struct svr4_library_list library_list; ++ char annex[64]; ++ ++ xsnprintf (annex, sizeof (annex), "start=%lx;prev=%lx", lm, prev_lm); ++ if (!svr4_current_sos_via_xfer_libraries (&library_list, annex)) ++ return 0; ++ ++ tail->next = library_list.head; ++ } ++ else ++ { ++ struct so_list **link = &tail->next; ++ ++ if (!svr4_read_so_list (lm, prev_lm, &link, 0)) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* Disable the probes-based linker interface and revert to the ++ original interface. We don't reset the breakpoints as the ++ ones set up for the probes-based interface are adequate. */ ++ ++static void ++disable_probes_interface_cleanup (void *arg) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ ++ warning (_("Probes-based dynamic linker interface failed.\n" ++ "Reverting to original interface.\n")); ++ ++ free_probes_table (info); ++ free_solib_list (info); ++} ++ ++/* Update the solib list as appropriate when using the ++ probes-based linker interface. Do nothing if using the ++ standard interface. */ ++ ++static void ++svr4_handle_solib_event (void) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ struct probe_and_action *pa; ++ enum probe_action action; ++ struct cleanup *old_chain, *usm_chain; ++ struct value *val; ++ CORE_ADDR pc, debug_base, lm = 0; ++ int is_initial_ns; ++ ++ /* Do nothing if not using the probes interface. */ ++ if (info->probes_table == NULL) ++ return; ++ ++ /* If anything goes wrong we revert to the original linker ++ interface. */ ++ old_chain = make_cleanup (disable_probes_interface_cleanup, NULL); ++ ++ pc = regcache_read_pc (get_current_regcache ()); ++ pa = solib_event_probe_at (info, pc); ++ if (pa == NULL) ++ goto error; ++ ++ action = solib_event_probe_action (pa); ++ if (action == PROBES_INTERFACE_FAILED) ++ goto error; ++ ++ if (action == DO_NOTHING) ++ return; ++ ++ /* EVALUATE_PROBE_ARGUMENT looks up symbols in the dynamic linker ++ using FIND_PC_SECTION. FIND_PC_SECTION is accelerated by a cache ++ called the section map. The section map is invalidated every ++ time a shared library is loaded or unloaded, and if the inferior ++ is generating a lot of shared library events then the section map ++ will be updated every time SVR4_HANDLE_SOLIB_EVENT is called. ++ We called FIND_PC_SECTION in SVR4_CREATE_SOLIB_EVENT_BREAKPOINTS, ++ so we can guarantee that the dynamic linker's sections are in the ++ section map. We can therefore inhibit section map updates across ++ these calls to EVALUATE_PROBE_ARGUMENT and save a lot of time. */ ++ inhibit_section_map_updates (); ++ usm_chain = make_cleanup (resume_section_map_updates_cleanup, NULL); ++ ++ val = evaluate_probe_argument (pa->probe, 1); ++ if (val == NULL) ++ goto error; ++ ++ debug_base = value_as_address (val); ++ if (debug_base == 0) ++ goto error; ++ ++ /* Always locate the debug struct, in case it moved. */ ++ info->debug_base = 0; ++ if (locate_base (info) == 0) ++ goto error; ++ ++ /* Do not process namespaces other than the initial one. */ ++ if (debug_base != info->debug_base) ++ action = DO_NOTHING; ++ ++ if (action == UPDATE_OR_RELOAD) ++ { ++ val = evaluate_probe_argument (pa->probe, 2); ++ if (val != NULL) ++ lm = value_as_address (val); ++ ++ if (lm == 0) ++ action = FULL_RELOAD; ++ } ++ ++ /* Resume section map updates. */ ++ do_cleanups (usm_chain); ++ ++ if (action == UPDATE_OR_RELOAD) ++ { ++ if (!solist_update_incremental (info, lm)) ++ action = FULL_RELOAD; ++ } ++ ++ if (action == FULL_RELOAD) ++ { ++ if (!solist_update_full (info)) ++ goto error; ++ } ++ ++ discard_cleanups (old_chain); ++ return; ++ ++ error: ++ /* We should never reach here, but if we do we disable the ++ probes interface and revert to the original interface. */ ++ ++ do_cleanups (old_chain); ++} ++ ++/* Helper function for svr4_update_solib_event_breakpoints. */ ++ ++static int ++svr4_update_solib_event_breakpoint (struct breakpoint *b, void *arg) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ struct bp_location *loc; ++ ++ if (b->type != bp_shlib_event) ++ return 0; /* Continue iterating. */ ++ ++ for (loc = b->loc; loc; loc = loc->next) ++ { ++ struct probe_and_action *pa = solib_event_probe_at (info, loc->address); ++ ++ if (pa != NULL) ++ { ++ if (pa->action == DO_NOTHING) ++ b->enable_state = (stop_on_solib_events ++ ? bp_enabled : bp_disabled); ++ ++ return 0; /* Continue iterating. */ ++ } ++ } ++ ++ return 0; /* Continue iterating. */ ++} ++ ++/* Enable or disable optional solib event breakpoints as appropriate. ++ Called whenever stop_on_solib_events is changed. */ ++ ++static void ++svr4_update_solib_event_breakpoints (void) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ ++ if (info->probes_table) ++ iterate_over_breakpoints (svr4_update_solib_event_breakpoint, NULL); ++} ++ ++/* Create and register solib event breakpoints. */ ++ ++static void ++svr4_create_probe_breakpoints (struct gdbarch *gdbarch, ++ VEC (probe_p) **probes) ++{ ++ int i; ++ ++ for (i = 0; i < NUM_PROBES; i++) ++ { ++ enum probe_action action = probe_info[i].action; ++ struct probe *probe; ++ int ix; ++ ++ for (ix = 0; ++ VEC_iterate (probe_p, probes[i], ix, probe); ++ ++ix) ++ { ++ create_solib_event_breakpoint (gdbarch, probe->address); ++ register_solib_event_probe (probe, action); ++ } ++ } ++ ++ svr4_update_solib_event_breakpoints (); ++} ++ ++/* Both the SunOS and the SVR4 dynamic linkers call a marker function ++ before and after mapping and unmapping shared libraries. The sole ++ purpose of this method is to allow debuggers to set a breakpoint so ++ they can track these changes. ++ ++ Some versions of the glibc dynamic linker contain named probes ++ to allow more fine grained stopping. Given the address of the ++ original marker function, this function attempts to find these ++ probes, and if found, sets breakpoints on those instead. If the ++ probes aren't found, a single breakpoint is set on the original ++ marker function. */ ++ ++static void ++svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch, ++ CORE_ADDR address) ++{ ++ struct svr4_info *info = get_svr4_info (); ++ struct obj_section *os; ++ ++ os = find_pc_section (address); ++ if (os != NULL) ++ { ++ int with_prefix; ++ ++ for (with_prefix = 0; with_prefix <= 1; with_prefix++) ++ { ++ VEC (probe_p) *probes[NUM_PROBES]; ++ int all_probes_found = 1; ++ int i; ++ ++ memset (probes, 0, sizeof (probes)); ++ for (i = 0; i < NUM_PROBES; i++) ++ { ++ char name[32] = { '\0' }; ++ ++ /* Fedora 17, RHEL 6.2, and RHEL 6.3 shipped with an ++ early version of the probes code in which the probes' ++ names were prefixed with "rtld_" and the "map_failed" ++ probe did not exist. The locations of the probes are ++ otherwise the same, so we check for probes with ++ prefixed names if probes with unprefixed names are ++ not present. */ ++ ++ if (with_prefix) ++ strncat (name, "rtld_", sizeof (name) - strlen (name) - 1); ++ ++ strncat (name, probe_info[i].name, ++ sizeof (name) - strlen (name) - 1); ++ ++ probes[i] = find_probes_in_objfile (os->objfile, "rtld", name); ++ ++ if (!strcmp (name, "rtld_map_failed")) ++ continue; ++ ++ if (!VEC_length (probe_p, probes[i])) ++ { ++ all_probes_found = 0; ++ break; ++ } ++ } ++ ++ if (all_probes_found) ++ svr4_create_probe_breakpoints (gdbarch, probes); ++ ++ for (i = 0; i < NUM_PROBES; i++) ++ VEC_free (probe_p, probes[i]); ++ ++ if (all_probes_found) ++ return; ++ } ++ } ++ ++ create_solib_event_breakpoint (gdbarch, address); ++} ++ + /* Helper function for gdb_bfd_lookup_symbol. */ + + static int +@@ -1501,6 +2073,8 @@ enable_break (struct svr4_info *info, in + info->interp_text_sect_low = info->interp_text_sect_high = 0; + info->interp_plt_sect_low = info->interp_plt_sect_high = 0; + ++ free_probes_table (info); ++ + /* If we already have a shared library list in the target, and + r_debug contains r_brk, set the breakpoint there - this should + mean r_brk has already been relocated. Assume the dynamic linker +@@ -1532,7 +2106,7 @@ enable_break (struct svr4_info *info, in + That knowledge is encoded in the address, if it's Thumb the low bit + is 1. However, we've stripped that info above and it's not clear + what all the consequences are of passing a non-addr_bits_remove'd +- address to create_solib_event_breakpoint. The call to ++ address to svr4_create_solib_event_breakpoints. The call to + find_pc_section verifies we know about the address and have some + hope of computing the right kind of breakpoint to use (via + symbol info). It does mean that GDB needs to be pointed at a +@@ -1570,7 +2144,7 @@ enable_break (struct svr4_info *info, in + + bfd_section_size (tmp_bfd, interp_sect); + } + +- create_solib_event_breakpoint (target_gdbarch (), sym_addr); ++ svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr); + return 1; + } + } +@@ -1728,7 +2302,8 @@ enable_break (struct svr4_info *info, in + + if (sym_addr != 0) + { +- create_solib_event_breakpoint (target_gdbarch (), load_addr + sym_addr); ++ svr4_create_solib_event_breakpoints (target_gdbarch (), ++ load_addr + sym_addr); + xfree (interp_name); + return 1; + } +@@ -1754,7 +2329,7 @@ enable_break (struct svr4_info *info, in + sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (), + sym_addr, + ¤t_target); +- create_solib_event_breakpoint (target_gdbarch (), sym_addr); ++ svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr); + return 1; + } + } +@@ -1770,7 +2345,7 @@ enable_break (struct svr4_info *info, in + sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (), + sym_addr, + ¤t_target); +- create_solib_event_breakpoint (target_gdbarch (), sym_addr); ++ svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr); + return 1; + } + } +@@ -2266,6 +2841,9 @@ svr4_solib_create_inferior_hook (int fro + + info = get_svr4_info (); + ++ /* Free the probes-based interface's solib list. */ ++ free_solib_list (info); ++ + /* Relocate the main executable if necessary. */ + svr4_relocate_main_executable (); + +@@ -2507,4 +3085,6 @@ _initialize_svr4_solib (void) + svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol; + svr4_so_ops.same = svr4_same; + svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core; ++ svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints; ++ svr4_so_ops.handle_event = svr4_handle_solib_event; + } +Index: gdb-7.6/gdb/breakpoint.c +=================================================================== +--- gdb-7.6.orig/gdb/breakpoint.c 2013-05-19 16:16:20.606087208 +0200 ++++ gdb-7.6/gdb/breakpoint.c 2013-05-19 16:21:55.288805269 +0200 +@@ -5361,25 +5361,6 @@ handle_jit_event (void) + target_terminal_inferior (); + } + +-/* Handle an solib event by calling solib_add. */ +- +-void +-handle_solib_event (void) +-{ +- clear_program_space_solib_cache (current_inferior ()->pspace); +- +- /* Check for any newly added shared libraries if we're supposed to +- be adding them automatically. Switch terminal for any messages +- produced by breakpoint_re_set. */ +- target_terminal_ours_for_output (); +-#ifdef SOLIB_ADD +- SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); +-#else +- solib_add (NULL, 0, ¤t_target, auto_solib_add); +-#endif +- target_terminal_inferior (); +-} +- + /* Prepare WHAT final decision for infrun. */ + + /* Decide what infrun needs to do with this bpstat. */ diff --git a/gdb-dlopen-stap-probe-6of7.patch b/gdb-dlopen-stap-probe-6of7.patch index aca4bfd..500ab34 100644 --- a/gdb-dlopen-stap-probe-6of7.patch +++ b/gdb-dlopen-stap-probe-6of7.patch @@ -1,1501 +1,165 @@ -gdb/ -2012-07-30 Gary Benson +http://sourceware.org/ml/gdb-patches/2013-05/msg00631.html +Subject: [RFA 6/7] Linker-debugger interface tests by Jan - * breakpoint.h (handle_solib_event): Moved function definition - to solib.h, and added a new parameter. - * breakpoint.c (handle_solib_event): Moved function to solib.c - and added a new parameter. - (bpstat_stop_status): Pass new argument to handle_solib_event. - * solib.h (breakpoint.h): New include. - (handle_solib_event): Moved function definition from breakpoint.h - and added a new parameter. - (update_solib_breakpoints): New function definition. - * solib.c (handle_solib_event): Moved function from breakpoint.c - and added a new parameter. - (update_solib_breakpoints): New function. - * solist.h (breakpoint.h): New include. - (target_so_ops): New fields "handle_solib_event" and - "update_breakpoints". - * infrun.c (set_stop_on_solib_events): New function. - (_initialize_infrun): Use the above for "set stop-on-solib-events". - (handle_inferior_event): Pass new argument to handle_solib_event. - * solib-svr4.c (probe.h): New include. - (namespace_table_flatten): New forward declaration. - (lm_info): New fields "lmid" and "in_initial_ns". - (probe_action): New enum. - (probe_info): New struct. - (probe_info): New static variable. - (NUM_PROBES): New definition. - (svr4_info): New fields "using_probes", "probes" and - "namespace_table". - (free_probes): New function. - (free_namespace_table): Likewise. - (svr4_pspace_data_cleanup): Free probes and namespace table. - (svr4_same): Also compare namespaces if using probes. - (lm_addr_check): Only print .dynamic section at wrong address - warning for initial namespace if using probes. - (r_map_from_debug_base): New function. - (solib_svr4_r_map): Call the above. - (svr4_read_so_list): New parameter "prev_lm". - Changed return type from void to int. - Return nonzero on success, zero on error. - (svr4_current_sos_from_debug_base): New function. - (svr4_current_sos): Create result from namespace table if available. - Use svr4_current_sos_from_debug_base to generate list otherwise. - (probe_and_info): New struct. - (solib_event_probe_at): New function. - (solib_event_probe_action): Likewise. - (namespace): New struct. - (hash_namespace): New function. - (equal_namespace): Likewise. - (free_namespace): Likewise. - (namespace_update_full): Likewise. - (namespace_update_incremental): Likewise. - (svr4_handle_solib_event): Likewise. - (namespace_table_flatten_helper): Likewise. - (namespace_table_flatten): Likewise. - (svr4_update_solib_event_breakpoint): Likewise. - (svr4_update_solib_event_breakpoints): Likewise. - (svr4_create_solib_event_breakpoints): Likewise. - (enable_break): Free probes before creating breakpoints. - Use svr4_create_solib_event_breakpoints to create breakpoints. - (svr4_solib_create_inferior_hook): Free the namespace table. - (_initialize_svr4_solib): Initialise svr4_so_ops.handle_solib_event - and svr4_so_ops.update_breakpoints. -gdb/testsuite -2012-07-30 Gary Benson +--IYV9cRr2u6rjcP4B +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +This patch updates the testsuite to cope with some changes resulting +from the probes-based interface, and adds a new test. This patch is +principally the work of Jan Kratochvil. + +--IYV9cRr2u6rjcP4B +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-6-tests-jk.patch" + +2013-05-16 Jan Kratochvil + Gary Benson + + * lib/gdb.exp (build_executable_from_specs): Use gdb_compile_pthread, + gdb_compile_shlib or gdb_compile_shlib_pthreads where appropriate. + * lib/prelink-support.exp (build_executable_own_libs): Allow INTERP + to be set to "no" to indicate that no ld.so copy should be made. * gdb.base/break-interp.exp (solib_bp): New constant. (reach_1): Use the above instead of "_dl_debug_state". (test_attach): Likewise. (test_ld): Likewise. - * gdb.base/break-probes.exp: New file. - * gdb.base/break-probes.c: Likewise. - * gdb.base/break-probes-solib.c: Likewise. - * gdb.base/info-shared.exp: New file. - * gdb.base/info-shared.c: Likewise. - * gdb.base/info-shared-solib1.c: Likewise. - * gdb.base/info-shared-solib2.c: Likewise. - * gdb.base/break-dlmopen.exp: Likewise. - * gdb.base/break-dlmopen.c: Likewise. - * gdb.base/break-dlmopen-solib.c: Likewise. + * gdb.threads/dlopen-libpthread.exp: New file. + * gdb.threads/dlopen-libpthread.c: Likewise. + * gdb.threads/dlopen-libpthread-lib.c: Likewise. + * gdb.base/solib-corrupted.exp: Disable test if GDB is using probes. -Index: gdb-7.5.50.20130215/gdb/breakpoint.h +Index: gdb-7.6/gdb/testsuite/lib/gdb.exp =================================================================== ---- gdb-7.5.50.20130215.orig/gdb/breakpoint.h 2013-02-15 22:37:19.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/breakpoint.h 2013-02-15 22:37:47.185432296 +0100 -@@ -1552,8 +1552,6 @@ extern int user_breakpoint_p (struct bre - /* Attempt to determine architecture of location identified by SAL. */ - extern struct gdbarch *get_sal_arch (struct symtab_and_line sal); +--- gdb-7.6.orig/gdb/testsuite/lib/gdb.exp 2013-05-19 16:05:37.881840646 +0200 ++++ gdb-7.6/gdb/testsuite/lib/gdb.exp 2013-05-19 16:06:10.436822964 +0200 +@@ -4011,22 +4011,6 @@ proc build_executable_from_specs {testna --extern void handle_solib_event (void); + set binfile [standard_output_file $executable] + +- set objects {} +- set i 0 +- foreach {s local_options} $args { +- if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $local_options] != "" } { +- untested $testname +- return -1 +- } +- lappend objects "${binfile}${i}.o" +- incr i +- } +- +- if { [gdb_compile $objects "${binfile}" executable $options] != "" } { +- untested $testname +- return -1 +- } - - extern void breakpoint_free_objfile (struct objfile *objfile); - - extern void breakpoints_relocate (struct objfile *objfile, -Index: gdb-7.5.50.20130215/gdb/breakpoint.c -=================================================================== ---- gdb-7.5.50.20130215.orig/gdb/breakpoint.c 2013-02-15 22:37:30.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/breakpoint.c 2013-02-15 22:37:35.755417584 +0100 -@@ -5250,7 +5250,7 @@ bpstat_stop_status (struct address_space - { - if (bs->breakpoint_at && bs->breakpoint_at->type == bp_shlib_event) - { -- handle_solib_event (); -+ handle_solib_event (bs); - break; - } + set info_options "" + if { [lsearch -exact $options "c++"] >= 0 } { + set info_options "c++" +@@ -4034,6 +4018,42 @@ proc build_executable_from_specs {testna + if [get_compiler_info ${info_options}] { + return -1 } -@@ -5346,25 +5346,6 @@ handle_jit_event (void) - target_terminal_inferior (); - } - --/* Handle an solib event by calling solib_add. */ -- --void --handle_solib_event (void) --{ -- clear_program_space_solib_cache (current_inferior ()->pspace); -- -- /* Check for any newly added shared libraries if we're supposed to -- be adding them automatically. Switch terminal for any messages -- produced by breakpoint_re_set. */ -- target_terminal_ours_for_output (); --#ifdef SOLIB_ADD -- SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); --#else -- solib_add (NULL, 0, ¤t_target, auto_solib_add); --#endif -- target_terminal_inferior (); --} -- - /* Prepare WHAT final decision for infrun. */ - - /* Decide what infrun needs to do with this bpstat. */ -Index: gdb-7.5.50.20130215/gdb/solib.h -=================================================================== ---- gdb-7.5.50.20130215.orig/gdb/solib.h 2013-01-01 07:32:51.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/solib.h 2013-02-15 22:37:35.757417588 +0100 -@@ -20,6 +20,9 @@ - #ifndef SOLIB_H - #define SOLIB_H - -+/* For bpstat. */ -+#include "breakpoint.h" + - /* Forward decl's for prototypes */ - struct so_list; - struct target_ops; -@@ -90,4 +93,15 @@ extern CORE_ADDR gdb_bfd_lookup_symbol_f - void *), - void *data); - -+/* Handle an solib event by calling solib_add. Targets which handle -+ solib events using breakpoints must pass a valid bpstat. Targets -+ which handle solib events using some other mechanism should pass -+ NULL. */ ++ set binfile [standard_output_file $executable] + -+extern void handle_solib_event (bpstat bs); -+ -+/* Enable or disable optional solib event breakpoints as appropriate. */ -+ -+extern void update_solib_breakpoints (void); -+ - #endif /* SOLIB_H */ -Index: gdb-7.5.50.20130215/gdb/solib.c -=================================================================== ---- gdb-7.5.50.20130215.orig/gdb/solib.c 2013-02-15 22:37:04.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/solib.c 2013-02-15 22:37:35.757417588 +0100 -@@ -1221,6 +1221,42 @@ no_shared_libraries (char *ignored, int - objfile_purge_solibs (); - } - -+/* See solib.h. */ -+ -+void -+handle_solib_event (bpstat bs) -+{ -+ struct target_so_ops *ops = solib_ops (target_gdbarch ()); -+ -+ if (ops->handle_solib_event != NULL) -+ ops->handle_solib_event (bs); -+ -+ clear_program_space_solib_cache (current_inferior ()->pspace); -+ -+ /* Check for any newly added shared libraries if we're supposed to -+ be adding them automatically. Switch terminal for any messages -+ produced by breakpoint_re_set. */ -+ target_terminal_ours_for_output (); -+#ifdef SOLIB_ADD -+ SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); -+#else -+ solib_add (NULL, 0, ¤t_target, auto_solib_add); -+#endif -+ target_terminal_inferior (); -+} -+ -+/* See solib.h. */ -+ -+void -+update_solib_breakpoints (void) -+{ -+ struct target_so_ops *ops = solib_ops (target_gdbarch ()); -+ -+ if (ops->update_breakpoints != NULL) -+ ops->update_breakpoints (); -+} -+ -+ - /* Reload shared libraries, but avoid reloading the same symbol file - we already have loaded. */ - -Index: gdb-7.5.50.20130215/gdb/solist.h -=================================================================== ---- gdb-7.5.50.20130215.orig/gdb/solist.h 2013-01-01 07:32:51.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/solist.h 2013-02-15 22:37:35.758417590 +0100 -@@ -22,6 +22,8 @@ - #define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */ - /* For domain_enum domain. */ - #include "symtab.h" -+/* For bpstat. */ -+#include "breakpoint.h" - - /* Forward declaration for target specific link map information. This - struct is opaque to all but the target specific file. */ -@@ -148,6 +150,20 @@ struct target_so_ops - core file (in particular, for readonly sections). */ - int (*keep_data_in_core) (CORE_ADDR vaddr, - unsigned long size); -+ -+ /* Target-specific handling of solib events. For targets which -+ handle solib events using breakpoints a valid bpstat must be -+ passed. Targets which handle solib events using some other -+ mechanism should pass NULL. This pointer can be NULL, in which -+ case no specific handling is necessary for this target. */ -+ void (*handle_solib_event) (bpstat bs); -+ -+ /* Enable or disable optional solib event breakpoints as -+ appropriate. This should be called whenever -+ stop_on_solib_events is changed. This pointer can be -+ NULL, in which case no enabling or disabling is necessary -+ for this target. */ -+ void (*update_breakpoints) (void); - }; - - /* Free the memory associated with a (so_list *). */ -Index: gdb-7.5.50.20130215/gdb/infrun.c -=================================================================== ---- gdb-7.5.50.20130215.orig/gdb/infrun.c 2013-02-15 22:37:04.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/infrun.c 2013-02-15 22:37:35.760417594 +0100 -@@ -369,6 +369,16 @@ static struct symbol *step_start_functio - /* Nonzero if we want to give control to the user when we're notified - of shared library events by the dynamic linker. */ - int stop_on_solib_events; -+ -+/* Enable or disable optional shared library event breakpoints -+ as appropriate when the above flag is changed. */ -+ -+static void -+set_stop_on_solib_events (char *args, int from_tty, struct cmd_list_element *c) -+{ -+ update_solib_breakpoints (); -+} -+ - static void - show_stop_on_solib_events (struct ui_file *file, int from_tty, - struct cmd_list_element *c, const char *value) -@@ -3346,7 +3356,7 @@ handle_inferior_event (struct execution_ - context_switch (ecs->ptid); - regcache = get_thread_regcache (ecs->ptid); - -- handle_solib_event (); -+ handle_solib_event (NULL); - - ecs->event_thread->control.stop_bpstat - = bpstat_stop_status (get_regcache_aspace (regcache), -@@ -7334,7 +7344,7 @@ Show stopping for shared library events. - If nonzero, gdb will give control to the user when the dynamic linker\n\ - notifies gdb of shared library events. The most common event of interest\n\ - to the user would be loading/unloading of a new library."), -- NULL, -+ set_stop_on_solib_events, - show_stop_on_solib_events, - &setlist, &showlist); - -Index: gdb-7.5.50.20130215/gdb/solib-svr4.c -=================================================================== ---- gdb-7.5.50.20130215.orig/gdb/solib-svr4.c 2013-02-15 22:37:30.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/solib-svr4.c 2013-02-15 22:37:35.761417596 +0100 -@@ -46,10 +46,12 @@ - #include "auxv.h" - #include "exceptions.h" - #include "gdb_bfd.h" -+#include "probe.h" - - 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); -+static struct so_list *namespace_table_flatten (htab_t namespace_table); - - /* Link map info to include in an allocated so_list entry. */ - -@@ -70,6 +72,16 @@ struct lm_info - - /* Values read in from inferior's fields of the same name. */ - CORE_ADDR l_ld, l_next, l_prev, l_name; -+ -+ /* Numeric link-map ID of the namespace this object is loaded -+ into. This value is only valid when using the probes-based -+ interface. */ -+ LONGEST lmid; -+ -+ /* Nonzero if the namespace list this object is loaded into is the -+ application's initial namespace (LM_ID_BASE). This value is -+ only valid when using the probes-based interface. */ -+ unsigned int in_initial_ns : 1; - }; - - /* On SVR4 systems, a list of symbols in the dynamic linker where -@@ -106,6 +118,53 @@ static const char * const main_name_lis - NULL - }; - -+/* What to do with the namespace table when a probe stop occurs. */ -+ -+enum probe_action -+ { -+ /* Something went seriously wrong. Stop using probes and -+ revert to using the older interface. */ -+ NAMESPACE_TABLE_INVALIDATE, -+ -+ /* No action is required. This namespace is still valid. */ -+ NAMESPACE_NO_ACTION, -+ -+ /* This namespace should be reloaded entirely. */ -+ NAMESPACE_RELOAD, -+ -+ /* Attempt to incrementally update this namespace. If the -+ update fails or is not possible, fall back to reloading -+ the namespace in full. */ -+ NAMESPACE_UPDATE_OR_RELOAD, -+ }; -+ -+/* A probe's name and its associated action. */ -+ -+struct probe_info -+{ -+ /* The name of the probe. */ -+ const char *name; -+ -+ /* What to do with the namespace table when a probe stop occurs. */ -+ enum probe_action action; -+}; -+ -+/* A list of named probes and their associated actions. If all -+ probes are present in the dynamic linker then the probes-based -+ interface will be used. */ -+ -+static const struct probe_info probe_info[] = -+{ -+ { "init_start", NAMESPACE_NO_ACTION }, -+ { "init_complete", NAMESPACE_RELOAD }, -+ { "map_start", NAMESPACE_NO_ACTION }, -+ { "reloc_complete", NAMESPACE_UPDATE_OR_RELOAD }, -+ { "unmap_start", NAMESPACE_NO_ACTION }, -+ { "unmap_complete", NAMESPACE_RELOAD }, -+}; -+ -+#define NUM_PROBES ARRAY_SIZE (probe_info) -+ - /* Per pspace SVR4 specific data. */ - - struct svr4_info -@@ -128,17 +187,58 @@ struct svr4_info - CORE_ADDR interp_text_sect_high; - CORE_ADDR interp_plt_sect_low; - CORE_ADDR interp_plt_sect_high; -+ -+ /* Nonzero if we are using the probes-based interface. */ -+ unsigned int using_probes : 1; -+ -+ /* Named probes in the dynamic linker. */ -+ VEC (probe_p) *probes[NUM_PROBES]; -+ -+ /* Table of dynamic linker namespaces, used by the probes-based -+ interface. */ -+ htab_t namespace_table; - }; - - /* Per-program-space data key. */ - static const struct program_space_data *solib_svr4_pspace_data; - -+/* Free any allocated probe vectors. */ -+ -+static void -+free_probes (struct svr4_info *info) -+{ -+ int i; -+ -+ for (i = 0; i < NUM_PROBES; i++) -+ VEC_free (probe_p, info->probes[i]); -+ -+ memset (info->probes, 0, sizeof (info->probes)); -+} -+ -+/* Free the namespace table. */ -+ -+static void -+free_namespace_table (struct svr4_info *info) -+{ -+ if (info->namespace_table == NULL) -+ return; -+ -+ htab_delete (info->namespace_table); -+ info->namespace_table = NULL; -+} -+ - static void - svr4_pspace_data_cleanup (struct program_space *pspace, void *arg) - { - struct svr4_info *info; - - info = program_space_data (pspace, solib_svr4_pspace_data); -+ if (info == NULL) -+ return; -+ -+ free_probes (info); -+ free_namespace_table (info); -+ - xfree (info); - } - -@@ -187,10 +287,21 @@ svr4_same_1 (const char *gdb_so_name, co - return 0; - } - -+/* Return non-zero if GDB and INFERIOR represent the same shared -+ library. */ -+ - static int - svr4_same (struct so_list *gdb, struct so_list *inferior) - { -- return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name)); -+ struct svr4_info *info = get_svr4_info (); -+ -+ if (info->using_probes) -+ { -+ if (gdb->lm_info->lmid != inferior->lm_info->lmid) -+ return 0; ++ set func gdb_compile ++ set func_index [lsearch -regexp $options {^(pthreads|shlib|shlib_pthreads)$}] ++ if {$func_index != -1} { ++ set func "${func}_[lindex $options $func_index]" + } + -+ return svr4_same_1 (gdb->so_original_name, inferior->so_original_name); - } - - static struct lm_info * -@@ -321,18 +432,26 @@ lm_addr_check (struct so_list *so, bfd * - } - else - { -- /* There is no way to verify the library file matches. prelink -- can during prelinking of an unprelinked file (or unprelinking -- of a prelinked file) shift the DYNAMIC segment by arbitrary -- offset without any page size alignment. There is no way to -- find out the ELF header and/or Program Headers for a limited -- verification if it they match. One could do a verification -- of the DYNAMIC segment. Still the found address is the best -- one GDB could find. */ -- -- warning (_(".dynamic section for \"%s\" " -- "is not at the expected address " -- "(wrong library or version mismatch?)"), so->so_name); -+ struct svr4_info *info = get_svr4_info (); -+ -+ if (!info->using_probes || so->lm_info->in_initial_ns) -+ { -+ /* There is no way to verify the library file -+ matches. prelink can during prelinking of an -+ unprelinked file (or unprelinking of a prelinked -+ file) shift the DYNAMIC segment by arbitrary -+ offset without any page size alignment. There is -+ no way to find out the ELF header and/or Program -+ Headers for a limited verification if it they -+ match. One could do a verification of the -+ DYNAMIC segment. Still the found address is the -+ best one GDB could find. */ -+ -+ warning (_(".dynamic section for \"%s\" " -+ "is not at the expected address " -+ "(wrong library or version mismatch?)"), -+ so->so_name); -+ } - } - } - -@@ -774,16 +893,10 @@ locate_base (struct svr4_info *info) - return info->debug_base; - } - --/* Find the first element in the inferior's dynamic link map, and -- return its address in the inferior. Return zero if the address -- could not be determined. -- -- FIXME: Perhaps we should validate the info somehow, perhaps by -- checking r_version for a known version number, or r_state for -- RT_CONSISTENT. */ -+/* Read the r_map field from the supplied r_debug structure. */ - - static CORE_ADDR --solib_svr4_r_map (struct svr4_info *info) -+r_map_from_debug_base (CORE_ADDR debug_base) - { - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; -@@ -792,13 +905,27 @@ solib_svr4_r_map (struct svr4_info *info - - TRY_CATCH (ex, RETURN_MASK_ERROR) - { -- addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset, -+ addr = read_memory_typed_address (debug_base + lmo->r_map_offset, - ptr_type); - } - exception_print (gdb_stderr, ex); - return addr; - } - -+/* Find the first element in the inferior's dynamic link map, and -+ return its address in the inferior. Return zero if the address -+ could not be determined. -+ -+ FIXME: Perhaps we should validate the info somehow, perhaps by -+ checking r_version for a known version number, or r_state for -+ RT_CONSISTENT. */ -+ -+static CORE_ADDR -+solib_svr4_r_map (struct svr4_info *info) -+{ -+ return r_map_from_debug_base (info->debug_base); -+} -+ - /* Find r_brk from the inferior's debug base. */ - - static CORE_ADDR -@@ -1161,15 +1288,17 @@ svr4_default_sos (void) - return new; - } - --/* Read the whole inferior libraries chain starting at address LM. Add the -- entries to the tail referenced by LINK_PTR_PTR. Ignore the first entry if -- IGNORE_FIRST and set global MAIN_LM_ADDR according to it. */ -+/* Read the whole inferior libraries chain starting at address LM. -+ Expect the first entry in the chain's previous entry to be PREV_LM. -+ Add the entries to the tail referenced by LINK_PTR_PTR. Ignore the -+ first entry if IGNORE_FIRST and set global MAIN_LM_ADDR according -+ to it. Returns nonzero upon success. */ - --static void --svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr, -- int ignore_first) -+static int -+svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, -+ struct so_list ***link_ptr_ptr, int ignore_first) - { -- CORE_ADDR prev_lm = 0, next_lm; -+ CORE_ADDR next_lm; - - for (; lm != 0; prev_lm = lm, lm = next_lm) - { -@@ -1185,7 +1314,7 @@ svr4_read_so_list (CORE_ADDR lm, struct - if (new->lm_info == NULL) - { - do_cleanups (old_chain); -- break; -+ return 0; - } - - next_lm = new->lm_info->l_next; -@@ -1196,7 +1325,7 @@ svr4_read_so_list (CORE_ADDR lm, struct - paddress (target_gdbarch (), prev_lm), - paddress (target_gdbarch (), new->lm_info->l_prev)); - do_cleanups (old_chain); -- break; -+ return 0; - } - - /* For SVR4 versions, the first entry in the link map is for the -@@ -1291,20 +1420,61 @@ svr4_read_so_list (CORE_ADDR lm, struct - **link_ptr_ptr = new; - *link_ptr_ptr = &new->next; - } -+ -+ return 1; - } - --/* Implement the "current_sos" target_so_ops method. */ -+/* Read the list of loaded libraries from the dynamic linker's base -+ structure. */ - - static struct so_list * --svr4_current_sos (void) -+svr4_current_sos_from_debug_base (void) - { -+ struct svr4_info *info = get_svr4_info (); - CORE_ADDR lm; - struct so_list *head = NULL; - struct so_list **link_ptr = &head; -- struct svr4_info *info; - struct cleanup *back_to; - int ignore_first; -+ -+ gdb_assert (info->debug_base); -+ -+ /* Assume that everything is a library if the dynamic loader was loaded -+ late by a static executable. */ -+ if (exec_bfd && bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL) -+ ignore_first = 0; -+ else -+ ignore_first = 1; -+ -+ back_to = make_cleanup (svr4_free_library_list, &head); -+ -+ /* Walk the inferior's link map list, and build our list of -+ `struct so_list' nodes. */ -+ lm = solib_svr4_r_map (info); -+ if (lm) -+ svr4_read_so_list (lm, 0, &link_ptr, ignore_first); -+ -+ /* On Solaris, the dynamic linker is not in the normal list of -+ shared objects, so make sure we pick it up too. Having -+ symbol information for the dynamic linker is quite crucial -+ for skipping dynamic linker resolver code. */ -+ lm = solib_svr4_r_ldsomap (info); -+ if (lm) -+ svr4_read_so_list (lm, 0, &link_ptr, 0); -+ -+ discard_cleanups (back_to); -+ -+ return head; -+} -+ -+/* Implement the "current_sos" target_so_ops method. */ -+ -+static struct so_list * -+svr4_current_sos (void) -+{ -+ struct svr4_info *info; - struct svr4_library_list library_list; -+ struct so_list *result; - - /* Fall back to manual examination of the target if the packet is not - supported or gdbserver failed to find DT_DEBUG. gdb.server/solib-list.exp -@@ -1327,6 +1497,10 @@ svr4_current_sos (void) - - info = get_svr4_info (); - -+ /* If we have a namespace table then return a flattened copy. */ -+ if (info->namespace_table != NULL) -+ return namespace_table_flatten (info->namespace_table); -+ - /* Always locate the debug struct, in case it has moved. */ - info->debug_base = 0; - locate_base (info); -@@ -1336,35 +1510,12 @@ svr4_current_sos (void) - if (! info->debug_base) - return svr4_default_sos (); - -- /* Assume that everything is a library if the dynamic loader was loaded -- late by a static executable. */ -- if (exec_bfd && bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL) -- ignore_first = 0; -- else -- ignore_first = 1; -- -- back_to = make_cleanup (svr4_free_library_list, &head); -- -- /* Walk the inferior's link map list, and build our list of -- `struct so_list' nodes. */ -- lm = solib_svr4_r_map (info); -- if (lm) -- svr4_read_so_list (lm, &link_ptr, ignore_first); -- -- /* On Solaris, the dynamic linker is not in the normal list of -- shared objects, so make sure we pick it up too. Having -- symbol information for the dynamic linker is quite crucial -- for skipping dynamic linker resolver code. */ -- lm = solib_svr4_r_ldsomap (info); -- if (lm) -- svr4_read_so_list (lm, &link_ptr, 0); -- -- discard_cleanups (back_to); -+ result = svr4_current_sos_from_debug_base (); - -- if (head == NULL) -+ if (result == NULL) - return svr4_default_sos (); - -- return head; -+ return result; - } - - /* Get the address of the link_map for a given OBJFILE. */ -@@ -1449,6 +1600,498 @@ exec_entry_point (struct bfd *abfd, stru - return gdbarch_addr_bits_remove (target_gdbarch (), addr); - } - -+/* A probe and its associated information structure. */ -+ -+struct probe_and_info -+{ -+ /* The probe. */ -+ struct probe *probe; -+ -+ /* The probe_info from which the probe was created. */ -+ const struct probe_info *info; -+}; -+ -+/* Get the solib event probe at the specified location, and the -+ probe_info the probe was created with. Fills in RESULT and -+ returns nonzero if a solib event probe was found at the -+ specified location. Returns zero if no solib event probe -+ was found. */ -+ -+static int -+solib_event_probe_at (struct svr4_info *info, struct bp_location *loc, -+ struct probe_and_info *result) -+{ -+ int i; -+ -+ for (i = 0; i < NUM_PROBES; i++) -+ { -+ struct probe *probe; -+ int ix; -+ -+ for (ix = 0; VEC_iterate (probe_p, info->probes[i], ix, probe); ++ix) -+ { -+ if (loc->pspace == current_program_space -+ && loc->address == probe->address) -+ { -+ result->info = &probe_info[i]; -+ result->probe = probe; -+ -+ return 1; ++ # gdb_compile_shlib and gdb_compile_shlib_pthreads do not use the 3rd ++ # parameter. They also requires $sources while gdb_compile and ++ # gdb_compile_pthreads require $objects. Moreover they ignore any options. ++ if [string match gdb_compile_shlib* $func] { ++ set sources_path {} ++ foreach {s local_options} $args { ++ lappend sources_path "${srcdir}/${subdir}/${s}" ++ } ++ set ret [$func $sources_path "${binfile}" $options] ++ } else { ++ set objects {} ++ set i 0 ++ foreach {s local_options} $args { ++ if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $local_options] != "" } { ++ untested $testname ++ return -1 + } ++ lappend objects "${binfile}${i}.o" ++ incr i + } ++ set ret [$func $objects "${binfile}" executable $options] ++ } ++ if { $ret != "" } { ++ untested $testname ++ return -1 + } + -+ return 0; -+} -+ -+/* Decide what action to take when the specified solib event probe is -+ hit. */ -+ -+static enum probe_action -+solib_event_probe_action (struct probe_and_info *pi) -+{ -+ enum probe_action action; -+ unsigned probe_argc; -+ -+ action = pi->info->action; -+ if (action == NAMESPACE_NO_ACTION || action == NAMESPACE_TABLE_INVALIDATE) -+ return action; -+ -+ gdb_assert (action == NAMESPACE_RELOAD -+ || action == NAMESPACE_UPDATE_OR_RELOAD); -+ -+ /* Check that an appropriate number of arguments has been supplied. -+ We expect: -+ arg0: Lmid_t lmid (mandatory) -+ arg1: struct r_debug *debug_base (mandatory) -+ arg2: struct link_map *new (optional, for incremental updates) */ -+ probe_argc = get_probe_argument_count (pi->probe); -+ if (probe_argc == 2) -+ action = NAMESPACE_RELOAD; -+ else if (probe_argc < 2) -+ action = NAMESPACE_TABLE_INVALIDATE; -+ -+ return action; -+} -+ -+/* A namespace in the dynamic linker. */ -+ -+struct namespace -+{ -+ /* Numeric link-map ID of the namespace. */ -+ LONGEST lmid; -+ -+ /* List of objects loaded into the namespace. */ -+ struct so_list *solist; -+}; -+ -+/* Returns a hash code for the namespace referenced by p. */ -+ -+static hashval_t -+hash_namespace (const void *p) -+{ -+ const struct namespace *ns = p; -+ -+ return (hashval_t) ns->lmid; -+} -+ -+/* Returns non-zero if the namespaces referenced by p1 and p2 -+ are equal. */ -+ -+static int -+equal_namespace (const void *p1, const void *p2) -+{ -+ const struct namespace *ns1 = p1; -+ const struct namespace *ns2 = p2; -+ -+ return ns1->lmid == ns2->lmid; -+} -+ -+/* Free a namespace. */ -+ -+static void -+free_namespace (void *p) -+{ -+ struct namespace *ns = p; -+ -+ svr4_free_library_list (ns->solist); -+ xfree (ns); -+} -+ -+/* Populate this namespace by reading the entire list of shared -+ objects from the inferior. Returns nonzero on success. */ -+ -+static int -+namespace_update_full (struct svr4_info *info, LONGEST lmid, -+ CORE_ADDR debug_base, int is_initial_ns) -+{ -+ struct so_list *result = NULL, *so; -+ struct namespace lookup, *ns; -+ void **slot; -+ -+ /* Read the list of shared objects from the inferior. The -+ initial namespace requires extra processing and is handled -+ separately. */ -+ if (is_initial_ns) -+ { -+ result = svr4_current_sos_from_debug_base (); -+ } -+ else -+ { -+ CORE_ADDR lm = r_map_from_debug_base (debug_base); -+ struct so_list **link_ptr = &result; -+ -+ if (!svr4_read_so_list (lm, 0, &link_ptr, 0)) -+ return 0; -+ } -+ -+ /* If the namespace is empty then delete it from the table. */ -+ if (result == NULL) -+ { -+ if (info->namespace_table != NULL) -+ { -+ lookup.lmid = lmid; -+ htab_remove_elt (info->namespace_table, &lookup); -+ } -+ -+ return 1; -+ } -+ -+ /* Fill in the link-map IDs and initial namespace flags. */ -+ for (so = result; so; so = so->next) -+ { -+ so->lm_info->lmid = lmid; -+ so->lm_info->in_initial_ns = is_initial_ns; -+ } -+ -+ /* Create the namespace table, if necessary. */ -+ if (info->namespace_table == NULL) -+ { -+ info->namespace_table = htab_create_alloc (1, hash_namespace, -+ equal_namespace, -+ free_namespace, -+ xcalloc, xfree); -+ } -+ -+ /* Update the namespace table with our new list. */ -+ lookup.lmid = lmid; -+ slot = htab_find_slot (info->namespace_table, &lookup, INSERT); -+ if (*slot == HTAB_EMPTY_ENTRY) -+ { -+ ns = XCNEW (struct namespace); -+ ns->lmid = lmid; -+ *slot = ns; -+ } -+ else -+ { -+ ns = *slot; -+ svr4_free_library_list (ns->solist); -+ } -+ ns->solist = result; -+ -+ return 1; -+} -+ -+/* Update this namespace starting from the link-map entry passed by -+ the linker in the probe's third argument. Returns nonzero if the -+ list was successfully updated, or zero to indicate failure. */ -+ -+static int -+namespace_update_incremental (struct svr4_info *info, LONGEST lmid, -+ CORE_ADDR lm, int is_initial_ns) -+{ -+ struct namespace lookup, *ns; -+ struct so_list *tail, **link, *so; -+ struct value *val; -+ -+ /* Find our namespace in the table. */ -+ if (info->namespace_table == NULL) -+ return 0; -+ -+ lookup.lmid = lmid; -+ ns = htab_find (info->namespace_table, &lookup); -+ if (ns == NULL) -+ return 0; -+ -+ /* Walk to the end of the list. */ -+ tail = ns->solist; -+ if (tail == NULL) -+ return 0; -+ -+ while (tail->next) -+ tail = tail->next; -+ link = &tail->next; -+ -+ /* Read the new objects. */ -+ if (!svr4_read_so_list (lm, tail->lm_info->lm_addr, &link, 0)) -+ return 0; -+ -+ /* Fill in the link-map IDs and initial namespace flags. */ -+ for (so = tail; so; so = so->next) -+ { -+ so->lm_info->lmid = lmid; -+ so->lm_info->in_initial_ns = is_initial_ns; -+ } -+ -+ return 1; -+} -+ -+/* Update the namespace table as appropriate when using the -+ probes-based linker interface. Do nothing if using the -+ standard interface. */ -+ -+static void -+svr4_handle_solib_event (bpstat bs) -+{ -+ struct svr4_info *info = get_svr4_info (); -+ struct probe_and_info buf, *pi = &buf; -+ enum probe_action action; -+ struct value *val; -+ LONGEST lmid; -+ CORE_ADDR debug_base, lm = 0; -+ int is_initial_ns; -+ -+ /* It is possible that this function will be called incorrectly -+ by the handle_solib_event in handle_inferior_event if GDB goes -+ fully multi-target. */ -+ gdb_assert (bs != NULL); -+ -+ if (!info->using_probes) -+ return; -+ -+ if (!solib_event_probe_at (info, bs->bp_location_at, pi)) -+ goto error; -+ -+ action = solib_event_probe_action (pi); -+ if (action == NAMESPACE_TABLE_INVALIDATE) -+ goto error; -+ -+ if (action == NAMESPACE_NO_ACTION) -+ return; -+ -+ val = evaluate_probe_argument (pi->probe, 0); -+ if (val == NULL) -+ goto error; -+ -+ lmid = value_as_long (val); -+ -+ val = evaluate_probe_argument (pi->probe, 1); -+ if (val == NULL) -+ goto error; -+ -+ debug_base = value_as_address (val); -+ if (debug_base == 0) -+ goto error; -+ -+ /* Always locate the debug struct, in case it moved. */ -+ info->debug_base = 0; -+ if (locate_base (info) == 0) -+ goto error; -+ -+ is_initial_ns = (debug_base == info->debug_base); -+ -+ if (action == NAMESPACE_UPDATE_OR_RELOAD) -+ { -+ val = evaluate_probe_argument (pi->probe, 2); -+ if (val != NULL) -+ lm = value_as_address (val); -+ -+ if (lm == 0) -+ action = NAMESPACE_RELOAD; -+ } -+ -+ if (action == NAMESPACE_UPDATE_OR_RELOAD) -+ { -+ if (namespace_update_incremental (info, lmid, lm, is_initial_ns)) -+ return; -+ -+ action = NAMESPACE_RELOAD; -+ } -+ -+ gdb_assert (action == NAMESPACE_RELOAD); -+ -+ if (namespace_update_full (info, lmid, debug_base, is_initial_ns)) -+ return; -+ -+ error: -+ -+ /* We should never reach here, but if we do we disable the -+ probes interface and revert to the original interface. -+ We don't reset the breakpoints as the ones we've set up -+ are adequate. */ -+ warning (_("Probes-based dynamic linker interface failed.\n" -+ "Reverting to original interface.\n")); -+ -+ free_namespace_table (info); -+ free_probes (info); -+ info->using_probes = 0; -+} -+ -+/* Helper function for namespace_table_flatten. */ -+ -+static int -+namespace_table_flatten_helper (void **slot, void *arg) -+{ -+ struct namespace *ns = (struct namespace *) *slot; -+ struct so_list *src = ns->solist; -+ struct so_list **link = (struct so_list **) arg; -+ -+ while (*link) -+ link = &(*link)->next; -+ -+ while (src != NULL) -+ { -+ struct so_list *dst; -+ -+ dst = xmalloc (sizeof (struct so_list)); -+ memcpy (dst, src, sizeof (struct so_list)); -+ -+ dst->lm_info = xmalloc (sizeof (struct lm_info)); -+ memcpy (dst->lm_info, src->lm_info, sizeof (struct lm_info)); -+ -+ *link = dst; -+ link = &dst->next; -+ -+ src = src->next; -+ } -+ -+ *link = NULL; -+ -+ return 1; /* Continue traversal. */ -+} -+ -+/* Flatten the namespace table into a single list. */ -+ -+static struct so_list * -+namespace_table_flatten (htab_t namespace_table) -+{ -+ struct so_list *dst = NULL; -+ -+ htab_traverse (namespace_table, namespace_table_flatten_helper, &dst); -+ -+ return dst; -+} -+ -+/* Helper function for svr4_update_solib_event_breakpoints. */ -+ -+static int -+svr4_update_solib_event_breakpoint (struct breakpoint *b, void *arg) -+{ -+ struct svr4_info *info = get_svr4_info (); -+ struct bp_location *loc; -+ -+ if (b->type != bp_shlib_event) -+ return 0; /* Continue iterating. */ -+ -+ for (loc = b->loc; loc; loc = loc->next) -+ { -+ struct probe_and_info buf, *pi = &buf; -+ -+ if (solib_event_probe_at (info, loc, pi)) -+ { -+ if (pi->info->action == NAMESPACE_NO_ACTION) -+ b->enable_state = (stop_on_solib_events -+ ? bp_enabled : bp_disabled); -+ -+ return 0; /* Continue iterating. */ -+ } -+ } -+ -+ return 0; /* Continue iterating. */ -+} -+ -+/* Enable or disable optional solib event breakpoints as appropriate. -+ Called whenever stop_on_solib_events is changed. */ -+ -+static void -+svr4_update_solib_event_breakpoints (void) -+{ -+ struct svr4_info *info = get_svr4_info (); -+ -+ if (info->using_probes) -+ iterate_over_breakpoints (svr4_update_solib_event_breakpoint, NULL); -+} -+ -+/* Both the SunOS and the SVR4 dynamic linkers call a marker function -+ before and after mapping and unmapping shared libraries. The sole -+ purpose of this method is to allow debuggers to set a breakpoint so -+ they can track these changes. -+ -+ Some versions of the glibc dynamic linker contain named probes -+ to allow more fine grained stopping. Given the address of the -+ original marker function, this function attempts to find these -+ probes, and if found, sets breakpoints on those instead. If the -+ probes aren't found, a single breakpoint is set on the original -+ marker function. */ -+ -+static void -+svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch, -+ CORE_ADDR address) -+{ -+ struct svr4_info *info = get_svr4_info (); -+ struct obj_section *os; -+ -+ os = find_pc_section (address); -+ if (os != NULL) -+ { -+ int with_prefix; -+ -+ for (with_prefix = 0; with_prefix <= 1; with_prefix++) -+ { -+ int all_probes_found = 1; -+ int i; -+ -+ for (i = 0; i < NUM_PROBES; i++) -+ { -+ char name[32] = { '\0' }; -+ -+ /* Fedora 17, RHEL 6.2, and RHEL 6.3 shipped with an -+ early version of the probes code in which the probes' -+ names were prefixed with "rtld_". The locations and -+ arguments of the probes are otherwise the same, so we -+ check for the prefixed version if the unprefixed -+ probes are not found. */ -+ -+ if (with_prefix) -+ strncat (name, "rtld_", sizeof (name)); -+ -+ strncat (name, probe_info[i].name, sizeof (name) - sizeof ("rtld_")); -+ -+ info->probes[i] = find_probes_in_objfile (os->objfile, "rtld", -+ name); -+ -+ if (!VEC_length (probe_p, info->probes[i])) -+ { -+ free_probes (info); -+ all_probes_found = 0; -+ break; -+ } -+ } -+ -+ if (all_probes_found) -+ { -+ info->using_probes = 1; -+ -+ for (i = 0; i < NUM_PROBES; i++) -+ { -+ struct probe *probe; -+ int ix; -+ -+ for (ix = 0; -+ VEC_iterate (probe_p, info->probes[i], ix, probe); -+ ++ix) -+ create_solib_event_breakpoint (gdbarch, probe->address); -+ } -+ -+ svr4_update_solib_event_breakpoints (); -+ return; -+ } -+ } -+ } -+ -+ create_solib_event_breakpoint (gdbarch, address); -+} -+ - /* Helper function for gdb_bfd_lookup_symbol. */ - - static int -@@ -1501,6 +2144,9 @@ enable_break (struct svr4_info *info, in - info->interp_text_sect_low = info->interp_text_sect_high = 0; - info->interp_plt_sect_low = info->interp_plt_sect_high = 0; - -+ free_probes (info); -+ info->using_probes = 0; -+ - /* If we already have a shared library list in the target, and - r_debug contains r_brk, set the breakpoint there - this should - mean r_brk has already been relocated. Assume the dynamic linker -@@ -1532,7 +2178,7 @@ enable_break (struct svr4_info *info, in - That knowledge is encoded in the address, if it's Thumb the low bit - is 1. However, we've stripped that info above and it's not clear - what all the consequences are of passing a non-addr_bits_remove'd -- address to create_solib_event_breakpoint. The call to -+ address to svr4_create_solib_event_breakpoints. The call to - find_pc_section verifies we know about the address and have some - hope of computing the right kind of breakpoint to use (via - symbol info). It does mean that GDB needs to be pointed at a -@@ -1570,7 +2216,7 @@ enable_break (struct svr4_info *info, in - + bfd_section_size (tmp_bfd, interp_sect); - } - -- create_solib_event_breakpoint (target_gdbarch (), sym_addr); -+ svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr); - return 1; - } - } -@@ -1728,7 +2374,8 @@ enable_break (struct svr4_info *info, in - - if (sym_addr != 0) - { -- create_solib_event_breakpoint (target_gdbarch (), load_addr + sym_addr); -+ svr4_create_solib_event_breakpoints (target_gdbarch (), -+ load_addr + sym_addr); - xfree (interp_name); - return 1; - } -@@ -1754,7 +2401,7 @@ enable_break (struct svr4_info *info, in - sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (), - sym_addr, - ¤t_target); -- create_solib_event_breakpoint (target_gdbarch (), sym_addr); -+ svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr); - return 1; - } - } -@@ -1770,7 +2417,7 @@ enable_break (struct svr4_info *info, in - sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (), - sym_addr, - ¤t_target); -- create_solib_event_breakpoint (target_gdbarch (), sym_addr); -+ svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr); - return 1; - } - } -@@ -2266,6 +2913,9 @@ svr4_solib_create_inferior_hook (int fro - - info = get_svr4_info (); - -+ /* Free the probes-based interface's namespace table. */ -+ free_namespace_table (info); -+ - /* Relocate the main executable if necessary. */ - svr4_relocate_main_executable (); - -@@ -2507,4 +3157,6 @@ _initialize_svr4_solib (void) - svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol; - svr4_so_ops.same = svr4_same; - svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core; -+ svr4_so_ops.handle_solib_event = svr4_handle_solib_event; -+ svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints; + return 0 } -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-dlmopen-solib.c + +Index: gdb-7.6/gdb/testsuite/lib/prelink-support.exp =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-dlmopen-solib.c 2013-02-15 22:37:35.761417596 +0100 -@@ -0,0 +1,24 @@ -+/* Copyright 2012 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 -+foo (int n) -+{ -+ printf ("foo %d\n", n); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-dlmopen.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-dlmopen.c 2013-02-15 22:37:35.762417598 +0100 -@@ -0,0 +1,58 @@ -+/* Copyright 2012 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 . */ -+ -+#define _GNU_SOURCE -+#include -+ -+void -+stop () -+{ -+} -+ -+int -+main () -+{ -+ void *handle1, *handle2, *handle3; -+ void (*func)(int); -+ -+ handle1 = dlmopen (LM_ID_NEWLM, SHLIB_NAME, RTLD_LAZY); -+ stop (); -+ -+ func = (void (*)(int)) dlsym (handle1, "foo"); -+ func (1); -+ -+ handle2 = dlmopen (LM_ID_NEWLM, SHLIB_NAME, RTLD_LAZY); -+ stop (); -+ -+ func = (void (*)(int)) dlsym (handle2, "foo"); -+ func (2); -+ -+ handle3 = dlopen (SHLIB_NAME, RTLD_LAZY); -+ stop (); -+ -+ func = (void (*)(int)) dlsym (handle3, "foo"); -+ func (3); -+ -+ dlclose (handle1); -+ stop (); -+ -+ dlclose (handle2); -+ stop (); -+ -+ dlclose (handle3); -+ stop (); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-dlmopen.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-dlmopen.exp 2013-02-15 22:37:35.762417598 +0100 -@@ -0,0 +1,125 @@ -+# Copyright 2012 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 . -+ -+if { [skip_shlib_tests] || [is_remote target] } { -+ return 0 -+} -+ -+standard_testfile -+ -+set libname $testfile-solib -+set srcfile_lib $srcdir/$subdir/$libname.c -+set binfile_lib [standard_output_file $libname.so] -+ -+set normal_bp "_dl_debug_state" -+set probes_bp "dl_main" -+ -+if { [gdb_compile_shlib $srcfile_lib $binfile_lib \ -+ [list additional_flags=-fPIC]] != "" } { -+ untested "Could not compile $binfile_lib." -+ return -1 -+} -+ -+if { [prepare_for_testing $testfile.exp $testfile $srcfile \ -+ [list additional_flags=-DSHLIB_NAME\=\"$binfile_lib\" libs=-ldl]] } { -+ return -1 -+} -+ -+# Run "info sharedlibrary" and check our library is shown the expected -+# number of times. -+proc check_info_shared { test expect } { -+ global libname -+ global gdb_prompt -+ -+ set actual 0 -+ -+ gdb_test_multiple "info sharedlibrary" $test { -+ -re $libname { -+ incr actual 1 -+ exp_continue -+ } -+ -re "\r\n$gdb_prompt $" { -+ if { $actual == $expect } { -+ pass $test -+ } else { -+ fail $test -+ } +--- gdb-7.6.orig/gdb/testsuite/lib/prelink-support.exp 2013-05-19 16:05:37.881840646 +0200 ++++ gdb-7.6/gdb/testsuite/lib/prelink-support.exp 2013-05-19 16:05:39.100839980 +0200 +@@ -95,8 +95,9 @@ proc file_copy {src dest} { + # Wrap function build_executable so that the resulting executable is fully + # self-sufficient (without dependencies on system libraries). Parameter + # INTERP may be used to specify a loader (ld.so) to be used that is +-# different from the default system one. Libraries on which the executable +-# depends are copied into directory DIR. Default DIR value to ++# different from the default system one. INTERP can be set to "no" if no ld.so ++# copy should be made. Libraries on which the executable depends are copied ++# into directory DIR. Default DIR value to + # `${objdir}/${subdir}/${EXECUTABLE}.d'. + # + # In case of success, return a string containing the arguments to be used +@@ -151,8 +152,15 @@ proc build_executable_own_libs {testname + + if {$interp == ""} { + set interp_system [section_get $binfile .interp] +- set interp ${dir}/[file tail $interp_system] +- file_copy $interp_system $interp ++ if {$interp_system == ""} { ++ fail "$test could not find .interp" ++ } else { ++ set interp ${dir}/[file tail $interp_system] ++ file_copy $interp_system $interp + } + } -+} -+ -+# Enable stop-on-solib-events -+gdb_test_no_output "set stop-on-solib-events 1" -+ -+# Run to the first stop -+gdb_test "run" ".*Stopped due to shared library event.*" -+ -+# XFAIL if we are not using probes -+set test "ensure using probes" -+set using_probes 0 -+gdb_test_multiple "bt" $test { -+ -re "#0 +\[^\r\n\]*\\m(__GI_)?$normal_bp\\M.*$gdb_prompt $" { -+ xfail $test ++ if {$interp == "no"} { ++ set interp "" + } + + set dests {} +@@ -164,13 +172,19 @@ proc build_executable_own_libs {testname + + # Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s + # specified by the caller to be able to link it for ldd" above. +- set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp,-rpath,$dir"] ++ set options [linsert $options 0 "ldflags=-Wl,-rpath,$dir"] ++ if {$interp != ""} { ++ set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp"] + } -+ -re "#0 +\[^\r\n\]*\\m(__GI_)?$probes_bp\\M.*$gdb_prompt $" { -+ pass $test -+ set using_probes 1 + + if {[build_executable $testname $executable $sources $options] == -1} { + return "" + } + +- set prelink_args "--dynamic-linker=$interp --ld-library-path=$dir $binfile $interp [concat $dests]" ++ set prelink_args "--ld-library-path=$dir $binfile [concat $dests]" ++ if {$interp != ""} { ++ set prelink_args "--dynamic-linker=$interp $prelink_args $interp" + } -+} -+ -+if { $using_probes } { -+ # Set up breakpoints. -+ gdb_test_no_output "set stop-on-solib-events 0" -+ gdb_test "break stop" {Breakpoint [0-9]+ at .*} -+ gdb_test_no_output "set breakpoint pending on" -+ gdb_test "break foo" {Breakpoint [0-9]+ \(foo\) pending\.} -+ -+ # Check our library isn't loaded. -+ check_info_shared "info sharedlibrary #1" 0 -+ -+ # Run to the first stop and check our library loaded. -+ gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+ check_info_shared "info sharedlibrary #2" 1 -+ -+ # The next stop should be the function in the library. -+ gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} -+ -+ # Run to the next stop and check our library is now loaded twice. -+ gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+ check_info_shared "info sharedlibrary #3" 2 -+ -+ # The next stop should be the function in the library. -+ gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} -+ -+ # Run to the next stop and check our library is now loaded three -+ # times. -+ gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+ check_info_shared "info sharedlibrary #4" 3 -+ -+ # The next stop should be the function in the library. -+ gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} -+ -+ # Run to the next stop and check our library is now loaded twice. -+ gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+ check_info_shared "info sharedlibrary #5" 2 -+ -+ # Run to the next stop and check our library is now loaded once. -+ gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+ check_info_shared "info sharedlibrary #6" 1 -+ -+ # Run to the next stop and check our library is not loaded. -+ gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+ check_info_shared "info sharedlibrary #7" 0 -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-interp.exp + return $prelink_args + } + +Index: gdb-7.6/gdb/testsuite/gdb.base/break-interp.exp =================================================================== ---- gdb-7.5.50.20130215.orig/gdb/testsuite/gdb.base/break-interp.exp 2013-01-01 07:33:25.000000000 +0100 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-interp.exp 2013-02-15 22:37:35.762417598 +0100 +--- gdb-7.6.orig/gdb/testsuite/gdb.base/break-interp.exp 2013-05-19 16:05:37.882840646 +0200 ++++ gdb-7.6/gdb/testsuite/gdb.base/break-interp.exp 2013-05-19 16:05:39.101839979 +0200 @@ -109,12 +109,19 @@ proc strip_debug {dest} { } } @@ -1591,73 +255,13 @@ Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-interp.exp # Use two separate gdb_test_multiple statements to avoid timeouts due # to slow processing of wildcard capturing long output -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes-solib.c +Index: gdb-7.6/gdb/testsuite/gdb.threads/dlopen-libpthread.exp =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes-solib.c 2013-02-15 22:37:35.762417598 +0100 -@@ -0,0 +1,24 @@ -+/* Copyright 2012 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 -+foo (int n) -+{ -+ printf ("foo %d\n", n); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes.c 2013-02-15 22:37:35.763417600 +0100 -@@ -0,0 +1,26 @@ -+/* Copyright 2012 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 *handle = dlopen (SHLIB_NAME, RTLD_LAZY); -+ -+ dlclose (handle); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes.exp 2013-02-15 22:37:35.763417600 +0100 -@@ -0,0 +1,76 @@ -+# Copyright 2012 Free Software Foundation, Inc. -+ ++++ gdb-7.6/gdb/testsuite/gdb.threads/dlopen-libpthread.exp 2013-05-19 16:05:39.101839979 +0200 +@@ -0,0 +1,74 @@ ++# Copyright 2011 Free Software Foundation, Inc. ++# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or @@ -1671,319 +275,196 @@ Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/break-probes.exp +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + -+if { [skip_shlib_tests] || [is_remote target] } { ++if {![istarget *-linux*] || [skip_shlib_tests]} { + return 0 +} + -+standard_testfile ++load_lib prelink-support.exp + -+set libname $testfile-solib -+set srcfile_lib $srcdir/$subdir/$libname.c -+set binfile_lib [standard_output_file $libname.so] ++set testfile "dlopen-libpthread" ++set srcmainfile ${testfile}.c ++set srclibfile ${testfile}-lib.c ++set executable ${testfile} ++set binfile_lib ${objdir}/${subdir}/${executable}.so ++set binfile ${objdir}/${subdir}/${executable} ++set lib_dlopen [shlib_target_file ${executable}.so] + -+set normal_bp "_dl_debug_state" -+set probes_bp "dl_main" ++# Use build_executable_own_libs as prelinked libpthread.so can produce false ++# PASS - it is OK if GDB processes it still before relocation. + -+if { [gdb_compile_shlib $srcfile_lib $binfile_lib \ -+ [list additional_flags=-fPIC]] != "" } { -+ untested "Could not compile $binfile_lib." ++set relink_args [build_executable_own_libs ${testfile}.exp ${executable}.so $srclibfile {debug shlib_pthreads} no] ++if {$relink_args == "" || ![prelink_no $relink_args] ++ || [prepare_for_testing ${testfile}.exp ${executable} ${srcmainfile} {debug shlib_load}] } { ++ return -1 ++} ++gdb_load_shlibs $binfile_lib ++ ++if { ![runto_main] } { + return -1 +} + -+if { [prepare_for_testing $testfile.exp $testfile $srcfile \ -+ [list additional_flags=-DSHLIB_NAME\=\"$binfile_lib\" libs=-ldl]] } { -+ return -1 -+} -+ -+# Enable stop-on-solib-events -+gdb_test_no_output "set stop-on-solib-events 1" -+ -+# Run to the first stop -+gdb_test "run" ".*Stopped due to shared library event.*" -+ -+# XFAIL if we are not using probes -+set test "ensure using probes" -+set using_probes 0 -+gdb_test_multiple "bt" $test { -+ -re "#0 +\[^\r\n\]*\\m(__GI_)?$normal_bp\\M.*$gdb_prompt $" { -+ xfail $test -+ } -+ -re "#0 +\[^\r\n\]*\\m(__GI_)?$probes_bp\\M.*$gdb_prompt $" { ++set test "info probes all rtld rtld_map_complete" ++gdb_test_multiple $test $test { ++ -re "\[ \t\]rtld_map_complete\[ \t\]+0x\[0-9a-f\]+.*\r\n$gdb_prompt $" { + pass $test -+ set using_probes 1 ++ } ++ -re "No probes matched\\.\r\n$gdb_prompt $" { ++ xfail $test ++ untested ${testfile}.exp ++ return + } +} + -+if { $using_probes } { -+ # Run til it loads our library -+ set test "run til our library loads" -+ set loaded_library 0 -+ while { !$loaded_library } { -+ gdb_test_multiple "c" $test { -+ -re "Inferior loaded $binfile_lib\\M.*$gdb_prompt $" { -+ pass $test -+ set loaded_library 1 -+ } -+ -re "Stopped due to shared library event\\M.*$gdb_prompt $" { -+ } -+ } -+ } -+ -+ # Call something to ensure that relocation occurred -+ gdb_test "call foo(23)" "foo 23.*\\\$.* = .*" -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared-solib1.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared-solib1.c 2013-02-15 22:37:35.763417600 +0100 -@@ -0,0 +1,24 @@ -+/* Copyright 2012 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 -+foo (int n) -+{ -+ printf ("foo %d\n", n); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared-solib2.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared-solib2.c 2013-02-15 22:37:35.763417600 +0100 -@@ -0,0 +1,24 @@ -+/* Copyright 2012 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 -+bar (int n) -+{ -+ printf ("bar %d\n", n); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared.c 2013-02-15 22:37:35.763417600 +0100 -@@ -0,0 +1,48 @@ -+/* Copyright 2012 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 -+stop () -+{ -+} -+ -+int -+main () -+{ -+ void *handle1, *handle2; -+ void (*func)(int); -+ -+ handle1 = dlopen (SHLIB1_NAME, RTLD_LAZY); -+ stop (); -+ -+ handle2 = dlopen (SHLIB2_NAME, RTLD_LAZY); -+ stop (); -+ -+ func = (void (*)(int)) dlsym (handle1, "foo"); -+ func (1); -+ -+ func = (void (*)(int)) dlsym (handle2, "bar"); -+ func (2); -+ -+ dlclose (handle1); -+ stop (); -+ -+ dlclose (handle2); -+ stop (); -+ -+ return 0; -+} -Index: gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.5.50.20130215/gdb/testsuite/gdb.base/info-shared.exp 2013-02-15 22:37:35.764417602 +0100 -@@ -0,0 +1,139 @@ -+# Copyright 2012 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 . -+ -+if { [skip_shlib_tests] || [is_remote target] } { -+ return 0 -+} -+ -+standard_testfile -+ -+set lib1name $testfile-solib1 -+set srcfile_lib1 $srcdir/$subdir/$lib1name.c -+set binfile_lib1 [standard_output_file $lib1name.so] -+set define1 -DSHLIB1_NAME\=\"$binfile_lib1\" -+ -+set lib2name $testfile-solib2 -+set srcfile_lib2 $srcdir/$subdir/$lib2name.c -+set binfile_lib2 [standard_output_file $lib2name.so] -+set define2 -DSHLIB2_NAME\=\"$binfile_lib2\" -+ -+if { [gdb_compile_shlib $srcfile_lib1 $binfile_lib1 \ -+ [list additional_flags=-fPIC]] != "" } { -+ untested "Could not compile $binfile_lib1." -+ return -1 -+} -+ -+if { [gdb_compile_shlib $srcfile_lib2 $binfile_lib2 \ -+ [list additional_flags=-fPIC]] != "" } { -+ untested "Could not compile $binfile_lib2." -+ return -1 -+} -+ -+set cflags "$define1 $define2" -+if { [prepare_for_testing $testfile.exp $testfile $srcfile \ -+ [list additional_flags=$cflags libs=-ldl]] } { -+ return -1 -+} -+ -+# Run "info sharedlibrary" and check for the presence or absence of -+# our libraries. -+proc check_info_shared { test expect1 expect2 } { -+ global lib1name -+ global lib2name -+ global gdb_prompt -+ -+ set actual1 0 -+ set actual2 0 -+ -+ gdb_test_multiple "info sharedlibrary" $test { -+ -re $lib1name { -+ set actual1 1 -+ exp_continue -+ } -+ -re $lib2name { -+ set actual2 1 -+ exp_continue -+ } -+ -re "\r\n$gdb_prompt $" { -+ if { $actual1 == $expect1 && $actual2 == $expect2 } { -+ pass $test -+ } else { -+ fail $test -+ } -+ } -+ } -+} -+ -+# Set up breakpoints. -+gdb_test "break stop" {Breakpoint [0-9]+ at .*} -+gdb_test_no_output "set breakpoint pending on" -+gdb_test "break foo" {Breakpoint [0-9]+ \(foo\) pending\.} -+gdb_test "break bar" {Breakpoint [0-9]+ \(bar\) pending\.} -+ -+# Check neither of the libraries are loaded at the start. -+gdb_test "start" {Temporary breakpoint [0-9]+, .* in main \(\)} -+check_info_shared "info sharedlibrary #1" 0 0 -+ -+# Run to the first stop and check that only the first library is loaded. -+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+check_info_shared "info sharedlibrary #2" 1 0 -+ -+# Run to the second stop and check that both libraries are loaded. -+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+check_info_shared "info sharedlibrary #3" 1 1 -+ -+# Check that the next stop is in foo. -+gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} -+ -+# Check that the next stop is in bar. -+gdb_test "c" {Breakpoint [0-9]+, .* in bar \(\) from .*} -+ -+# Restart the inferior and make sure there are no breakpoint reset -+# errors. These can happen with the probes-based runtime linker -+# interface if the cache is not cleared correctly. -+set test "restart" -+gdb_test_multiple "run" $test { -+ -re {Start it from the beginning\? \(y or n\) } { -+ send_gdb "y\n" -+ exp_continue -+ } -+ -re {Error in re-setting breakpoint} { ++set test "libpthread.so not found" ++gdb_test_multiple "info sharedlibrary" $test { ++ -re "/libpthread\\.so.*\r\n$gdb_prompt $" { + fail $test + } -+ -re "\r\n$gdb_prompt $" { ++ -re "/libc\\.so.*\r\n$gdb_prompt $" { + pass $test + } +} + -+# We're at the first stop. Check that only the first library is loaded. -+check_info_shared "info sharedlibrary #4" 1 0 ++gdb_test "set variable filename=\"$lib_dlopen\"" + -+# Run to the second stop and check that both libraries are loaded. -+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+check_info_shared "info sharedlibrary #5" 1 1 ++gdb_breakpoint "notify" + -+# Check that the next stop is in foo. -+gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} ++# The error was: ++# Cannot find new threads: generic error ++gdb_continue_to_breakpoint "notify" ".* notify-here .*" + -+# Check that the next stop is in bar. -+gdb_test "c" {Breakpoint [0-9]+, .* in bar \(\) from .*} ++gdb_test "info sharedlibrary" {/libpthread\.so.*} "libpthread.so found" +Index: gdb-7.6/gdb/testsuite/gdb.threads/dlopen-libpthread.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.6/gdb/testsuite/gdb.threads/dlopen-libpthread.c 2013-05-19 16:05:39.101839979 +0200 +@@ -0,0 +1,46 @@ ++/* This testcase is part of GDB, the GNU debugger. + -+# Run to the next stop and check that the first library has been unloaded. -+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+check_info_shared "info sharedlibrary #6" 0 1 ++ Copyright 2011 Free Software Foundation, Inc. + -+# Run to the last stop and check that both libraries are gone. -+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} -+check_info_shared "info sharedlibrary #7" 0 0 ++ 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 ++ ++static const char *volatile filename; ++ ++static void ++notify (void) ++{ ++ filename = NULL; /* notify-here */ ++} ++ ++int ++main (void) ++{ ++ void *h; ++ void (*fp) (void (*) (void)); ++ ++ assert (filename != NULL); ++ h = dlopen (filename, RTLD_LAZY); ++ assert (h != NULL); ++ ++ fp = dlsym (h, "f"); ++ assert (fp != NULL); ++ ++ fp (notify); ++ ++ return 0; ++} +Index: gdb-7.6/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.6/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c 2013-05-19 16:05:39.101839979 +0200 +@@ -0,0 +1,40 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2011 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#include ++#include ++ ++static void * ++tfunc (void *arg) ++{ ++ void (*notifyp) (void) = arg; ++ ++ notifyp (); ++} ++ ++void ++f (void (*notifyp) (void)) ++{ ++ pthread_t t; ++ int i; ++ ++ i = pthread_create (&t, NULL, tfunc, notifyp); ++ assert (i == 0); ++ ++ i = pthread_join (t, NULL); ++ assert (i == 0); ++} +Index: gdb-7.6/gdb/testsuite/gdb.base/solib-corrupted.exp +=================================================================== +--- gdb-7.6.orig/gdb/testsuite/gdb.base/solib-corrupted.exp 2013-05-19 16:05:37.883840645 +0200 ++++ gdb-7.6/gdb/testsuite/gdb.base/solib-corrupted.exp 2013-05-19 16:05:39.102839978 +0200 +@@ -36,6 +36,33 @@ if ![runto_main] { + return + } + ++# With probes interface GDB no longer scans the inferior library list so its ++# corruption cannot be tested. There is no way to disable the probes ++# interface. ++ ++set probes { init_start init_complete map_start reloc_complete unmap_start ++ unmap_complete } ++set test "info probes" ++gdb_test_multiple $test $test { ++ -re "^rtld\[ \t\]+(?:rtld_)?(\[a-z_\]+)\[ \t\]" { ++ set idx [lsearch -exact $probes $expect_out(1,string)] ++ if { $idx >= 0 } { ++ set probes [lreplace $probes $idx $idx] ++ } ++ exp_continue ++ } ++ -re "^\[^\r\n\]*\r\n" { ++ exp_continue ++ } ++ -re "^$gdb_prompt $" { ++ } ++} ++if { [llength $probes] == 0 } { ++ xfail $test ++ untested "GDB is using probes" ++ return ++} ++ + gdb_test "info sharedlibrary" "From * To .*" "normal list" + + # GDB checks there for matching L_PREV. diff --git a/gdb-dlopen-stap-probe-7of7.patch b/gdb-dlopen-stap-probe-7of7.patch index 8f2b419..30357e9 100644 --- a/gdb-dlopen-stap-probe-7of7.patch +++ b/gdb-dlopen-stap-probe-7of7.patch @@ -1,147 +1,435 @@ -2012-07-30 Gary Benson +http://sourceware.org/ml/gdb-patches/2013-05/msg00630.html +Subject: [RFA 7/7] Linker-debugger interface tests - * objfiles.h (inhibit_section_map_updates): New function - declaration. - (resume_section_map_updates): Likewise. - (resume_section_map_updates_cleanup): Likewise. - * objfiles.c (objfile_pspace_info): New field "inhibit_updates". - (find_pc_section): Do not update the section map if - inhibit_updates is set. - (inhibit_section_map_updates): New function. - (resume_section_map_updates): Likewise. - (resume_section_map_updates_cleanup): Likewise. - * solib-svr4.c (svr4_handle_solib_event): Inhibit section map - updates for calls to evaluate_probe_argument. -Index: gdb-7.5.50.20130118/gdb/objfiles.h -=================================================================== ---- gdb-7.5.50.20130118.orig/gdb/objfiles.h 2013-01-18 23:18:16.862315673 +0100 -+++ gdb-7.5.50.20130118/gdb/objfiles.h 2013-01-18 23:18:36.702343482 +0100 -@@ -508,6 +508,22 @@ extern int in_plt_section (CORE_ADDR, ch - modules. */ - DECLARE_REGISTRY(objfile); - -+/* In normal use, the section map will be rebuilt by FIND_PC_SECTION -+ if objfiles have been added, removed or relocated since it was last -+ called. Calling INHIBIT_SECTION_MAP_UPDATES will inhibit this -+ behavior until RESUME_SECTION_MAP_UPDATES is called. If you call -+ INHIBIT_SECTION_MAP_UPDATES you must ensure that every call to -+ FIND_PC_SECTION in the inhibited region relates to a section that -+ is already in the section map and has not since been removed or -+ relocated. */ -+extern void inhibit_section_map_updates (void); +--DCA/C9WSnDtl50zu +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This patch adds some testcases for the linker-debugger interface. + +--DCA/C9WSnDtl50zu +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="rtld-probes-7-tests-gb.patch" + +2013-05-16 Gary Benson + + * gdb.base/break-probes.exp: New file. + * gdb.base/break-probes.c: Likewise. + * gdb.base/break-probes-solib.c: Likewise. + * gdb.base/info-shared.exp: New file. + * gdb.base/info-shared.c: Likewise. + * gdb.base/info-shared-solib1.c: Likewise. + * gdb.base/info-shared-solib2.c: Likewise. + +diff --git a/gdb/testsuite/gdb.base/break-probes.exp b/gdb/testsuite/gdb.base/break-probes.exp +new file mode 100644 +index 0000000..8372636 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/break-probes.exp +@@ -0,0 +1,77 @@ ++# Copyright 2013 Free Software Foundation, Inc. + -+/* Resume automatically rebuilding the section map as required. */ -+extern void resume_section_map_updates (void); ++# 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 . + -+/* Version of the above suitable for use as a cleanup. */ -+extern void resume_section_map_updates_cleanup (void *arg); -+ - extern void default_iterate_over_objfiles_in_search_order - (struct gdbarch *gdbarch, - iterate_over_objfiles_in_search_order_cb_ftype *cb, -Index: gdb-7.5.50.20130118/gdb/objfiles.c -=================================================================== ---- gdb-7.5.50.20130118.orig/gdb/objfiles.c 2013-01-18 23:18:13.647311006 +0100 -+++ gdb-7.5.50.20130118/gdb/objfiles.c 2013-01-18 23:18:16.862315673 +0100 -@@ -69,6 +69,9 @@ struct objfile_pspace_info - int objfiles_changed_p; - struct obj_section **sections; - int num_sections; -+ -+ /* Nonzero if section map updates should be inhibited. */ -+ int inhibit_updates; - }; - - /* Per-program-space data key. */ -@@ -1356,7 +1359,7 @@ find_pc_section (CORE_ADDR pc) - return s; - - pspace_info = get_objfile_pspace_data (current_program_space); -- if (pspace_info->objfiles_changed_p != 0) -+ if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates) - { - update_section_map (current_program_space, - &pspace_info->sections, -@@ -1415,6 +1418,30 @@ objfiles_changed (void) - get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1; - } - -+/* See comments in objfiles.h. */ -+ -+void -+inhibit_section_map_updates (void) -+{ -+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 1; ++if { [skip_shlib_tests] } { ++ return 0 +} + -+/* See comments in objfiles.h. */ ++standard_testfile + -+void -+resume_section_map_updates (void) -+{ -+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 0; ++set libname $testfile-solib ++set srcfile_lib $srcdir/$subdir/$libname.c ++set binfile_lib [standard_output_file $libname.so] ++ ++set normal_bp "_dl_debug_state" ++set probes_bp "dl_main" ++ ++if { [gdb_compile_shlib $srcfile_lib $binfile_lib \ ++ [list additional_flags=-fPIC]] != "" } { ++ untested "Could not compile $binfile_lib." ++ return -1 +} + -+/* See comments in objfiles.h. */ -+ -+void -+resume_section_map_updates_cleanup (void *arg) -+{ -+ resume_section_map_updates (); ++if { [prepare_for_testing $testfile.exp $testfile $srcfile \ ++ [list additional_flags=-DSHLIB_NAME\=\"$binfile_lib\" libs=-ldl]] } { ++ return -1 +} + - /* The default implementation for the "iterate_over_objfiles_in_search_order" - gdbarch method. It is equivalent to use the ALL_OBJFILES macro, - searching the objfiles in the order they are stored internally, -Index: gdb-7.5.50.20130118/gdb/solib-svr4.c -=================================================================== ---- gdb-7.5.50.20130118.orig/gdb/solib-svr4.c 2013-01-18 23:18:13.649311010 +0100 -+++ gdb-7.5.50.20130118/gdb/solib-svr4.c 2013-01-18 23:18:16.863315675 +0100 -@@ -1849,6 +1849,7 @@ svr4_handle_solib_event (bpstat bs) - struct svr4_info *info = get_svr4_info (); - struct probe_and_info buf, *pi = &buf; - enum probe_action action; -+ struct cleanup *cleanups = NULL; - struct value *val; - LONGEST lmid; - CORE_ADDR debug_base, lm = 0; -@@ -1872,6 +1873,19 @@ svr4_handle_solib_event (bpstat bs) - if (action == NAMESPACE_NO_ACTION) - return; - -+ /* EVALUATE_PROBE_ARGUMENT looks up symbols in the dynamic linker -+ using FIND_PC_SECTION. FIND_PC_SECTION is accelerated by a cache -+ called the section map. The section map is invalidated every -+ time a shared library is loaded or unloaded, and if the inferior -+ is generating a lot of shared library events then the section map -+ will be updated every time SVR4_HANDLE_SOLIB_EVENT is called. -+ We called FIND_PC_SECTION in SVR4_CREATE_SOLIB_EVENT_BREAKPOINTS, -+ so we can guarantee that the dynamic linker's sections are in the -+ section map. We can therefore inhibit section map updates across -+ these calls to EVALUATE_PROBE_ARGUMENT and save a lot of time. */ -+ inhibit_section_map_updates (); -+ cleanups = make_cleanup (resume_section_map_updates_cleanup, NULL); ++# Enable stop-on-solib-events ++gdb_test_no_output "set stop-on-solib-events 1" + - val = evaluate_probe_argument (pi->probe, 0); - if (val == NULL) - goto error; -@@ -1903,6 +1917,9 @@ svr4_handle_solib_event (bpstat bs) - action = NAMESPACE_RELOAD; - } - -+ do_cleanups (cleanups); -+ cleanups = NULL; ++# Start the inferior and run to the first stop ++gdb_run_cmd ++gdb_test "" ".*Stopped due to shared library event.*" + - if (action == NAMESPACE_UPDATE_OR_RELOAD) - { - if (namespace_update_incremental (info, lmid, lm, is_initial_ns)) -@@ -1925,6 +1942,8 @@ svr4_handle_solib_event (bpstat bs) - warning (_("Probes-based dynamic linker interface failed.\n" - "Reverting to original interface.\n")); - -+ if (cleanups != NULL) -+ do_cleanups (cleanups); - free_namespace_table (info); - free_probes (info); - info->using_probes = 0; ++# XFAIL if we are not using probes ++set test "ensure using probes" ++set using_probes 0 ++gdb_test_multiple "bt" $test { ++ -re "#0 +\[^\r\n\]*\\m(__GI_)?$normal_bp\\M.*$gdb_prompt $" { ++ xfail $test ++ } ++ -re "#0 +\[^\r\n\]*\\m(__GI_)?$probes_bp\\M.*$gdb_prompt $" { ++ pass $test ++ set using_probes 1 ++ } ++} ++ ++if { $using_probes } { ++ # Run til it loads our library ++ set test "run til our library loads" ++ set loaded_library 0 ++ while { !$loaded_library } { ++ gdb_test_multiple "c" $test { ++ -re "Inferior loaded $binfile_lib\\M.*$gdb_prompt $" { ++ pass $test ++ set loaded_library 1 ++ } ++ -re "Stopped due to shared library event\\M.*$gdb_prompt $" { ++ } ++ } ++ } ++ ++ # Call something to ensure that relocation occurred ++ gdb_test "call foo(23)" "\\\$.* = 31.*\\\M.*" ++} +diff --git a/gdb/testsuite/gdb.base/break-probes.c b/gdb/testsuite/gdb.base/break-probes.c +new file mode 100644 +index 0000000..a778099 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/break-probes.c +@@ -0,0 +1,26 @@ ++/* Copyright 2013 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 *handle = dlopen (SHLIB_NAME, RTLD_LAZY); ++ ++ dlclose (handle); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/break-probes-solib.c b/gdb/testsuite/gdb.base/break-probes-solib.c +new file mode 100644 +index 0000000..bdde2db +--- /dev/null ++++ b/gdb/testsuite/gdb.base/break-probes-solib.c +@@ -0,0 +1,22 @@ ++/* Copyright 2013 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 ++foo (int n) ++{ ++ return n * n / 17; ++} +diff --git a/gdb/testsuite/gdb.base/info-shared.exp b/gdb/testsuite/gdb.base/info-shared.exp +new file mode 100644 +index 0000000..1dabb9f +--- /dev/null ++++ b/gdb/testsuite/gdb.base/info-shared.exp +@@ -0,0 +1,145 @@ ++# Copyright 2013 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 . ++ ++if { [skip_shlib_tests] } { ++ return 0 ++} ++ ++standard_testfile ++ ++set lib1name $testfile-solib1 ++set srcfile_lib1 $srcdir/$subdir/$lib1name.c ++set binfile_lib1 [standard_output_file $lib1name.so] ++set define1 -DSHLIB1_NAME\=\"$binfile_lib1\" ++ ++set lib2name $testfile-solib2 ++set srcfile_lib2 $srcdir/$subdir/$lib2name.c ++set binfile_lib2 [standard_output_file $lib2name.so] ++set define2 -DSHLIB2_NAME\=\"$binfile_lib2\" ++ ++if { [gdb_compile_shlib $srcfile_lib1 $binfile_lib1 \ ++ [list additional_flags=-fPIC]] != "" } { ++ untested "Could not compile $binfile_lib1." ++ return -1 ++} ++ ++if { [gdb_compile_shlib $srcfile_lib2 $binfile_lib2 \ ++ [list additional_flags=-fPIC]] != "" } { ++ untested "Could not compile $binfile_lib2." ++ return -1 ++} ++ ++set cflags "$define1 $define2" ++if { [prepare_for_testing $testfile.exp $testfile $srcfile \ ++ [list additional_flags=$cflags libs=-ldl]] } { ++ return -1 ++} ++ ++# Run "info sharedlibrary" and check for the presence or absence of ++# our libraries. ++proc check_info_shared { test expect1 expect2 } { ++ global lib1name ++ global lib2name ++ global gdb_prompt ++ ++ set actual1 0 ++ set actual2 0 ++ ++ gdb_test_multiple "info sharedlibrary" $test { ++ -re $lib1name { ++ set actual1 1 ++ exp_continue ++ } ++ -re $lib2name { ++ set actual2 1 ++ exp_continue ++ } ++ -re "\r\n$gdb_prompt $" { ++ if { $actual1 == $expect1 && $actual2 == $expect2 } { ++ pass $test ++ } else { ++ fail $test ++ } ++ } ++ } ++} ++ ++# Start the inferior, and check neither of the libraries are loaded at ++# the start. ++runto_main ++check_info_shared "info sharedlibrary #1" 0 0 ++ ++# Set up breakpoints. ++gdb_test "break stop" {Breakpoint [0-9]+ at .*} ++gdb_test_no_output "set breakpoint pending on" ++gdb_test "break foo" {Breakpoint [0-9]+ \(foo\) pending\.} ++gdb_test "break bar" {Breakpoint [0-9]+ \(bar\) pending\.} ++ ++# Run to the first stop and check that only the first library is loaded. ++gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} ++check_info_shared "info sharedlibrary #2" 1 0 ++ ++# Run to the second stop and check that both libraries are loaded. ++gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} ++check_info_shared "info sharedlibrary #3" 1 1 ++ ++# Check that the next stop is in foo. ++gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} ++ ++# Check that the next stop is in bar. ++gdb_test "c" {Breakpoint [0-9]+, .* in bar \(\) from .*} ++ ++# Restart the inferior and make sure there are no breakpoint reset ++# errors. These can happen with the probes-based runtime linker ++# interface if the cache is not cleared correctly. ++set test "restart" ++gdb_run_cmd ++gdb_test_multiple "" $test { ++ -re {Start it from the beginning\? \(y or n\) } { ++ send_gdb "y\n" ++ exp_continue ++ } ++ -re {Error in re-setting breakpoint} { ++ fail $test ++ } ++ -re "\r\n$gdb_prompt $" { ++ pass $test ++ } ++} ++ ++# Check that neither library is loaded. ++check_info_shared "info sharedlibrary #4" 0 0 ++ ++# Run to the first stop and check that only the first library is loaded. ++gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} ++check_info_shared "info sharedlibrary #5" 1 0 ++ ++# Run to the second stop and check that both libraries are loaded. ++gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} ++check_info_shared "info sharedlibrary #6" 1 1 ++ ++# Check that the next stop is in foo. ++gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*} ++ ++# Check that the next stop is in bar. ++gdb_test "c" {Breakpoint [0-9]+, .* in bar \(\) from .*} ++ ++# Run to the next stop and check that the first library has been unloaded. ++gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} ++check_info_shared "info sharedlibrary #7" 0 1 ++ ++# Run to the last stop and check that both libraries are gone. ++gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)} ++check_info_shared "info sharedlibrary #8" 0 0 +diff --git a/gdb/testsuite/gdb.base/info-shared.c b/gdb/testsuite/gdb.base/info-shared.c +new file mode 100644 +index 0000000..d699a11 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/info-shared.c +@@ -0,0 +1,48 @@ ++/* Copyright 2013 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 ++stop () ++{ ++} ++ ++int ++main () ++{ ++ void *handle1, *handle2; ++ void (*func)(int); ++ ++ handle1 = dlopen (SHLIB1_NAME, RTLD_LAZY); ++ stop (); ++ ++ handle2 = dlopen (SHLIB2_NAME, RTLD_LAZY); ++ stop (); ++ ++ func = (void (*)(int)) dlsym (handle1, "foo"); ++ func (1); ++ ++ func = (void (*)(int)) dlsym (handle2, "bar"); ++ func (2); ++ ++ dlclose (handle1); ++ stop (); ++ ++ dlclose (handle2); ++ stop (); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/info-shared-solib1.c b/gdb/testsuite/gdb.base/info-shared-solib1.c +new file mode 100644 +index 0000000..9979ee7 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/info-shared-solib1.c +@@ -0,0 +1,24 @@ ++/* Copyright 2013 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 ++foo (int n) ++{ ++ printf ("foo %d\n", n); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/info-shared-solib2.c b/gdb/testsuite/gdb.base/info-shared-solib2.c +new file mode 100644 +index 0000000..d4ed1e6 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/info-shared-solib2.c +@@ -0,0 +1,24 @@ ++/* Copyright 2013 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 ++bar (int n) ++{ ++ printf ("bar %d\n", n); ++ ++ return 0; ++} + +--DCA/C9WSnDtl50zu-- + diff --git a/gdb-dlopen-stap-probe-fixup.patch b/gdb-dlopen-stap-probe-fixup.patch new file mode 100644 index 0000000..30e18c1 --- /dev/null +++ b/gdb-dlopen-stap-probe-fixup.patch @@ -0,0 +1,62 @@ +--- gdb-7.6-x/gdb/solib-svr4.c 2013-05-19 16:04:36.838874595 +0200 ++++ gdb-7.6/gdb/solib-svr4.c 2013-05-19 16:12:35.112514978 +0200 +@@ -1078,7 +1078,6 @@ svr4_free_library_list (void *p_list) + static struct so_list * + svr4_copy_library_list (struct so_list *src) + { +- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); + struct so_list *dst = NULL; + struct so_list **link = &dst; + +@@ -1090,8 +1089,8 @@ svr4_copy_library_list (struct so_list * + + memcpy (new, src, sizeof (struct so_list)); + +- new->lm_info = xmalloc (lmo->link_map_size); +- memcpy (new->lm_info, src->lm_info, lmo->link_map_size); ++ new->lm_info = xmalloc (sizeof (*new->lm_info)); ++ memcpy (new->lm_info, src->lm_info, sizeof (*new->lm_info)); + + new->next = NULL; + *link = new; +@@ -1747,7 +1746,7 @@ solist_update_incremental (struct svr4_i + struct svr4_library_list library_list; + char annex[64]; + +- xsnprintf (annex, sizeof (annex), "start=%lx;prev=%lx", lm, prev_lm); ++ xsnprintf (annex, sizeof (annex), "start=%lx;prev=%lx", (unsigned long) lm, (unsigned long) prev_lm); + if (!svr4_current_sos_via_xfer_libraries (&library_list, annex)) + return 0; + +@@ -1813,7 +1812,10 @@ svr4_handle_solib_event (void) + goto error; + + if (action == DO_NOTHING) ++{ ++do_cleanups (old_chain); + return; ++} + + /* EVALUATE_PROBE_ARGUMENT looks up symbols in the dynamic linker + using FIND_PC_SECTION. FIND_PC_SECTION is accelerated by a cache +--- gdb-7.6-x/gdb/testsuite/gdb.base/break-probes.exp 2013-05-19 16:06:19.452818090 +0200 ++++ gdb-7.6/gdb/testsuite/gdb.base/break-probes.exp 2013-05-19 16:07:49.730770135 +0200 +@@ -60,14 +60,15 @@ gdb_test_multiple "bt" $test { + if { $using_probes } { + # Run til it loads our library + set test "run til our library loads" +- set loaded_library 0 +- while { !$loaded_library } { ++ set not_loaded_library 1 ++ while { $not_loaded_library } { ++ set not_loaded_library 0 + gdb_test_multiple "c" $test { + -re "Inferior loaded $binfile_lib\\M.*$gdb_prompt $" { + pass $test +- set loaded_library 1 + } + -re "Stopped due to shared library event\\M.*$gdb_prompt $" { ++ set not_loaded_library 1 + } + } + } diff --git a/gdb-dlopen-stap-probe-inhibit.patch b/gdb-dlopen-stap-probe-inhibit.patch deleted file mode 100644 index f0417ec..0000000 --- a/gdb-dlopen-stap-probe-inhibit.patch +++ /dev/null @@ -1,60 +0,0 @@ -https://bugzilla.redhat.com/show_bug.cgi?id=911712 - ---- ./gdb/objfiles.c-orig 2013-03-21 18:51:00.141957331 +0100 -+++ ./gdb/objfiles.c 2013-03-21 19:20:25.615519748 +0100 -@@ -615,6 +615,7 @@ free_objfile (struct objfile *objfile) - obstack_free (&objfile->objfile_obstack, 0); - - /* Rebuild section map next time we need it. */ -+ gdb_assert (!get_objfile_pspace_data (objfile->pspace)->inhibit_updates); - get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1; - - xfree (objfile); -@@ -1284,6 +1285,21 @@ bsearch_cmp (const void *key, const void - return 1; - } - -+static void -+update_space_info_sections (struct objfile_pspace_info *pspace_info) -+{ -+ if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates) -+ { -+ update_section_map (current_program_space, -+ &pspace_info->sections, -+ &pspace_info->num_sections); -+ -+ /* Don't need updates to section map until objfiles are added, -+ removed or relocated. */ -+ pspace_info->objfiles_changed_p = 0; -+ } -+} -+ - /* Returns a section whose range includes PC or NULL if none found. */ - - struct obj_section * -@@ -1298,16 +1314,7 @@ find_pc_section (CORE_ADDR pc) - return s; - - pspace_info = get_objfile_pspace_data (current_program_space); -- if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates) -- { -- update_section_map (current_program_space, -- &pspace_info->sections, -- &pspace_info->num_sections); -- -- /* Don't need updates to section map until objfiles are added, -- removed or relocated. */ -- pspace_info->objfiles_changed_p = 0; -- } -+ update_space_info_sections (pspace_info); - - /* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to - bsearch be non-NULL. */ -@@ -1471,6 +1478,7 @@ objfiles_changed (void) - void - inhibit_section_map_updates (void) - { -+ update_space_info_sections (get_objfile_pspace_data (current_program_space)); - get_objfile_pspace_data (current_program_space)->inhibit_updates = 1; - } - diff --git a/gdb-dlopen-stap-probe-mapfailed.patch b/gdb-dlopen-stap-probe-mapfailed.patch deleted file mode 100644 index 4030f4b..0000000 --- a/gdb-dlopen-stap-probe-mapfailed.patch +++ /dev/null @@ -1,30 +0,0 @@ -commit 21fd080d18f280c19fdc5489726dcd6c66eb5fbf -Author: Gary Benson -Date: Tue Jan 8 12:12:14 2013 +0000 - - Also stop on "map_failed" where appropriate - -Removed a comment patch hunk. - -diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c -index 5eb84ba..a46fd74 100644 ---- a/gdb/solib-svr4.c -+++ b/gdb/solib-svr4.c -@@ -160,6 +160,7 @@ static const struct probe_info probe_info[] = - { "init_start", NAMESPACE_NO_ACTION }, - { "init_complete", NAMESPACE_RELOAD }, - { "map_start", NAMESPACE_NO_ACTION }, -+ { "map_failed", NAMESPACE_NO_ACTION }, - { "reloc_complete", NAMESPACE_UPDATE_OR_RELOAD }, - { "unmap_start", NAMESPACE_NO_ACTION }, - { "unmap_complete", NAMESPACE_RELOAD }, -@@ -2056,6 +2058,9 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch, - info->probes[i] = find_probes_in_objfile (os->objfile, "rtld", - name); - -+ if (!strcmp (name, "rtld_map_failed")) -+ continue; -+ - if (!VEC_length (probe_p, info->probes[i])) - { - free_probes (info); diff --git a/gdb-dlopen-stap-probe-test.patch b/gdb-dlopen-stap-probe-test.patch deleted file mode 100644 index fb2ebd1..0000000 --- a/gdb-dlopen-stap-probe-test.patch +++ /dev/null @@ -1,307 +0,0 @@ -commit 5bfdc32cd3bf373c3b02e1fd864ed8ceab0292b2 -Author: Jan Kratochvil -Date: Mon Aug 8 12:08:53 2011 +0200 - - +testcase - -Index: gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c 2012-07-15 08:51:38.238701282 +0200 -@@ -0,0 +1,40 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2011 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+#include -+#include -+ -+static void * -+tfunc (void *arg) -+{ -+ void (*notifyp) (void) = arg; -+ -+ notifyp (); -+} -+ -+void -+f (void (*notifyp) (void)) -+{ -+ pthread_t t; -+ int i; -+ -+ i = pthread_create (&t, NULL, tfunc, notifyp); -+ assert (i == 0); -+ -+ i = pthread_join (t, NULL); -+ assert (i == 0); -+} -Index: gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.c 2012-07-15 08:51:38.239701277 +0200 -@@ -0,0 +1,46 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2011 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+#include -+#include -+#include -+ -+static const char *volatile filename; -+ -+static void -+notify (void) -+{ -+ filename = NULL; /* notify-here */ -+} -+ -+int -+main (void) -+{ -+ void *h; -+ void (*fp) (void (*) (void)); -+ -+ assert (filename != NULL); -+ h = dlopen (filename, RTLD_LAZY); -+ assert (h != NULL); -+ -+ fp = dlsym (h, "f"); -+ assert (fp != NULL); -+ -+ fp (notify); -+ -+ return 0; -+} -Index: gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.exp 2012-07-15 09:08:01.760258588 +0200 -@@ -0,0 +1,74 @@ -+# Copyright 2011 Free Software Foundation, Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+if {![istarget *-linux*] || [skip_shlib_tests]} { -+ return 0 -+} -+ -+load_lib prelink-support.exp -+ -+set testfile "dlopen-libpthread" -+set srcmainfile ${testfile}.c -+set srclibfile ${testfile}-lib.c -+set executable ${testfile} -+set binfile_lib ${objdir}/${subdir}/${executable}.so -+set binfile ${objdir}/${subdir}/${executable} -+set lib_dlopen [shlib_target_file ${executable}.so] -+ -+# Use build_executable_own_libs as prelinked libpthread.so can produce false -+# PASS - it is OK if GDB processes it still before relocation. -+ -+set relink_args [build_executable_own_libs ${testfile}.exp ${executable}.so $srclibfile {debug shlib_pthreads} no] -+if {$relink_args == "" || ![prelink_no $relink_args] -+ || [prepare_for_testing ${testfile}.exp ${executable} ${srcmainfile} {debug shlib_load}] } { -+ return -1 -+} -+gdb_load_shlibs $binfile_lib -+ -+if { ![runto_main] } { -+ return -1 -+} -+ -+set test "info probes all rtld rtld_map_complete" -+gdb_test_multiple $test $test { -+ -re "\[ \t\]rtld_map_complete\[ \t\]+0x\[0-9a-f\]+.*\r\n$gdb_prompt $" { -+ pass $test -+ } -+ -re "No probes matched\\.\r\n$gdb_prompt $" { -+ xfail $test -+ untested ${testfile}.exp -+ return -+ } -+} -+ -+set test "libpthread.so not found" -+gdb_test_multiple "info sharedlibrary" $test { -+ -re "/libpthread\\.so.*\r\n$gdb_prompt $" { -+ fail $test -+ } -+ -re "/libc\\.so.*\r\n$gdb_prompt $" { -+ pass $test -+ } -+} -+ -+gdb_test "set variable filename=\"$lib_dlopen\"" -+ -+gdb_breakpoint "notify" -+ -+# The error was: -+# Cannot find new threads: generic error -+gdb_continue_to_breakpoint "notify" ".* notify-here .*" -+ -+gdb_test "info sharedlibrary" {/libpthread\.so.*} "libpthread.so found" -Index: gdb-7.4.50.20120714/gdb/testsuite/lib/gdb.exp -=================================================================== ---- gdb-7.4.50.20120714.orig/gdb/testsuite/lib/gdb.exp 2012-07-15 08:51:36.803709222 +0200 -+++ gdb-7.4.50.20120714/gdb/testsuite/lib/gdb.exp 2012-07-15 09:02:41.983028197 +0200 -@@ -3774,22 +3774,6 @@ proc build_executable_from_specs {testna - - set binfile [standard_output_file $executable] - -- set objects {} -- set i 0 -- foreach {s local_options} $args { -- if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $local_options] != "" } { -- untested $testname -- return -1 -- } -- lappend objects "${binfile}${i}.o" -- incr i -- } -- -- if { [gdb_compile $objects "${binfile}" executable $options] != "" } { -- untested $testname -- return -1 -- } -- - set info_options "" - if { [lsearch -exact $options "c++"] >= 0 } { - set info_options "c++" -@@ -3797,6 +3781,42 @@ proc build_executable_from_specs {testna - if [get_compiler_info ${info_options}] { - return -1 - } -+ -+ set binfile [standard_output_file $executable] -+ -+ set func gdb_compile -+ set func_index [lsearch -regexp $options {^(pthreads|shlib|shlib_pthreads)$}] -+ if {$func_index != -1} { -+ set func "${func}_[lindex $options $func_index]" -+ } -+ -+ # gdb_compile_shlib and gdb_compile_shlib_pthreads do not use the 3rd -+ # parameter. They also requires $sources while gdb_compile and -+ # gdb_compile_pthreads require $objects. Moreover they ignore any options. -+ if [string match gdb_compile_shlib* $func] { -+ set sources_path {} -+ foreach {s local_options} $args { -+ lappend sources_path "${srcdir}/${subdir}/${s}" -+ } -+ set ret [$func $sources_path "${binfile}" $options] -+ } else { -+ set objects {} -+ set i 0 -+ foreach {s local_options} $args { -+ if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $local_options] != "" } { -+ untested $testname -+ return -1 -+ } -+ lappend objects "${binfile}${i}.o" -+ incr i -+ } -+ set ret [$func $objects "${binfile}" executable $options] -+ } -+ if { $ret != "" } { -+ untested $testname -+ return -1 -+ } -+ - return 0 - } - -Index: gdb-7.4.50.20120714/gdb/testsuite/lib/prelink-support.exp -=================================================================== ---- gdb-7.4.50.20120714.orig/gdb/testsuite/lib/prelink-support.exp 2012-01-04 09:27:56.000000000 +0100 -+++ gdb-7.4.50.20120714/gdb/testsuite/lib/prelink-support.exp 2012-07-15 08:51:38.243701254 +0200 -@@ -95,8 +95,9 @@ proc file_copy {src dest} { - # Wrap function build_executable so that the resulting executable is fully - # self-sufficient (without dependencies on system libraries). Parameter - # INTERP may be used to specify a loader (ld.so) to be used that is --# different from the default system one. Libraries on which the executable --# depends are copied into directory DIR. Default DIR value to -+# different from the default system one. INTERP can be set to "no" if no ld.so -+# copy should be made. Libraries on which the executable depends are copied -+# into directory DIR. Default DIR value to - # `${objdir}/${subdir}/${EXECUTABLE}.d'. - # - # In case of success, return a string containing the arguments to be used -@@ -151,8 +152,15 @@ proc build_executable_own_libs {testname - - if {$interp == ""} { - set interp_system [section_get $binfile .interp] -- set interp ${dir}/[file tail $interp_system] -- file_copy $interp_system $interp -+ if {$interp_system == ""} { -+ fail "$test could not find .interp" -+ } else { -+ set interp ${dir}/[file tail $interp_system] -+ file_copy $interp_system $interp -+ } -+ } -+ if {$interp == "no"} { -+ set interp "" - } - - set dests {} -@@ -164,13 +172,19 @@ proc build_executable_own_libs {testname - - # Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s - # specified by the caller to be able to link it for ldd" above. -- set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp,-rpath,$dir"] -+ set options [linsert $options 0 "ldflags=-Wl,-rpath,$dir"] -+ if {$interp != ""} { -+ set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp"] -+ } - - if {[build_executable $testname $executable $sources $options] == -1} { - return "" - } - -- set prelink_args "--dynamic-linker=$interp --ld-library-path=$dir $binfile $interp [concat $dests]" -+ set prelink_args "--ld-library-path=$dir $binfile [concat $dests]" -+ if {$interp != ""} { -+ set prelink_args "--dynamic-linker=$interp $prelink_args $interp" -+ } - return $prelink_args - } - diff --git a/gdb-dlopen-stap-probe-test2.patch b/gdb-dlopen-stap-probe-test2.patch deleted file mode 100644 index 9ca4f6b..0000000 --- a/gdb-dlopen-stap-probe-test2.patch +++ /dev/null @@ -1,69 +0,0 @@ -http://sourceware.org/ml/gdb-patches/2012-08/msg00500.html -Subject: [patch] testsuite: Make solib-corrupted.exp untested for probes [Re: [RFA 0/4 take 2] Improved linker-debugger interface] - -On Fri, 17 Aug 2012 22:53:53 +0200, Jan Kratochvil wrote: -> It regresses with glibc-debuginfo installed: -> -> info sharedlibrary^M -> From To Syms Read Shared Object Library^M -> 0x00007ffff7ddcb20 0x00007ffff7df63d9 Yes /lib64/ld-linux-x86-64.so.2^M -> 0x00007ffff7ae05b0 0x00007ffff7b4ad78 Yes /lib64/libm.so.6^M -> 0x00007ffff77431a0 0x00007ffff7883cf0 Yes /lib64/libc.so.6^M -> (gdb) FAIL: gdb.base/solib-corrupted.exp: corrupted list -> -> But I guess there is no longer a way to test it with probes so it should just -> run some 'info probes' and make this test UNTESTED if rtld probes are -> available. - -I had to implement it for Fedora already anyway. - - -Regards, -Jan - - -gdb/testsuite/ -2012-08-18 Jan Kratochvil - - * gdb.base/solib-corrupted.exp: New variable probes. - (info probes): New test. - -diff --git a/gdb/testsuite/gdb.base/solib-corrupted.exp b/gdb/testsuite/gdb.base/solib-corrupted.exp -index 84b3b0c..c9f55d6 100644 ---- a/gdb/testsuite/gdb.base/solib-corrupted.exp -+++ b/gdb/testsuite/gdb.base/solib-corrupted.exp -@@ -36,6 +36,33 @@ if ![runto_main] { - return - } - -+# With probes interface GDB no longer scans the inferior library list so its -+# corruption cannot be tested. There is no way to disable the probes -+# interface. -+ -+set probes { init_start init_complete map_start reloc_complete unmap_start -+ unmap_complete } -+set test "info probes" -+gdb_test_multiple $test $test { -+ -re "^rtld\[ \t\]+(?:rtld_)?(\[a-z_\]+)\[ \t\]" { -+ set idx [lsearch -exact $probes $expect_out(1,string)] -+ if { $idx >= 0 } { -+ set probes [lreplace $probes $idx $idx] -+ } -+ exp_continue -+ } -+ -re "^\[^\r\n\]*\r\n" { -+ exp_continue -+ } -+ -re "^$gdb_prompt $" { -+ } -+} -+if { [llength $probes] == 0 } { -+ xfail $test -+ untested "GDB is using probes" -+ return -+} -+ - gdb_test "info sharedlibrary" "From * To .*" "normal list" - - # GDB checks there for matching L_PREV. - diff --git a/gdb.spec b/gdb.spec index 89c2d83..16bc3f0 100644 --- a/gdb.spec +++ b/gdb.spec @@ -36,7 +36,7 @@ Version: 7.6 # 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: 28%{?dist} +Release: 29%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain Group: Development/Debuggers @@ -504,16 +504,16 @@ Patch579: gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch # Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432). # Fix crash regression from the dlopen of libpthread.so fix (BZ 911712). +# Fix performance regression when inferior opens many libraries (Gary Benson). #=push -Patch718: gdb-dlopen-stap-probe-3of7.patch -Patch719: gdb-dlopen-stap-probe-4of7.patch -Patch720: gdb-dlopen-stap-probe-5of7.patch -Patch721: gdb-dlopen-stap-probe-6of7.patch -Patch722: gdb-dlopen-stap-probe-7of7.patch -Patch619: gdb-dlopen-stap-probe-test.patch -Patch723: gdb-dlopen-stap-probe-test2.patch -Patch822: gdb-dlopen-stap-probe-mapfailed.patch -Patch827: gdb-dlopen-stap-probe-inhibit.patch +Patch718: gdb-dlopen-stap-probe-1of7.patch +Patch719: gdb-dlopen-stap-probe-2of7.patch +Patch720: gdb-dlopen-stap-probe-3of7.patch +Patch721: gdb-dlopen-stap-probe-4of7.patch +Patch722: gdb-dlopen-stap-probe-5of7.patch +Patch723: gdb-dlopen-stap-probe-6of7.patch +Patch822: gdb-dlopen-stap-probe-7of7.patch +Patch827: gdb-dlopen-stap-probe-fixup.patch # Work around PR libc/13097 "linux-vdso.so.1" warning message. #=push @@ -876,7 +876,6 @@ find -name "*.info*"|xargs rm -f %patch723 -p1 %patch822 -p1 %patch827 -p1 -%patch619 -p1 %patch627 -p1 %patch634 -p1 %patch653 -p1 @@ -1398,6 +1397,9 @@ fi %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch" %changelog +* Sun May 19 2013 Jan Kratochvil - 7.6-29.fc19 +- Fix performance regression when inferior opens many libraries (Gary Benson). + * Thu May 9 2013 Jan Kratochvil - 7.6-28.fc19 - Fix needless expansion of non-gdbindex symtabs (Doug Evans).