Home | History | Annotate | Line # | Download | only in gas
listing.c revision 1.1.1.1
      1  1.1  skrll /* listing.c - maintain assembly listings
      2  1.1  skrll    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
      3  1.1  skrll    2001, 2002, 2003, 2005, 2006, 2007, 2008
      4  1.1  skrll    Free Software Foundation, Inc.
      5  1.1  skrll 
      6  1.1  skrll    This file is part of GAS, the GNU Assembler.
      7  1.1  skrll 
      8  1.1  skrll    GAS is free software; you can redistribute it and/or modify
      9  1.1  skrll    it under the terms of the GNU General Public License as published by
     10  1.1  skrll    the Free Software Foundation; either version 3, or (at your option)
     11  1.1  skrll    any later version.
     12  1.1  skrll 
     13  1.1  skrll    GAS is distributed in the hope that it will be useful,
     14  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  skrll    GNU General Public License for more details.
     17  1.1  skrll 
     18  1.1  skrll    You should have received a copy of the GNU General Public License
     19  1.1  skrll    along with GAS; see the file COPYING.  If not, write to the Free
     20  1.1  skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     21  1.1  skrll    02110-1301, USA.  */
     22  1.1  skrll 
     23  1.1  skrll /* Contributed by Steve Chamberlain <sac (at) cygnus.com>
     24  1.1  skrll 
     25  1.1  skrll  A listing page looks like:
     26  1.1  skrll 
     27  1.1  skrll  LISTING_HEADER  sourcefilename pagenumber
     28  1.1  skrll  TITLE LINE
     29  1.1  skrll  SUBTITLE LINE
     30  1.1  skrll  linenumber address data  source
     31  1.1  skrll  linenumber address data  source
     32  1.1  skrll  linenumber address data  source
     33  1.1  skrll  linenumber address data  source
     34  1.1  skrll 
     35  1.1  skrll  If not overridden, the listing commands are:
     36  1.1  skrll 
     37  1.1  skrll  .title  "stuff"
     38  1.1  skrll  	Put "stuff" onto the title line
     39  1.1  skrll  .sbttl  "stuff"
     40  1.1  skrll         Put stuff onto the subtitle line
     41  1.1  skrll 
     42  1.1  skrll   If these commands come within 10 lines of the top of the page, they
     43  1.1  skrll   will affect the page they are on, as well as any subsequent page
     44  1.1  skrll 
     45  1.1  skrll  .eject
     46  1.1  skrll  	Thow a page
     47  1.1  skrll  .list
     48  1.1  skrll  	Increment the enable listing counter
     49  1.1  skrll  .nolist
     50  1.1  skrll  	Decrement the enable listing counter
     51  1.1  skrll 
     52  1.1  skrll  .psize Y[,X]
     53  1.1  skrll  	Set the paper size to X wide and Y high. Setting a psize Y of
     54  1.1  skrll 	zero will suppress form feeds except where demanded by .eject
     55  1.1  skrll 
     56  1.1  skrll  If the counter goes below zero, listing is suppressed.
     57  1.1  skrll 
     58  1.1  skrll  Listings are a maintained by read calling various listing_<foo>
     59  1.1  skrll  functions.  What happens most is that the macro NO_LISTING is not
     60  1.1  skrll  defined (from the Makefile), then the macro LISTING_NEWLINE expands
     61  1.1  skrll  into a call to listing_newline.  The call is done from read.c, every
     62  1.1  skrll  time it sees a newline, and -l is on the command line.
     63  1.1  skrll 
     64  1.1  skrll  The function listing_newline remembers the frag associated with the
     65  1.1  skrll  newline, and creates a new frag - note that this is wasteful, but not
     66  1.1  skrll  a big deal, since listing slows things down a lot anyway.  The
     67  1.1  skrll  function also remembers when the filename changes.
     68  1.1  skrll 
     69  1.1  skrll  When all the input has finished, and gas has had a chance to settle
     70  1.1  skrll  down, the listing is output. This is done by running down the list of
     71  1.1  skrll  frag/source file records, and opening the files as needed and printing
     72  1.1  skrll  out the bytes and chars associated with them.
     73  1.1  skrll 
     74  1.1  skrll  The only things which the architecture can change about the listing
     75  1.1  skrll  are defined in these macros:
     76  1.1  skrll 
     77  1.1  skrll  LISTING_HEADER		The name of the architecture
     78  1.1  skrll  LISTING_WORD_SIZE      The make of the number of bytes in a word, this determines
     79  1.1  skrll  			the clumping of the output data. eg a value of
     80  1.1  skrll 			2 makes words look like 1234 5678, whilst 1
     81  1.1  skrll 			would make the same value look like 12 34 56
     82  1.1  skrll 			78
     83  1.1  skrll  LISTING_LHS_WIDTH      Number of words of above size for the lhs
     84  1.1  skrll 
     85  1.1  skrll  LISTING_LHS_WIDTH_SECOND   Number of words for the data on the lhs
     86  1.1  skrll  			for the second line
     87  1.1  skrll 
     88  1.1  skrll  LISTING_LHS_CONT_LINES	Max number of lines to use up for a continuation
     89  1.1  skrll  LISTING_RHS_WIDTH      Number of chars from the input file to print
     90  1.1  skrll                         on a line.  */
     91  1.1  skrll 
     92  1.1  skrll #include "as.h"
     93  1.1  skrll #include "obstack.h"
     94  1.1  skrll #include "safe-ctype.h"
     95  1.1  skrll #include "input-file.h"
     96  1.1  skrll #include "subsegs.h"
     97  1.1  skrll #include "bfdver.h"
     98  1.1  skrll #include <time.h>
     99  1.1  skrll 
    100  1.1  skrll #ifndef NO_LISTING
    101  1.1  skrll 
    102  1.1  skrll #ifndef LISTING_HEADER
    103  1.1  skrll #define LISTING_HEADER "GAS LISTING"
    104  1.1  skrll #endif
    105  1.1  skrll #ifndef LISTING_WORD_SIZE
    106  1.1  skrll #define LISTING_WORD_SIZE 4
    107  1.1  skrll #endif
    108  1.1  skrll #ifndef LISTING_LHS_WIDTH
    109  1.1  skrll #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
    110  1.1  skrll #endif
    111  1.1  skrll #ifndef LISTING_LHS_WIDTH_SECOND
    112  1.1  skrll #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
    113  1.1  skrll #endif
    114  1.1  skrll #ifndef LISTING_RHS_WIDTH
    115  1.1  skrll #define LISTING_RHS_WIDTH 100
    116  1.1  skrll #endif
    117  1.1  skrll #ifndef LISTING_LHS_CONT_LINES
    118  1.1  skrll #define LISTING_LHS_CONT_LINES 4
    119  1.1  skrll #endif
    120  1.1  skrll #define MAX_DATELEN 30
    121  1.1  skrll 
    122  1.1  skrll /* This structure remembers which .s were used.  */
    123  1.1  skrll typedef struct file_info_struct
    124  1.1  skrll {
    125  1.1  skrll   struct file_info_struct * next;
    126  1.1  skrll   char *                    filename;
    127  1.1  skrll   long                      pos;
    128  1.1  skrll   unsigned int              linenum;
    129  1.1  skrll   int                       at_end;
    130  1.1  skrll } file_info_type;
    131  1.1  skrll 
    132  1.1  skrll /* This structure remembers which line from which file goes into which
    133  1.1  skrll    frag.  */
    134  1.1  skrll struct list_info_struct
    135  1.1  skrll {
    136  1.1  skrll   /* Frag which this line of source is nearest to.  */
    137  1.1  skrll   fragS *frag;
    138  1.1  skrll 
    139  1.1  skrll   /* The actual line in the source file.  */
    140  1.1  skrll   unsigned int line;
    141  1.1  skrll 
    142  1.1  skrll   /* Pointer to the file info struct for the file which this line
    143  1.1  skrll      belongs to.  */
    144  1.1  skrll   file_info_type *file;
    145  1.1  skrll 
    146  1.1  skrll   /* The expanded text of any macro that may have been executing.  */
    147  1.1  skrll   char *line_contents;
    148  1.1  skrll 
    149  1.1  skrll   /* Next in list.  */
    150  1.1  skrll   struct list_info_struct *next;
    151  1.1  skrll 
    152  1.1  skrll   /* Pointer to the file info struct for the high level language
    153  1.1  skrll      source line that belongs here.  */
    154  1.1  skrll   file_info_type *hll_file;
    155  1.1  skrll 
    156  1.1  skrll   /* High level language source line.  */
    157  1.1  skrll   unsigned int hll_line;
    158  1.1  skrll 
    159  1.1  skrll   /* Pointer to any error message associated with this line.  */
    160  1.1  skrll   char *message;
    161  1.1  skrll 
    162  1.1  skrll   enum
    163  1.1  skrll     {
    164  1.1  skrll       EDICT_NONE,
    165  1.1  skrll       EDICT_SBTTL,
    166  1.1  skrll       EDICT_TITLE,
    167  1.1  skrll       EDICT_NOLIST,
    168  1.1  skrll       EDICT_LIST,
    169  1.1  skrll       EDICT_NOLIST_NEXT,
    170  1.1  skrll       EDICT_EJECT
    171  1.1  skrll     } edict;
    172  1.1  skrll   char *edict_arg;
    173  1.1  skrll 
    174  1.1  skrll   /* Nonzero if this line is to be omitted because it contains
    175  1.1  skrll      debugging information.  This can become a flags field if we come
    176  1.1  skrll      up with more information to store here.  */
    177  1.1  skrll   int debugging;
    178  1.1  skrll };
    179  1.1  skrll 
    180  1.1  skrll typedef struct list_info_struct list_info_type;
    181  1.1  skrll 
    182  1.1  skrll int listing_lhs_width        = LISTING_LHS_WIDTH;
    183  1.1  skrll int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
    184  1.1  skrll int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
    185  1.1  skrll int listing_rhs_width        = LISTING_RHS_WIDTH;
    186  1.1  skrll 
    187  1.1  skrll struct list_info_struct *        listing_tail;
    188  1.1  skrll 
    189  1.1  skrll static file_info_type *          file_info_head;
    190  1.1  skrll static file_info_type *          last_open_file_info;
    191  1.1  skrll static FILE *                    last_open_file;
    192  1.1  skrll static struct list_info_struct * head;
    193  1.1  skrll static int                       paper_width = 200;
    194  1.1  skrll static int                       paper_height = 60;
    195  1.1  skrll 
    196  1.1  skrll extern int                       listing;
    197  1.1  skrll 
    198  1.1  skrll /* File to output listings to.  */
    199  1.1  skrll static FILE *list_file;
    200  1.1  skrll 
    201  1.1  skrll /* This static array is used to keep the text of data to be printed
    202  1.1  skrll    before the start of the line.  */
    203  1.1  skrll 
    204  1.1  skrll #define MAX_BYTES							\
    205  1.1  skrll   (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width			\
    206  1.1  skrll    + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second)	\
    207  1.1  skrll       * listing_lhs_cont_lines)						\
    208  1.1  skrll    + 20)
    209  1.1  skrll 
    210  1.1  skrll static char *data_buffer;
    211  1.1  skrll 
    212  1.1  skrll /* Prototypes.  */
    213  1.1  skrll static void listing_message (const char *, const char *);
    214  1.1  skrll static file_info_type *file_info (const char *);
    215  1.1  skrll static void new_frag (void);
    216  1.1  skrll static char *buffer_line (file_info_type *, char *, unsigned int);
    217  1.1  skrll static void listing_page (list_info_type *);
    218  1.1  skrll static unsigned int calc_hex (list_info_type *);
    219  1.1  skrll static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
    220  1.1  skrll static void list_symbol_table (void);
    221  1.1  skrll static void print_source (file_info_type *, list_info_type *, char *, unsigned int);
    222  1.1  skrll static int debugging_pseudo (list_info_type *, const char *);
    223  1.1  skrll static void listing_listing (char *);
    224  1.1  skrll 
    225  1.1  skrll static void
    226  1.1  skrll listing_message (const char *name, const char *message)
    227  1.1  skrll {
    228  1.1  skrll   if (listing_tail != (list_info_type *) NULL)
    229  1.1  skrll     {
    230  1.1  skrll       unsigned int l = strlen (name) + strlen (message) + 1;
    231  1.1  skrll       char *n = (char *) xmalloc (l);
    232  1.1  skrll       strcpy (n, name);
    233  1.1  skrll       strcat (n, message);
    234  1.1  skrll       listing_tail->message = n;
    235  1.1  skrll     }
    236  1.1  skrll }
    237  1.1  skrll 
    238  1.1  skrll void
    239  1.1  skrll listing_warning (const char *message)
    240  1.1  skrll {
    241  1.1  skrll   listing_message (_("Warning:"), message);
    242  1.1  skrll }
    243  1.1  skrll 
    244  1.1  skrll void
    245  1.1  skrll listing_error (const char *message)
    246  1.1  skrll {
    247  1.1  skrll   listing_message (_("Error:"), message);
    248  1.1  skrll }
    249  1.1  skrll 
    250  1.1  skrll static file_info_type *
    251  1.1  skrll file_info (const char *file_name)
    252  1.1  skrll {
    253  1.1  skrll   /* Find an entry with this file name.  */
    254  1.1  skrll   file_info_type *p = file_info_head;
    255  1.1  skrll 
    256  1.1  skrll   while (p != (file_info_type *) NULL)
    257  1.1  skrll     {
    258  1.1  skrll       if (strcmp (p->filename, file_name) == 0)
    259  1.1  skrll 	return p;
    260  1.1  skrll       p = p->next;
    261  1.1  skrll     }
    262  1.1  skrll 
    263  1.1  skrll   /* Make new entry.  */
    264  1.1  skrll   p = xmalloc (sizeof (file_info_type));
    265  1.1  skrll   p->next = file_info_head;
    266  1.1  skrll   file_info_head = p;
    267  1.1  skrll   p->filename = xstrdup (file_name);
    268  1.1  skrll   p->pos = 0;
    269  1.1  skrll   p->linenum = 0;
    270  1.1  skrll   p->at_end = 0;
    271  1.1  skrll 
    272  1.1  skrll   return p;
    273  1.1  skrll }
    274  1.1  skrll 
    275  1.1  skrll static void
    276  1.1  skrll new_frag (void)
    277  1.1  skrll {
    278  1.1  skrll   frag_wane (frag_now);
    279  1.1  skrll   frag_new (0);
    280  1.1  skrll }
    281  1.1  skrll 
    282  1.1  skrll void
    283  1.1  skrll listing_newline (char *ps)
    284  1.1  skrll {
    285  1.1  skrll   char *file;
    286  1.1  skrll   unsigned int line;
    287  1.1  skrll   static unsigned int last_line = 0xffff;
    288  1.1  skrll   static char *last_file = NULL;
    289  1.1  skrll   list_info_type *new = NULL;
    290  1.1  skrll 
    291  1.1  skrll   if (listing == 0)
    292  1.1  skrll     return;
    293  1.1  skrll 
    294  1.1  skrll   if (now_seg == absolute_section)
    295  1.1  skrll     return;
    296  1.1  skrll 
    297  1.1  skrll #ifdef OBJ_ELF
    298  1.1  skrll   /* In ELF, anything in a section beginning with .debug or .line is
    299  1.1  skrll      considered to be debugging information.  This includes the
    300  1.1  skrll      statement which switches us into the debugging section, which we
    301  1.1  skrll      can only set after we are already in the debugging section.  */
    302  1.1  skrll   if ((listing & LISTING_NODEBUG) != 0
    303  1.1  skrll       && listing_tail != NULL
    304  1.1  skrll       && ! listing_tail->debugging)
    305  1.1  skrll     {
    306  1.1  skrll       const char *segname;
    307  1.1  skrll 
    308  1.1  skrll       segname = segment_name (now_seg);
    309  1.1  skrll       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
    310  1.1  skrll 	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
    311  1.1  skrll 	listing_tail->debugging = 1;
    312  1.1  skrll     }
    313  1.1  skrll #endif
    314  1.1  skrll 
    315  1.1  skrll   as_where (&file, &line);
    316  1.1  skrll   if (ps == NULL)
    317  1.1  skrll     {
    318  1.1  skrll       if (line == last_line
    319  1.1  skrll 	  && !(last_file && file && strcmp (file, last_file)))
    320  1.1  skrll 	return;
    321  1.1  skrll 
    322  1.1  skrll       new = (list_info_type *) xmalloc (sizeof (list_info_type));
    323  1.1  skrll 
    324  1.1  skrll       /* Detect if we are reading from stdin by examining the file
    325  1.1  skrll 	 name returned by as_where().
    326  1.1  skrll 
    327  1.1  skrll 	 [FIXME: We rely upon the name in the strcmp below being the
    328  1.1  skrll 	 same as the one used by input_scrub_new_file(), if that is
    329  1.1  skrll 	 not true, then this code will fail].
    330  1.1  skrll 
    331  1.1  skrll 	 If we are reading from stdin, then we need to save each input
    332  1.1  skrll 	 line here (assuming of course that we actually have a line of
    333  1.1  skrll 	 input to read), so that it can be displayed in the listing
    334  1.1  skrll 	 that is produced at the end of the assembly.  */
    335  1.1  skrll       if (strcmp (file, _("{standard input}")) == 0
    336  1.1  skrll 	  && input_line_pointer != NULL)
    337  1.1  skrll 	{
    338  1.1  skrll 	  char *copy;
    339  1.1  skrll 	  int len;
    340  1.1  skrll 	  int seen_quote = 0;
    341  1.1  skrll 
    342  1.1  skrll 	  for (copy = input_line_pointer - 1;
    343  1.1  skrll 	       *copy && (seen_quote
    344  1.1  skrll 			 || (! is_end_of_line [(unsigned char) *copy]));
    345  1.1  skrll 	       copy++)
    346  1.1  skrll 	    if (*copy == '"' && copy[-1] != '\\')
    347  1.1  skrll 	      seen_quote = ! seen_quote;
    348  1.1  skrll 
    349  1.1  skrll 	  len = (copy - input_line_pointer) + 2;
    350  1.1  skrll 
    351  1.1  skrll 	  copy = xmalloc (len);
    352  1.1  skrll 
    353  1.1  skrll 	  if (copy != NULL)
    354  1.1  skrll 	    {
    355  1.1  skrll 	      char *src = input_line_pointer - 1;
    356  1.1  skrll 	      char *dest = copy;
    357  1.1  skrll 
    358  1.1  skrll 	      while (--len)
    359  1.1  skrll 		{
    360  1.1  skrll 		  unsigned char c = *src++;
    361  1.1  skrll 
    362  1.1  skrll 		  /* Omit control characters in the listing.  */
    363  1.1  skrll 		  if (!ISCNTRL (c))
    364  1.1  skrll 		    *dest++ = c;
    365  1.1  skrll 		}
    366  1.1  skrll 
    367  1.1  skrll 	      *dest = 0;
    368  1.1  skrll 	    }
    369  1.1  skrll 
    370  1.1  skrll 	  new->line_contents = copy;
    371  1.1  skrll 	}
    372  1.1  skrll       else
    373  1.1  skrll 	new->line_contents = NULL;
    374  1.1  skrll     }
    375  1.1  skrll   else
    376  1.1  skrll     {
    377  1.1  skrll       new = xmalloc (sizeof (list_info_type));
    378  1.1  skrll       new->line_contents = ps;
    379  1.1  skrll     }
    380  1.1  skrll 
    381  1.1  skrll   last_line = line;
    382  1.1  skrll   last_file = file;
    383  1.1  skrll 
    384  1.1  skrll   new_frag ();
    385  1.1  skrll 
    386  1.1  skrll   if (listing_tail)
    387  1.1  skrll     listing_tail->next = new;
    388  1.1  skrll   else
    389  1.1  skrll     head = new;
    390  1.1  skrll 
    391  1.1  skrll   listing_tail = new;
    392  1.1  skrll 
    393  1.1  skrll   new->frag = frag_now;
    394  1.1  skrll   new->line = line;
    395  1.1  skrll   new->file = file_info (file);
    396  1.1  skrll   new->next = (list_info_type *) NULL;
    397  1.1  skrll   new->message = (char *) NULL;
    398  1.1  skrll   new->edict = EDICT_NONE;
    399  1.1  skrll   new->hll_file = (file_info_type *) NULL;
    400  1.1  skrll   new->hll_line = 0;
    401  1.1  skrll   new->debugging = 0;
    402  1.1  skrll 
    403  1.1  skrll   new_frag ();
    404  1.1  skrll 
    405  1.1  skrll #ifdef OBJ_ELF
    406  1.1  skrll   /* In ELF, anything in a section beginning with .debug or .line is
    407  1.1  skrll      considered to be debugging information.  */
    408  1.1  skrll   if ((listing & LISTING_NODEBUG) != 0)
    409  1.1  skrll     {
    410  1.1  skrll       const char *segname;
    411  1.1  skrll 
    412  1.1  skrll       segname = segment_name (now_seg);
    413  1.1  skrll       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
    414  1.1  skrll 	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
    415  1.1  skrll 	new->debugging = 1;
    416  1.1  skrll     }
    417  1.1  skrll #endif
    418  1.1  skrll }
    419  1.1  skrll 
    420  1.1  skrll /* Attach all current frags to the previous line instead of the
    421  1.1  skrll    current line.  This is called by the MIPS backend when it discovers
    422  1.1  skrll    that it needs to add some NOP instructions; the added NOP
    423  1.1  skrll    instructions should go with the instruction that has the delay, not
    424  1.1  skrll    with the new instruction.  */
    425  1.1  skrll 
    426  1.1  skrll void
    427  1.1  skrll listing_prev_line (void)
    428  1.1  skrll {
    429  1.1  skrll   list_info_type *l;
    430  1.1  skrll   fragS *f;
    431  1.1  skrll 
    432  1.1  skrll   if (head == (list_info_type *) NULL
    433  1.1  skrll       || head == listing_tail)
    434  1.1  skrll     return;
    435  1.1  skrll 
    436  1.1  skrll   new_frag ();
    437  1.1  skrll 
    438  1.1  skrll   for (l = head; l->next != listing_tail; l = l->next)
    439  1.1  skrll     ;
    440  1.1  skrll 
    441  1.1  skrll   for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
    442  1.1  skrll     if (f->line == listing_tail)
    443  1.1  skrll       f->line = l;
    444  1.1  skrll 
    445  1.1  skrll   listing_tail->frag = frag_now;
    446  1.1  skrll   new_frag ();
    447  1.1  skrll }
    448  1.1  skrll 
    449  1.1  skrll /* This function returns the next source line from the file supplied,
    450  1.1  skrll    truncated to size.  It appends a fake line to the end of each input
    451  1.1  skrll    file to make.  */
    452  1.1  skrll 
    453  1.1  skrll static char *
    454  1.1  skrll buffer_line (file_info_type *file, char *line, unsigned int size)
    455  1.1  skrll {
    456  1.1  skrll   unsigned int count = 0;
    457  1.1  skrll   int c;
    458  1.1  skrll 
    459  1.1  skrll   char *p = line;
    460  1.1  skrll 
    461  1.1  skrll   /* If we couldn't open the file, return an empty line.  */
    462  1.1  skrll   if (file->at_end)
    463  1.1  skrll     return "";
    464  1.1  skrll 
    465  1.1  skrll   /* Check the cache and see if we last used this file.  */
    466  1.1  skrll   if (!last_open_file_info || file != last_open_file_info)
    467  1.1  skrll     {
    468  1.1  skrll       if (last_open_file)
    469  1.1  skrll 	{
    470  1.1  skrll 	  last_open_file_info->pos = ftell (last_open_file);
    471  1.1  skrll 	  fclose (last_open_file);
    472  1.1  skrll 	}
    473  1.1  skrll 
    474  1.1  skrll       last_open_file_info = file;
    475  1.1  skrll       last_open_file = fopen (file->filename, FOPEN_RT);
    476  1.1  skrll       if (last_open_file == NULL)
    477  1.1  skrll 	{
    478  1.1  skrll 	  file->at_end = 1;
    479  1.1  skrll 	  return "";
    480  1.1  skrll 	}
    481  1.1  skrll 
    482  1.1  skrll       /* Seek to where we were last time this file was open.  */
    483  1.1  skrll       if (file->pos)
    484  1.1  skrll 	fseek (last_open_file, file->pos, SEEK_SET);
    485  1.1  skrll     }
    486  1.1  skrll 
    487  1.1  skrll   c = fgetc (last_open_file);
    488  1.1  skrll 
    489  1.1  skrll   /* Leave room for null.  */
    490  1.1  skrll   size -= 1;
    491  1.1  skrll 
    492  1.1  skrll   while (c != EOF && c != '\n')
    493  1.1  skrll     {
    494  1.1  skrll       if (count < size)
    495  1.1  skrll 	*p++ = c;
    496  1.1  skrll       count++;
    497  1.1  skrll 
    498  1.1  skrll       c = fgetc (last_open_file);
    499  1.1  skrll 
    500  1.1  skrll     }
    501  1.1  skrll   if (c == EOF)
    502  1.1  skrll     {
    503  1.1  skrll       file->at_end = 1;
    504  1.1  skrll       if (count + 2 < size)
    505  1.1  skrll 	{
    506  1.1  skrll 	  *p++ = '.';
    507  1.1  skrll 	  *p++ = '.';
    508  1.1  skrll 	  *p++ = '.';
    509  1.1  skrll 	}
    510  1.1  skrll     }
    511  1.1  skrll   file->linenum++;
    512  1.1  skrll   *p++ = 0;
    513  1.1  skrll   return line;
    514  1.1  skrll }
    515  1.1  skrll 
    516  1.1  skrll static const char *fn;
    517  1.1  skrll 
    518  1.1  skrll static unsigned int eject;	/* Eject pending */
    519  1.1  skrll static unsigned int page;	/* Current page number */
    520  1.1  skrll static char *title;		/* Current title */
    521  1.1  skrll static char *subtitle;		/* Current subtitle */
    522  1.1  skrll static unsigned int on_page;	/* Number of lines printed on current page */
    523  1.1  skrll 
    524  1.1  skrll static void
    525  1.1  skrll listing_page (list_info_type *list)
    526  1.1  skrll {
    527  1.1  skrll   /* Grope around, see if we can see a title or subtitle edict coming up
    528  1.1  skrll      soon.  (we look down 10 lines of the page and see if it's there)  */
    529  1.1  skrll   if ((eject || (on_page >= (unsigned int) paper_height))
    530  1.1  skrll       && paper_height != 0)
    531  1.1  skrll     {
    532  1.1  skrll       unsigned int c = 10;
    533  1.1  skrll       int had_title = 0;
    534  1.1  skrll       int had_subtitle = 0;
    535  1.1  skrll 
    536  1.1  skrll       page++;
    537  1.1  skrll 
    538  1.1  skrll       while (c != 0 && list)
    539  1.1  skrll 	{
    540  1.1  skrll 	  if (list->edict == EDICT_SBTTL && !had_subtitle)
    541  1.1  skrll 	    {
    542  1.1  skrll 	      had_subtitle = 1;
    543  1.1  skrll 	      subtitle = list->edict_arg;
    544  1.1  skrll 	    }
    545  1.1  skrll 	  if (list->edict == EDICT_TITLE && !had_title)
    546  1.1  skrll 	    {
    547  1.1  skrll 	      had_title = 1;
    548  1.1  skrll 	      title = list->edict_arg;
    549  1.1  skrll 	    }
    550  1.1  skrll 	  list = list->next;
    551  1.1  skrll 	  c--;
    552  1.1  skrll 	}
    553  1.1  skrll 
    554  1.1  skrll       if (page > 1)
    555  1.1  skrll 	{
    556  1.1  skrll 	  fprintf (list_file, "\f");
    557  1.1  skrll 	}
    558  1.1  skrll 
    559  1.1  skrll       fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
    560  1.1  skrll       fprintf (list_file, "%s\n", title);
    561  1.1  skrll       fprintf (list_file, "%s\n", subtitle);
    562  1.1  skrll       on_page = 3;
    563  1.1  skrll       eject = 0;
    564  1.1  skrll     }
    565  1.1  skrll }
    566  1.1  skrll 
    567  1.1  skrll static unsigned int
    568  1.1  skrll calc_hex (list_info_type *list)
    569  1.1  skrll {
    570  1.1  skrll   int data_buffer_size;
    571  1.1  skrll   list_info_type *first = list;
    572  1.1  skrll   unsigned int address = ~(unsigned int) 0;
    573  1.1  skrll   fragS *frag;
    574  1.1  skrll   fragS *frag_ptr;
    575  1.1  skrll   unsigned int octet_in_frag;
    576  1.1  skrll 
    577  1.1  skrll   /* Find first frag which says it belongs to this line.  */
    578  1.1  skrll   frag = list->frag;
    579  1.1  skrll   while (frag && frag->line != list)
    580  1.1  skrll     frag = frag->fr_next;
    581  1.1  skrll 
    582  1.1  skrll   frag_ptr = frag;
    583  1.1  skrll 
    584  1.1  skrll   data_buffer_size = 0;
    585  1.1  skrll 
    586  1.1  skrll   /* Dump all the frags which belong to this line.  */
    587  1.1  skrll   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
    588  1.1  skrll     {
    589  1.1  skrll       /* Print as many bytes from the fixed part as is sensible.  */
    590  1.1  skrll       octet_in_frag = 0;
    591  1.1  skrll       while ((offsetT) octet_in_frag < frag_ptr->fr_fix
    592  1.1  skrll 	     && data_buffer_size < MAX_BYTES - 3)
    593  1.1  skrll 	{
    594  1.1  skrll 	  if (address == ~(unsigned int) 0)
    595  1.1  skrll 	    address = frag_ptr->fr_address / OCTETS_PER_BYTE;
    596  1.1  skrll 
    597  1.1  skrll 	  sprintf (data_buffer + data_buffer_size,
    598  1.1  skrll 		   "%02X",
    599  1.1  skrll 		   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
    600  1.1  skrll 	  data_buffer_size += 2;
    601  1.1  skrll 	  octet_in_frag++;
    602  1.1  skrll 	}
    603  1.1  skrll       if (frag_ptr->fr_type == rs_fill)
    604  1.1  skrll 	{
    605  1.1  skrll 	  unsigned int var_rep_max = octet_in_frag;
    606  1.1  skrll 	  unsigned int var_rep_idx = octet_in_frag;
    607  1.1  skrll 
    608  1.1  skrll 	  /* Print as many bytes from the variable part as is sensible.  */
    609  1.1  skrll 	  while (((offsetT) octet_in_frag
    610  1.1  skrll 		  < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
    611  1.1  skrll 		 && data_buffer_size < MAX_BYTES - 3)
    612  1.1  skrll 	    {
    613  1.1  skrll 	      if (address == ~(unsigned int) 0)
    614  1.1  skrll 		address = frag_ptr->fr_address / OCTETS_PER_BYTE;
    615  1.1  skrll 
    616  1.1  skrll 	      sprintf (data_buffer + data_buffer_size,
    617  1.1  skrll 		       "%02X",
    618  1.1  skrll 		       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
    619  1.1  skrll 	      data_buffer_size += 2;
    620  1.1  skrll 
    621  1.1  skrll 	      var_rep_idx++;
    622  1.1  skrll 	      octet_in_frag++;
    623  1.1  skrll 
    624  1.1  skrll 	      if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
    625  1.1  skrll 		var_rep_idx = var_rep_max;
    626  1.1  skrll 	    }
    627  1.1  skrll 	}
    628  1.1  skrll 
    629  1.1  skrll       frag_ptr = frag_ptr->fr_next;
    630  1.1  skrll     }
    631  1.1  skrll   data_buffer[data_buffer_size] = '\0';
    632  1.1  skrll   return address;
    633  1.1  skrll }
    634  1.1  skrll 
    635  1.1  skrll static void
    636  1.1  skrll print_lines (list_info_type *list, unsigned int lineno,
    637  1.1  skrll 	     char *string, unsigned int address)
    638  1.1  skrll {
    639  1.1  skrll   unsigned int idx;
    640  1.1  skrll   unsigned int nchars;
    641  1.1  skrll   unsigned int lines;
    642  1.1  skrll   unsigned int octet_in_word = 0;
    643  1.1  skrll   char *src = data_buffer;
    644  1.1  skrll   int cur;
    645  1.1  skrll 
    646  1.1  skrll   /* Print the stuff on the first line.  */
    647  1.1  skrll   listing_page (list);
    648  1.1  skrll   nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
    649  1.1  skrll 
    650  1.1  skrll   /* Print the hex for the first line.  */
    651  1.1  skrll   if (address == ~(unsigned int) 0)
    652  1.1  skrll     {
    653  1.1  skrll       fprintf (list_file, "% 4d     ", lineno);
    654  1.1  skrll       for (idx = 0; idx < nchars; idx++)
    655  1.1  skrll 	fprintf (list_file, " ");
    656  1.1  skrll 
    657  1.1  skrll       fprintf (list_file, "\t%s\n", string ? string : "");
    658  1.1  skrll 
    659  1.1  skrll       on_page++;
    660  1.1  skrll 
    661  1.1  skrll       listing_page (0);
    662  1.1  skrll 
    663  1.1  skrll       return;
    664  1.1  skrll     }
    665  1.1  skrll 
    666  1.1  skrll   if (had_errors ())
    667  1.1  skrll     fprintf (list_file, "% 4d ???? ", lineno);
    668  1.1  skrll   else
    669  1.1  skrll     fprintf (list_file, "% 4d %04x ", lineno, address);
    670  1.1  skrll 
    671  1.1  skrll   /* And the data to go along with it.  */
    672  1.1  skrll   idx = 0;
    673  1.1  skrll   cur = 0;
    674  1.1  skrll   while (src[cur] && idx < nchars)
    675  1.1  skrll     {
    676  1.1  skrll       int offset;
    677  1.1  skrll       offset = cur;
    678  1.1  skrll       fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
    679  1.1  skrll       cur += 2;
    680  1.1  skrll       octet_in_word++;
    681  1.1  skrll 
    682  1.1  skrll       if (octet_in_word == LISTING_WORD_SIZE)
    683  1.1  skrll 	{
    684  1.1  skrll 	  fprintf (list_file, " ");
    685  1.1  skrll 	  idx++;
    686  1.1  skrll 	  octet_in_word = 0;
    687  1.1  skrll 	}
    688  1.1  skrll 
    689  1.1  skrll       idx += 2;
    690  1.1  skrll     }
    691  1.1  skrll 
    692  1.1  skrll   for (; idx < nchars; idx++)
    693  1.1  skrll     fprintf (list_file, " ");
    694  1.1  skrll 
    695  1.1  skrll   fprintf (list_file, "\t%s\n", string ? string : "");
    696  1.1  skrll   on_page++;
    697  1.1  skrll   listing_page (list);
    698  1.1  skrll 
    699  1.1  skrll   if (list->message)
    700  1.1  skrll     {
    701  1.1  skrll       fprintf (list_file, "****  %s\n", list->message);
    702  1.1  skrll       listing_page (list);
    703  1.1  skrll       on_page++;
    704  1.1  skrll     }
    705  1.1  skrll 
    706  1.1  skrll   for (lines = 0;
    707  1.1  skrll        lines < (unsigned int) listing_lhs_cont_lines
    708  1.1  skrll 	 && src[cur];
    709  1.1  skrll        lines++)
    710  1.1  skrll     {
    711  1.1  skrll       nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
    712  1.1  skrll       idx = 0;
    713  1.1  skrll 
    714  1.1  skrll       /* Print any more lines of data, but more compactly.  */
    715  1.1  skrll       fprintf (list_file, "% 4d      ", lineno);
    716  1.1  skrll 
    717  1.1  skrll       while (src[cur] && idx < nchars)
    718  1.1  skrll 	{
    719  1.1  skrll 	  int offset;
    720  1.1  skrll 	  offset = cur;
    721  1.1  skrll 	  fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
    722  1.1  skrll 	  cur += 2;
    723  1.1  skrll 	  idx += 2;
    724  1.1  skrll 	  octet_in_word++;
    725  1.1  skrll 
    726  1.1  skrll 	  if (octet_in_word == LISTING_WORD_SIZE)
    727  1.1  skrll 	    {
    728  1.1  skrll 	      fprintf (list_file, " ");
    729  1.1  skrll 	      idx++;
    730  1.1  skrll 	      octet_in_word = 0;
    731  1.1  skrll 	    }
    732  1.1  skrll 	}
    733  1.1  skrll 
    734  1.1  skrll       fprintf (list_file, "\n");
    735  1.1  skrll       on_page++;
    736  1.1  skrll       listing_page (list);
    737  1.1  skrll     }
    738  1.1  skrll }
    739  1.1  skrll 
    740  1.1  skrll static void
    741  1.1  skrll list_symbol_table (void)
    742  1.1  skrll {
    743  1.1  skrll   extern symbolS *symbol_rootP;
    744  1.1  skrll   int got_some = 0;
    745  1.1  skrll 
    746  1.1  skrll   symbolS *ptr;
    747  1.1  skrll   eject = 1;
    748  1.1  skrll   listing_page (0);
    749  1.1  skrll 
    750  1.1  skrll   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
    751  1.1  skrll     {
    752  1.1  skrll       if (SEG_NORMAL (S_GET_SEGMENT (ptr))
    753  1.1  skrll 	  || S_GET_SEGMENT (ptr) == absolute_section)
    754  1.1  skrll 	{
    755  1.1  skrll 	  /* Don't report section symbols.  They are not interesting.  */
    756  1.1  skrll 	  if (symbol_section_p (ptr))
    757  1.1  skrll 	    continue;
    758  1.1  skrll 
    759  1.1  skrll 	  if (S_GET_NAME (ptr))
    760  1.1  skrll 	    {
    761  1.1  skrll 	      char buf[30], fmt[8];
    762  1.1  skrll 	      valueT val = S_GET_VALUE (ptr);
    763  1.1  skrll 
    764  1.1  skrll 	      /* @@ Note that this is dependent on the compilation options,
    765  1.1  skrll 		 not solely on the target characteristics.  */
    766  1.1  skrll 	      if (sizeof (val) == 4 && sizeof (int) == 4)
    767  1.1  skrll 		sprintf (buf, "%08lx", (unsigned long) val);
    768  1.1  skrll 	      else if (sizeof (val) <= sizeof (unsigned long))
    769  1.1  skrll 		{
    770  1.1  skrll 		  sprintf (fmt, "%%0%lulx",
    771  1.1  skrll 			   (unsigned long) (sizeof (val) * 2));
    772  1.1  skrll 		  sprintf (buf, fmt, (unsigned long) val);
    773  1.1  skrll 		}
    774  1.1  skrll #if defined (BFD64)
    775  1.1  skrll 	      else if (sizeof (val) > 4)
    776  1.1  skrll 		sprintf_vma (buf, val);
    777  1.1  skrll #endif
    778  1.1  skrll 	      else
    779  1.1  skrll 		abort ();
    780  1.1  skrll 
    781  1.1  skrll 	      if (!got_some)
    782  1.1  skrll 		{
    783  1.1  skrll 		  fprintf (list_file, "DEFINED SYMBOLS\n");
    784  1.1  skrll 		  on_page++;
    785  1.1  skrll 		  got_some = 1;
    786  1.1  skrll 		}
    787  1.1  skrll 
    788  1.1  skrll 	      if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
    789  1.1  skrll 		{
    790  1.1  skrll 		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
    791  1.1  skrll 			   symbol_get_frag (ptr)->line->file->filename,
    792  1.1  skrll 			   symbol_get_frag (ptr)->line->line,
    793  1.1  skrll 			   segment_name (S_GET_SEGMENT (ptr)),
    794  1.1  skrll 			   buf, S_GET_NAME (ptr));
    795  1.1  skrll 		}
    796  1.1  skrll 	      else
    797  1.1  skrll 		{
    798  1.1  skrll 		  fprintf (list_file, "%33s:%s %s\n",
    799  1.1  skrll 			   segment_name (S_GET_SEGMENT (ptr)),
    800  1.1  skrll 			   buf, S_GET_NAME (ptr));
    801  1.1  skrll 		}
    802  1.1  skrll 
    803  1.1  skrll 	      on_page++;
    804  1.1  skrll 	      listing_page (0);
    805  1.1  skrll 	    }
    806  1.1  skrll 	}
    807  1.1  skrll 
    808  1.1  skrll     }
    809  1.1  skrll   if (!got_some)
    810  1.1  skrll     {
    811  1.1  skrll       fprintf (list_file, "NO DEFINED SYMBOLS\n");
    812  1.1  skrll       on_page++;
    813  1.1  skrll     }
    814  1.1  skrll   fprintf (list_file, "\n");
    815  1.1  skrll   on_page++;
    816  1.1  skrll   listing_page (0);
    817  1.1  skrll 
    818  1.1  skrll   got_some = 0;
    819  1.1  skrll 
    820  1.1  skrll   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
    821  1.1  skrll     {
    822  1.1  skrll       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
    823  1.1  skrll 	{
    824  1.1  skrll 	  if (S_GET_SEGMENT (ptr) == undefined_section)
    825  1.1  skrll 	    {
    826  1.1  skrll 	      if (!got_some)
    827  1.1  skrll 		{
    828  1.1  skrll 		  got_some = 1;
    829  1.1  skrll 		  fprintf (list_file, "UNDEFINED SYMBOLS\n");
    830  1.1  skrll 		  on_page++;
    831  1.1  skrll 		  listing_page (0);
    832  1.1  skrll 		}
    833  1.1  skrll 	      fprintf (list_file, "%s\n", S_GET_NAME (ptr));
    834  1.1  skrll 	      on_page++;
    835  1.1  skrll 	      listing_page (0);
    836  1.1  skrll 	    }
    837  1.1  skrll 	}
    838  1.1  skrll     }
    839  1.1  skrll   if (!got_some)
    840  1.1  skrll     {
    841  1.1  skrll       fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
    842  1.1  skrll       on_page++;
    843  1.1  skrll       listing_page (0);
    844  1.1  skrll     }
    845  1.1  skrll }
    846  1.1  skrll 
    847  1.1  skrll static void
    848  1.1  skrll print_source (file_info_type *current_file, list_info_type *list,
    849  1.1  skrll 	      char *buffer, unsigned int width)
    850  1.1  skrll {
    851  1.1  skrll   if (!current_file->at_end)
    852  1.1  skrll     {
    853  1.1  skrll       while (current_file->linenum < list->hll_line
    854  1.1  skrll 	     && !current_file->at_end)
    855  1.1  skrll 	{
    856  1.1  skrll 	  char *p = buffer_line (current_file, buffer, width);
    857  1.1  skrll 
    858  1.1  skrll 	  fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
    859  1.1  skrll 		   current_file->filename, p);
    860  1.1  skrll 	  on_page++;
    861  1.1  skrll 	  listing_page (list);
    862  1.1  skrll 	}
    863  1.1  skrll     }
    864  1.1  skrll }
    865  1.1  skrll 
    866  1.1  skrll /* Sometimes the user doesn't want to be bothered by the debugging
    867  1.1  skrll    records inserted by the compiler, see if the line is suspicious.  */
    868  1.1  skrll 
    869  1.1  skrll static int
    870  1.1  skrll debugging_pseudo (list_info_type *list, const char *line)
    871  1.1  skrll {
    872  1.1  skrll   static int in_debug;
    873  1.1  skrll   int was_debug;
    874  1.1  skrll 
    875  1.1  skrll   if (list->debugging)
    876  1.1  skrll     {
    877  1.1  skrll       in_debug = 1;
    878  1.1  skrll       return 1;
    879  1.1  skrll     }
    880  1.1  skrll 
    881  1.1  skrll   was_debug = in_debug;
    882  1.1  skrll   in_debug = 0;
    883  1.1  skrll 
    884  1.1  skrll   while (ISSPACE (*line))
    885  1.1  skrll     line++;
    886  1.1  skrll 
    887  1.1  skrll   if (*line != '.')
    888  1.1  skrll     {
    889  1.1  skrll #ifdef OBJ_ELF
    890  1.1  skrll       /* The ELF compiler sometimes emits blank lines after switching
    891  1.1  skrll          out of a debugging section.  If the next line drops us back
    892  1.1  skrll          into debugging information, then don't print the blank line.
    893  1.1  skrll          This is a hack for a particular compiler behaviour, not a
    894  1.1  skrll          general case.  */
    895  1.1  skrll       if (was_debug
    896  1.1  skrll 	  && *line == '\0'
    897  1.1  skrll 	  && list->next != NULL
    898  1.1  skrll 	  && list->next->debugging)
    899  1.1  skrll 	{
    900  1.1  skrll 	  in_debug = 1;
    901  1.1  skrll 	  return 1;
    902  1.1  skrll 	}
    903  1.1  skrll #endif
    904  1.1  skrll 
    905  1.1  skrll       return 0;
    906  1.1  skrll     }
    907  1.1  skrll 
    908  1.1  skrll   line++;
    909  1.1  skrll 
    910  1.1  skrll   if (strncmp (line, "def", 3) == 0)
    911  1.1  skrll     return 1;
    912  1.1  skrll   if (strncmp (line, "val", 3) == 0)
    913  1.1  skrll     return 1;
    914  1.1  skrll   if (strncmp (line, "scl", 3) == 0)
    915  1.1  skrll     return 1;
    916  1.1  skrll   if (strncmp (line, "line", 4) == 0)
    917  1.1  skrll     return 1;
    918  1.1  skrll   if (strncmp (line, "endef", 5) == 0)
    919  1.1  skrll     return 1;
    920  1.1  skrll   if (strncmp (line, "ln", 2) == 0)
    921  1.1  skrll     return 1;
    922  1.1  skrll   if (strncmp (line, "type", 4) == 0)
    923  1.1  skrll     return 1;
    924  1.1  skrll   if (strncmp (line, "size", 4) == 0)
    925  1.1  skrll     return 1;
    926  1.1  skrll   if (strncmp (line, "dim", 3) == 0)
    927  1.1  skrll     return 1;
    928  1.1  skrll   if (strncmp (line, "tag", 3) == 0)
    929  1.1  skrll     return 1;
    930  1.1  skrll   if (strncmp (line, "stabs", 5) == 0)
    931  1.1  skrll     return 1;
    932  1.1  skrll   if (strncmp (line, "stabn", 5) == 0)
    933  1.1  skrll     return 1;
    934  1.1  skrll 
    935  1.1  skrll   return 0;
    936  1.1  skrll }
    937  1.1  skrll 
    938  1.1  skrll static void
    939  1.1  skrll listing_listing (char *name ATTRIBUTE_UNUSED)
    940  1.1  skrll {
    941  1.1  skrll   list_info_type *list = head;
    942  1.1  skrll   file_info_type *current_hll_file = (file_info_type *) NULL;
    943  1.1  skrll   char *message;
    944  1.1  skrll   char *buffer;
    945  1.1  skrll   char *p;
    946  1.1  skrll   int show_listing = 1;
    947  1.1  skrll   unsigned int width;
    948  1.1  skrll 
    949  1.1  skrll   buffer = xmalloc (listing_rhs_width);
    950  1.1  skrll   data_buffer = xmalloc (MAX_BYTES);
    951  1.1  skrll   eject = 1;
    952  1.1  skrll   list = head->next;
    953  1.1  skrll 
    954  1.1  skrll   while (list)
    955  1.1  skrll     {
    956  1.1  skrll       unsigned int list_line;
    957  1.1  skrll 
    958  1.1  skrll       width = listing_rhs_width > paper_width ? paper_width :
    959  1.1  skrll 	listing_rhs_width;
    960  1.1  skrll 
    961  1.1  skrll       list_line = list->line;
    962  1.1  skrll       switch (list->edict)
    963  1.1  skrll 	{
    964  1.1  skrll 	case EDICT_LIST:
    965  1.1  skrll 	  /* Skip all lines up to the current.  */
    966  1.1  skrll 	  list_line--;
    967  1.1  skrll 	  break;
    968  1.1  skrll 	case EDICT_NOLIST:
    969  1.1  skrll 	  show_listing--;
    970  1.1  skrll 	  break;
    971  1.1  skrll 	case EDICT_NOLIST_NEXT:
    972  1.1  skrll 	  if (show_listing == 0)
    973  1.1  skrll 	    list_line--;
    974  1.1  skrll 	  break;
    975  1.1  skrll 	case EDICT_EJECT:
    976  1.1  skrll 	  break;
    977  1.1  skrll 	case EDICT_NONE:
    978  1.1  skrll 	  break;
    979  1.1  skrll 	case EDICT_TITLE:
    980  1.1  skrll 	  title = list->edict_arg;
    981  1.1  skrll 	  break;
    982  1.1  skrll 	case EDICT_SBTTL:
    983  1.1  skrll 	  subtitle = list->edict_arg;
    984  1.1  skrll 	  break;
    985  1.1  skrll 	default:
    986  1.1  skrll 	  abort ();
    987  1.1  skrll 	}
    988  1.1  skrll 
    989  1.1  skrll       if (show_listing <= 0)
    990  1.1  skrll 	{
    991  1.1  skrll 	  while (list->file->linenum < list_line
    992  1.1  skrll 		 && !list->file->at_end)
    993  1.1  skrll 	    p = buffer_line (list->file, buffer, width);
    994  1.1  skrll 	}
    995  1.1  skrll 
    996  1.1  skrll       if (list->edict == EDICT_LIST
    997  1.1  skrll 	  || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
    998  1.1  skrll 	{
    999  1.1  skrll 	  /* Enable listing for the single line that caused the enable.  */
   1000  1.1  skrll 	  list_line++;
   1001  1.1  skrll 	  show_listing++;
   1002  1.1  skrll 	}
   1003  1.1  skrll 
   1004  1.1  skrll       if (show_listing > 0)
   1005  1.1  skrll 	{
   1006  1.1  skrll 	  /* Scan down the list and print all the stuff which can be done
   1007  1.1  skrll 	     with this line (or lines).  */
   1008  1.1  skrll 	  message = 0;
   1009  1.1  skrll 
   1010  1.1  skrll 	  if (list->hll_file)
   1011  1.1  skrll 	    current_hll_file = list->hll_file;
   1012  1.1  skrll 
   1013  1.1  skrll 	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
   1014  1.1  skrll 	    print_source (current_hll_file, list, buffer, width);
   1015  1.1  skrll 
   1016  1.1  skrll 	  if (list->line_contents)
   1017  1.1  skrll 	    {
   1018  1.1  skrll 	      if (!((listing & LISTING_NODEBUG)
   1019  1.1  skrll 		    && debugging_pseudo (list, list->line_contents)))
   1020  1.1  skrll 		print_lines (list,
   1021  1.1  skrll 			     list->file->linenum == 0 ? list->line : list->file->linenum,
   1022  1.1  skrll 			     list->line_contents, calc_hex (list));
   1023  1.1  skrll 
   1024  1.1  skrll 	      free (list->line_contents);
   1025  1.1  skrll 	      list->line_contents = NULL;
   1026  1.1  skrll 	    }
   1027  1.1  skrll 	  else
   1028  1.1  skrll 	    {
   1029  1.1  skrll 	      while (list->file->linenum < list_line
   1030  1.1  skrll 		     && !list->file->at_end)
   1031  1.1  skrll 		{
   1032  1.1  skrll 		  unsigned int address;
   1033  1.1  skrll 
   1034  1.1  skrll 		  p = buffer_line (list->file, buffer, width);
   1035  1.1  skrll 
   1036  1.1  skrll 		  if (list->file->linenum < list_line)
   1037  1.1  skrll 		    address = ~(unsigned int) 0;
   1038  1.1  skrll 		  else
   1039  1.1  skrll 		    address = calc_hex (list);
   1040  1.1  skrll 
   1041  1.1  skrll 		  if (!((listing & LISTING_NODEBUG)
   1042  1.1  skrll 			&& debugging_pseudo (list, p)))
   1043  1.1  skrll 		    print_lines (list, list->file->linenum, p, address);
   1044  1.1  skrll 		}
   1045  1.1  skrll 	    }
   1046  1.1  skrll 
   1047  1.1  skrll 	  if (list->edict == EDICT_EJECT)
   1048  1.1  skrll 	    eject = 1;
   1049  1.1  skrll 	}
   1050  1.1  skrll 
   1051  1.1  skrll       if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
   1052  1.1  skrll 	--show_listing;
   1053  1.1  skrll 
   1054  1.1  skrll       list = list->next;
   1055  1.1  skrll     }
   1056  1.1  skrll 
   1057  1.1  skrll   free (buffer);
   1058  1.1  skrll   free (data_buffer);
   1059  1.1  skrll   data_buffer = NULL;
   1060  1.1  skrll }
   1061  1.1  skrll 
   1062  1.1  skrll /* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
   1063  1.1  skrll 
   1064  1.1  skrll static void
   1065  1.1  skrll print_timestamp (void)
   1066  1.1  skrll {
   1067  1.1  skrll   const time_t now = time (NULL);
   1068  1.1  skrll   struct tm * timestamp;
   1069  1.1  skrll   char stampstr[MAX_DATELEN];
   1070  1.1  skrll 
   1071  1.1  skrll   /* Any portable way to obtain subsecond values???  */
   1072  1.1  skrll   timestamp = localtime (&now);
   1073  1.1  skrll   strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
   1074  1.1  skrll   fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
   1075  1.1  skrll }
   1076  1.1  skrll 
   1077  1.1  skrll static void
   1078  1.1  skrll print_single_option (char * opt, int *pos)
   1079  1.1  skrll {
   1080  1.1  skrll   int opt_len = strlen (opt);
   1081  1.1  skrll 
   1082  1.1  skrll    if ((*pos + opt_len) < paper_width)
   1083  1.1  skrll      {
   1084  1.1  skrll         fprintf (list_file, _("%s "), opt);
   1085  1.1  skrll         *pos = *pos + opt_len;
   1086  1.1  skrll      }
   1087  1.1  skrll    else
   1088  1.1  skrll      {
   1089  1.1  skrll         fprintf (list_file, _("\n\t%s "), opt);
   1090  1.1  skrll         *pos = opt_len;
   1091  1.1  skrll      }
   1092  1.1  skrll }
   1093  1.1  skrll 
   1094  1.1  skrll /* Print options passed to as.  */
   1095  1.1  skrll 
   1096  1.1  skrll static void
   1097  1.1  skrll print_options (char ** argv)
   1098  1.1  skrll {
   1099  1.1  skrll   const char *field_name = _("\n options passed\t: ");
   1100  1.1  skrll   int pos = strlen (field_name);
   1101  1.1  skrll   char **p;
   1102  1.1  skrll 
   1103  1.1  skrll   fputs (field_name, list_file);
   1104  1.1  skrll   for (p = &argv[1]; *p != NULL; p++)
   1105  1.1  skrll     if (**p == '-')
   1106  1.1  skrll       {
   1107  1.1  skrll         /* Ignore these.  */
   1108  1.1  skrll         if (strcmp (*p, "-o") == 0)
   1109  1.1  skrll           {
   1110  1.1  skrll             if (p[1] != NULL)
   1111  1.1  skrll               p++;
   1112  1.1  skrll             continue;
   1113  1.1  skrll           }
   1114  1.1  skrll         if (strcmp (*p, "-v") == 0)
   1115  1.1  skrll           continue;
   1116  1.1  skrll 
   1117  1.1  skrll         print_single_option (*p, &pos);
   1118  1.1  skrll       }
   1119  1.1  skrll }
   1120  1.1  skrll 
   1121  1.1  skrll /* Print a first section with basic info like file names, as version,
   1122  1.1  skrll    options passed, target, and timestamp.
   1123  1.1  skrll    The format of this section is as follows:
   1124  1.1  skrll 
   1125  1.1  skrll    AS VERSION
   1126  1.1  skrll 
   1127  1.1  skrll    fieldname TAB ':' fieldcontents
   1128  1.1  skrll   { TAB fieldcontents-cont }  */
   1129  1.1  skrll 
   1130  1.1  skrll static void
   1131  1.1  skrll listing_general_info (char ** argv)
   1132  1.1  skrll {
   1133  1.1  skrll   /* Print the stuff on the first line.  */
   1134  1.1  skrll   eject = 1;
   1135  1.1  skrll   listing_page (0);
   1136  1.1  skrll 
   1137  1.1  skrll   fprintf (list_file,
   1138  1.1  skrll            _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
   1139  1.1  skrll            VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
   1140  1.1  skrll   print_options (argv);
   1141  1.1  skrll   fprintf (list_file, _("\n input file    \t: %s"), fn);
   1142  1.1  skrll   fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
   1143  1.1  skrll   fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
   1144  1.1  skrll   print_timestamp ();
   1145  1.1  skrll }
   1146  1.1  skrll 
   1147  1.1  skrll void
   1148  1.1  skrll listing_print (char *name, char **argv)
   1149  1.1  skrll {
   1150  1.1  skrll   int using_stdout;
   1151  1.1  skrll 
   1152  1.1  skrll   title = "";
   1153  1.1  skrll   subtitle = "";
   1154  1.1  skrll 
   1155  1.1  skrll   if (name == NULL)
   1156  1.1  skrll     {
   1157  1.1  skrll       list_file = stdout;
   1158  1.1  skrll       using_stdout = 1;
   1159  1.1  skrll     }
   1160  1.1  skrll   else
   1161  1.1  skrll     {
   1162  1.1  skrll       list_file = fopen (name, FOPEN_WT);
   1163  1.1  skrll       if (list_file != NULL)
   1164  1.1  skrll 	using_stdout = 0;
   1165  1.1  skrll       else
   1166  1.1  skrll 	{
   1167  1.1  skrll 	  as_warn (_("can't open %s: %s"), name, xstrerror (errno));
   1168  1.1  skrll 	  list_file = stdout;
   1169  1.1  skrll 	  using_stdout = 1;
   1170  1.1  skrll 	}
   1171  1.1  skrll     }
   1172  1.1  skrll 
   1173  1.1  skrll   if (listing & LISTING_NOFORM)
   1174  1.1  skrll     paper_height = 0;
   1175  1.1  skrll 
   1176  1.1  skrll   if (listing & LISTING_GENERAL)
   1177  1.1  skrll     listing_general_info (argv);
   1178  1.1  skrll 
   1179  1.1  skrll   if (listing & LISTING_LISTING)
   1180  1.1  skrll     listing_listing (name);
   1181  1.1  skrll 
   1182  1.1  skrll   if (listing & LISTING_SYMBOLS)
   1183  1.1  skrll     list_symbol_table ();
   1184  1.1  skrll 
   1185  1.1  skrll   if (! using_stdout)
   1186  1.1  skrll     {
   1187  1.1  skrll       if (fclose (list_file) == EOF)
   1188  1.1  skrll 	as_warn (_("can't close %s: %s"), name, xstrerror (errno));
   1189  1.1  skrll     }
   1190  1.1  skrll 
   1191  1.1  skrll   if (last_open_file)
   1192  1.1  skrll     fclose (last_open_file);
   1193  1.1  skrll }
   1194  1.1  skrll 
   1195  1.1  skrll void
   1196  1.1  skrll listing_file (const char *name)
   1197  1.1  skrll {
   1198  1.1  skrll   fn = name;
   1199  1.1  skrll }
   1200  1.1  skrll 
   1201  1.1  skrll void
   1202  1.1  skrll listing_eject (int ignore ATTRIBUTE_UNUSED)
   1203  1.1  skrll {
   1204  1.1  skrll   if (listing)
   1205  1.1  skrll     listing_tail->edict = EDICT_EJECT;
   1206  1.1  skrll }
   1207  1.1  skrll 
   1208  1.1  skrll void
   1209  1.1  skrll listing_flags (int ignore ATTRIBUTE_UNUSED)
   1210  1.1  skrll {
   1211  1.1  skrll   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
   1212  1.1  skrll     input_line_pointer++;
   1213  1.1  skrll 
   1214  1.1  skrll }
   1215  1.1  skrll 
   1216  1.1  skrll /* Turn listing on or off.  An argument of 0 means to turn off
   1217  1.1  skrll    listing.  An argument of 1 means to turn on listing.  An argument
   1218  1.1  skrll    of 2 means to turn off listing, but as of the next line; that is,
   1219  1.1  skrll    the current line should be listed, but the next line should not.  */
   1220  1.1  skrll 
   1221  1.1  skrll void
   1222  1.1  skrll listing_list (int on)
   1223  1.1  skrll {
   1224  1.1  skrll   if (listing)
   1225  1.1  skrll     {
   1226  1.1  skrll       switch (on)
   1227  1.1  skrll 	{
   1228  1.1  skrll 	case 0:
   1229  1.1  skrll 	  if (listing_tail->edict == EDICT_LIST)
   1230  1.1  skrll 	    listing_tail->edict = EDICT_NONE;
   1231  1.1  skrll 	  else
   1232  1.1  skrll 	    listing_tail->edict = EDICT_NOLIST;
   1233  1.1  skrll 	  break;
   1234  1.1  skrll 	case 1:
   1235  1.1  skrll 	  if (listing_tail->edict == EDICT_NOLIST
   1236  1.1  skrll 	      || listing_tail->edict == EDICT_NOLIST_NEXT)
   1237  1.1  skrll 	    listing_tail->edict = EDICT_NONE;
   1238  1.1  skrll 	  else
   1239  1.1  skrll 	    listing_tail->edict = EDICT_LIST;
   1240  1.1  skrll 	  break;
   1241  1.1  skrll 	case 2:
   1242  1.1  skrll 	  listing_tail->edict = EDICT_NOLIST_NEXT;
   1243  1.1  skrll 	  break;
   1244  1.1  skrll 	default:
   1245  1.1  skrll 	  abort ();
   1246  1.1  skrll 	}
   1247  1.1  skrll     }
   1248  1.1  skrll }
   1249  1.1  skrll 
   1250  1.1  skrll void
   1251  1.1  skrll listing_psize (int width_only)
   1252  1.1  skrll {
   1253  1.1  skrll   if (! width_only)
   1254  1.1  skrll     {
   1255  1.1  skrll       paper_height = get_absolute_expression ();
   1256  1.1  skrll 
   1257  1.1  skrll       if (paper_height < 0 || paper_height > 1000)
   1258  1.1  skrll 	{
   1259  1.1  skrll 	  paper_height = 0;
   1260  1.1  skrll 	  as_warn (_("strange paper height, set to no form"));
   1261  1.1  skrll 	}
   1262  1.1  skrll 
   1263  1.1  skrll       if (*input_line_pointer != ',')
   1264  1.1  skrll 	{
   1265  1.1  skrll 	  demand_empty_rest_of_line ();
   1266  1.1  skrll 	  return;
   1267  1.1  skrll 	}
   1268  1.1  skrll 
   1269  1.1  skrll       ++input_line_pointer;
   1270  1.1  skrll     }
   1271  1.1  skrll 
   1272  1.1  skrll   paper_width = get_absolute_expression ();
   1273  1.1  skrll 
   1274  1.1  skrll   demand_empty_rest_of_line ();
   1275  1.1  skrll }
   1276  1.1  skrll 
   1277  1.1  skrll void
   1278  1.1  skrll listing_nopage (int ignore ATTRIBUTE_UNUSED)
   1279  1.1  skrll {
   1280  1.1  skrll   paper_height = 0;
   1281  1.1  skrll }
   1282  1.1  skrll 
   1283  1.1  skrll void
   1284  1.1  skrll listing_title (int depth)
   1285  1.1  skrll {
   1286  1.1  skrll   int quoted;
   1287  1.1  skrll   char *start;
   1288  1.1  skrll   char *ttl;
   1289  1.1  skrll   unsigned int length;
   1290  1.1  skrll 
   1291  1.1  skrll   SKIP_WHITESPACE ();
   1292  1.1  skrll   if (*input_line_pointer != '\"')
   1293  1.1  skrll     quoted = 0;
   1294  1.1  skrll   else
   1295  1.1  skrll     {
   1296  1.1  skrll       quoted = 1;
   1297  1.1  skrll       ++input_line_pointer;
   1298  1.1  skrll     }
   1299  1.1  skrll 
   1300  1.1  skrll   start = input_line_pointer;
   1301  1.1  skrll 
   1302  1.1  skrll   while (*input_line_pointer)
   1303  1.1  skrll     {
   1304  1.1  skrll       if (quoted
   1305  1.1  skrll 	  ? *input_line_pointer == '\"'
   1306  1.1  skrll 	  : is_end_of_line[(unsigned char) *input_line_pointer])
   1307  1.1  skrll 	{
   1308  1.1  skrll 	  if (listing)
   1309  1.1  skrll 	    {
   1310  1.1  skrll 	      length = input_line_pointer - start;
   1311  1.1  skrll 	      ttl = xmalloc (length + 1);
   1312  1.1  skrll 	      memcpy (ttl, start, length);
   1313  1.1  skrll 	      ttl[length] = 0;
   1314  1.1  skrll 	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
   1315  1.1  skrll 	      listing_tail->edict_arg = ttl;
   1316  1.1  skrll 	    }
   1317  1.1  skrll 	  if (quoted)
   1318  1.1  skrll 	    input_line_pointer++;
   1319  1.1  skrll 	  demand_empty_rest_of_line ();
   1320  1.1  skrll 	  return;
   1321  1.1  skrll 	}
   1322  1.1  skrll       else if (*input_line_pointer == '\n')
   1323  1.1  skrll 	{
   1324  1.1  skrll 	  as_bad (_("new line in title"));
   1325  1.1  skrll 	  demand_empty_rest_of_line ();
   1326  1.1  skrll 	  return;
   1327  1.1  skrll 	}
   1328  1.1  skrll       else
   1329  1.1  skrll 	{
   1330  1.1  skrll 	  input_line_pointer++;
   1331  1.1  skrll 	}
   1332  1.1  skrll     }
   1333  1.1  skrll }
   1334  1.1  skrll 
   1335  1.1  skrll void
   1336  1.1  skrll listing_source_line (unsigned int line)
   1337  1.1  skrll {
   1338  1.1  skrll   if (listing)
   1339  1.1  skrll     {
   1340  1.1  skrll       new_frag ();
   1341  1.1  skrll       listing_tail->hll_line = line;
   1342  1.1  skrll       new_frag ();
   1343  1.1  skrll     }
   1344  1.1  skrll }
   1345  1.1  skrll 
   1346  1.1  skrll void
   1347  1.1  skrll listing_source_file (const char *file)
   1348  1.1  skrll {
   1349  1.1  skrll   if (listing)
   1350  1.1  skrll     listing_tail->hll_file = file_info (file);
   1351  1.1  skrll }
   1352  1.1  skrll 
   1353  1.1  skrll #else
   1354  1.1  skrll 
   1355  1.1  skrll /* Dummy functions for when compiled without listing enabled.  */
   1356  1.1  skrll 
   1357  1.1  skrll void
   1358  1.1  skrll listing_flags (int ignore)
   1359  1.1  skrll {
   1360  1.1  skrll   s_ignore (0);
   1361  1.1  skrll }
   1362  1.1  skrll 
   1363  1.1  skrll void
   1364  1.1  skrll listing_list (int on)
   1365  1.1  skrll {
   1366  1.1  skrll   s_ignore (0);
   1367  1.1  skrll }
   1368  1.1  skrll 
   1369  1.1  skrll void
   1370  1.1  skrll listing_eject (int ignore)
   1371  1.1  skrll {
   1372  1.1  skrll   s_ignore (0);
   1373  1.1  skrll }
   1374  1.1  skrll 
   1375  1.1  skrll void
   1376  1.1  skrll listing_psize (int ignore)
   1377  1.1  skrll {
   1378  1.1  skrll   s_ignore (0);
   1379  1.1  skrll }
   1380  1.1  skrll 
   1381  1.1  skrll void
   1382  1.1  skrll listing_nopage (int ignore)
   1383  1.1  skrll {
   1384  1.1  skrll   s_ignore (0);
   1385  1.1  skrll }
   1386  1.1  skrll 
   1387  1.1  skrll void
   1388  1.1  skrll listing_title (int depth)
   1389  1.1  skrll {
   1390  1.1  skrll   s_ignore (0);
   1391  1.1  skrll }
   1392  1.1  skrll 
   1393  1.1  skrll void
   1394  1.1  skrll listing_file (const char *name)
   1395  1.1  skrll {
   1396  1.1  skrll }
   1397  1.1  skrll 
   1398  1.1  skrll void
   1399  1.1  skrll listing_newline (char *name)
   1400  1.1  skrll {
   1401  1.1  skrll }
   1402  1.1  skrll 
   1403  1.1  skrll void
   1404  1.1  skrll listing_source_line (unsigned int n)
   1405  1.1  skrll {
   1406  1.1  skrll }
   1407  1.1  skrll 
   1408  1.1  skrll void
   1409  1.1  skrll listing_source_file (const char *n)
   1410  1.1  skrll {
   1411  1.1  skrll }
   1412  1.1  skrll 
   1413  1.1  skrll #endif
   1414