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