public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Cc: "Pierre Muller" <pierre.muller@ics-cnrs.unistra.fr>
Subject: Re: [RFA] Fix maint translate command
Date: Wed, 01 Sep 2010 15:25:00 -0000	[thread overview]
Message-ID: <201009011625.27952.pedro@codesourcery.com> (raw)
In-Reply-To: <000001cb49dc$81074080$8315c180$@muller@ics-cnrs.unistra.fr>

[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) \

  reply	other threads:[~2010-09-01 15:25 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-01  8:54 Pierre Muller
2010-09-01 13:39 ` Pedro Alves
2010-09-01 13:49   ` Pierre Muller
2010-09-01 15:25     ` Pedro Alves [this message]
2010-09-01 16:07       ` Pedro Alves
2010-09-14 15:14         ` [PING]RE: " Pierre Muller
2010-09-22 18:59           ` Joel Brobecker
2010-09-22 19:23             ` Pedro Alves
2010-09-24 15:55               ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201009011625.27952.pedro@codesourcery.com \
    --to=pedro@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    --cc=pierre.muller@ics-cnrs.unistra.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).