This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

[patch] gas: Fix assembly listing on Windows.


Hi,

Attached is a patch to fix assembly listing.

Consider running the following on Windows:

m68k-elf-as.exe --gdwarf2 -v -alh=hello.lst -o hello.o hello.s

Without this patch, hello.lst looks like so:

  :
  :
  20               		.file 1 "hello.c"
   1:hello.c       **** #include <stdio.h>
   2:hello.c       **** 
   3:hello.c       **** int
   4:hello.c       **** main (void)
   5:hello.c       **** {
  21               	%fp,#0   <- Notice missing "link.w"
  :
  :

With this patch, hello.lst looks like:

  :
  :
  20               		.file 1 "hello.c"
   1:hello.c       **** #include <stdio.h>
   2:hello.c       **** 
   3:hello.c       **** int
   4:hello.c       **** main (void)
   5:hello.c       **** {
  21               		.loc 1 5 0    <- This line was missing
  22 0000 4E56 0000 		link.w %fp,#0 <- "link.w" came back
  :
  :

The short story is that the mingw version of ftell doesn't seem to be
able to handle a file opened in the text mode.

Here goes the long story.

listing.c:buffer_line is responsible for taking one line from a source
file and printing it, whether the source file is a C source file or an
assembly file.  listing.c:buffer_line tries to have no more than one
source file open at a time.  For example, when the listing switches
from a C source file to an assembly file, buffer_line closes the C
file, opens the assembly file, and picks up where it left off using
fseek.  The argument for fseek comes from ftell on the assembly file
when it was reading the C source file before.

The problem is that the return value from ftell is not usable for
fseek.  That is, doing something like the following does not give you
the intended result on Windows.

  f = fopen ("hello.s", "r");
  for (i = 0; i < 200; i++)
    printf ("%c", fgetc (f));
  fseek (f, ftell (f), SEEK_SET);
  for (i = 0; i < 200; i++)
    printf ("%c", fgetc (f));
  fclose (f); 

Since ftell is not reliable for a file opened in the text mode on
Windows, the patch teaches buffer_line to use the binary mode on
Windows and manually process line ends.

FWIW, objdump.c:index_file processes an input file in a similar way.

OK to apply?

Kazu Hirata

2008-10-03  Kazu Hirata  <kazu@codesourcery.com>

	* listing.c (buffer_line): Open the source file with FOPEN_RB.
	Manually process line ends.

Index: gas/listing.c
===================================================================
RCS file: /cvs/src/src/gas/listing.c,v
retrieving revision 1.35
diff -u -r1.35 listing.c
--- gas/listing.c	24 Sep 2008 14:38:03 -0000	1.35
+++ gas/listing.c	3 Oct 2008 15:25:32 -0000
@@ -471,8 +471,10 @@
 	  fclose (last_open_file);
 	}
 
+      /* Open the file in the binary mode so that ftell above can
+	 return a reliable value that we can feed to fseek below.  */
       last_open_file_info = file;
-      last_open_file = fopen (file->filename, FOPEN_RT);
+      last_open_file = fopen (file->filename, FOPEN_RB);
       if (last_open_file == NULL)
 	{
 	  file->at_end = 1;
@@ -489,7 +491,7 @@
   /* Leave room for null.  */
   size -= 1;
 
-  while (c != EOF && c != '\n')
+  while (c != EOF && c != '\n' && c != '\r')
     {
       if (count < size)
 	*p++ = c;
@@ -498,6 +500,17 @@
       c = fgetc (last_open_file);
 
     }
+
+  /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
+     is followed by '\r', swallow that as well.  */
+  if (c == '\r' || c == '\n')
+    {
+      int next = fgetc (last_open_file);
+      if ((c == '\r' && next != '\n')
+	  || (c == '\n' && next != '\r'))
+	ungetc (next, last_open_file);
+    }
+
   if (c == EOF)
     {
       file->at_end = 1;


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