This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] Fix maint translate command


[please don't top-post]

On Wednesday 01 September 2010 14:49:30, Pierre Muller wrote:
> > On Wednesday 01 September 2010 09:54:40, Pierre Muller wrote:
> > >   ALL_OBJSECTIONS is a double for loop,
> > > thus the 'break' statement was only exiting the first loop,
> > > but the second loop was still continuing, leading to
> > > a false error.
> > >
> > 
> > It all sounds like we should fix ALL_OBJSECTIONS then.

> Honestly, this might be a good idea,
> but I have no idea how to do this :(

With Magic.  It would be real simple if the inner loop's end condition
was a check againt NULL, rather than "(osect) < (objfile)->sections_end"
--- you'd just add an osect == NULL check to the outer loop's conditional.

Something like this is still simple, but clears "objfile" when you break
out of the inner loop:

#define ALL_OBJSECTIONS(objfile, osect)					\
  for ((objfile) = current_program_space->objfiles;			\
       (objfile) != NULL;						\
       (objfile) = (osect) < (objfile)->sections_end ? NULL : (objfile)->next) \
    for ((osect) = (objfile)->sections; (osect) < (objfile)->sections_end; osect++)


It happens that "maintenance translate ..." expects that OBJFILE is preserved
when you "break" within ALL_OBJSECTIONS, which, is probably what most would
expect if they didn't know the innards to the macro, so, we go a step further
to preserve that OBJFILE pointer:

#define ALL_OBJSECTIONS(objfile, osect)					\
  for ((objfile) = current_program_space->objfiles,			\
	 (osect) = (objfile) != NULL ? (objfile)->sections_end : NULL ; \
       (objfile) != NULL						\
	 && (osect) == (objfile)->sections_end;				\
       (objfile) = (osect) < (objfile)->sections_end			\
	 ? (objfile)							\
	 : (objfile)->next)						\
    for ((osect) = (objfile)->sections;					\
	 (osect) < (objfile)->sections_end;				\
	 osect++)

I admit it loop ugly, and that may look complicated, but it isn't
(complicated).  The outer loop learns about the inner loop's end
condition, and stops iterating if it detects the inner loop didn't
reach it's end.  The trick to not clearing "objfile" is to only
advance it in the outer loop, if the inner loop reached it's end.

It fixes "maint translate .text 0xXXX" for me and has no regressions on 
x86_64-unknown-linux-gnu.

There's a:

  goto keep;	/* break out of two nested for loops */

in gcore.c that could then be replaced with a "break" ...

-- 
Pedro Alves

2010-09-01  Pedro Alves  <pedro@codesourcery.com>

	* objfiles.h (ALL_OBJSECTIONS): Handle breaks in the inner loop.

---
 gdb/objfiles.h |   21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

Index: src/gdb/objfiles.h
===================================================================
--- src.orig/gdb/objfiles.h	2010-09-01 14:35:08.000000000 +0100
+++ src/gdb/objfiles.h	2010-09-01 16:10:53.000000000 +0100
@@ -611,9 +611,24 @@ extern int gdb_bfd_close_or_warn (struct
 #define ALL_OBJFILE_OSECTIONS(objfile, osect)	\
   for (osect = objfile->sections; osect < objfile->sections_end; osect++)
 
-#define ALL_OBJSECTIONS(objfile, osect)		\
-  ALL_OBJFILES (objfile)			\
-    ALL_OBJFILE_OSECTIONS (objfile, osect)
+/* Traverse all obj_sections in all objfiles in the current program
+   space.  Note that this detects a "break" in the inner loop, and
+   exits immediately from the outer loop as well, thus, client code
+   doesn't need to know that this is implemented with a double for.
+   The extra hair is to make sure that OBJFILE isn't cleared on a
+   "break".  */
+
+#define ALL_OBJSECTIONS(objfile, osect)					\
+  for ((objfile) = current_program_space->objfiles,			\
+	 (osect) = (objfile) != NULL ? (objfile)->sections_end : NULL ; \
+       (objfile) != NULL						\
+	 && (osect) == (objfile)->sections_end;				\
+       (objfile) = (osect) < (objfile)->sections_end			\
+	 ? (objfile)							\
+	 : (objfile)->next)						\
+    for ((osect) = (objfile)->sections;					\
+	 (osect) < (objfile)->sections_end;				\
+	 osect++)
 
 #define SECT_OFF_DATA(objfile) \
      ((objfile->sect_index_data == -1) \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]