Home | History | Annotate | Line # | Download | only in gas
listing.c revision 1.1.1.5.12.1
      1           1.1     skrll /* listing.c - maintain assembly listings
      2  1.1.1.5.12.1  pgoyette    Copyright (C) 1991-2018 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.5.12.1  pgoyette  	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     skrll       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
    322           1.1     skrll 	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
    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.5.12.1  pgoyette   /* PR 21977 - use the physical file name not the logical one unless high
    328  1.1.1.5.12.1  pgoyette      level source files are being included in the listing.  */
    329  1.1.1.5.12.1  pgoyette   if (listing & LISTING_HLL)
    330  1.1.1.5.12.1  pgoyette     file = as_where (&line);
    331  1.1.1.5.12.1  pgoyette   else
    332  1.1.1.5.12.1  pgoyette     file = as_where_physical (&line);
    333  1.1.1.5.12.1  pgoyette 
    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     skrll       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
    437           1.1     skrll 	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
    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     skrll   /* Leave room for null.  */
    512           1.1     skrll   size -= 1;
    513           1.1     skrll 
    514       1.1.1.2  christos   c = fgetc (last_open_file);
    515       1.1.1.2  christos 
    516       1.1.1.2  christos   while (c != EOF && c != '\n' && c != '\r')
    517           1.1     skrll     {
    518           1.1     skrll       if (count < size)
    519           1.1     skrll 	*p++ = c;
    520           1.1     skrll       count++;
    521           1.1     skrll 
    522           1.1     skrll       c = fgetc (last_open_file);
    523       1.1.1.2  christos     }
    524           1.1     skrll 
    525       1.1.1.2  christos   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
    526       1.1.1.2  christos      is followed by '\r', swallow that as well.  */
    527       1.1.1.2  christos   if (c == '\r' || c == '\n')
    528       1.1.1.2  christos     {
    529       1.1.1.2  christos       int next = fgetc (last_open_file);
    530       1.1.1.2  christos 
    531       1.1.1.2  christos       if ((c == '\r' && next != '\n')
    532       1.1.1.2  christos 	  || (c == '\n' && next != '\r'))
    533       1.1.1.2  christos 	ungetc (next, last_open_file);
    534           1.1     skrll     }
    535       1.1.1.2  christos 
    536           1.1     skrll   if (c == EOF)
    537           1.1     skrll     {
    538           1.1     skrll       file->at_end = 1;
    539           1.1     skrll       if (count + 2 < size)
    540           1.1     skrll 	{
    541           1.1     skrll 	  *p++ = '.';
    542           1.1     skrll 	  *p++ = '.';
    543           1.1     skrll 	  *p++ = '.';
    544           1.1     skrll 	}
    545           1.1     skrll     }
    546           1.1     skrll   file->linenum++;
    547           1.1     skrll   *p++ = 0;
    548           1.1     skrll   return line;
    549           1.1     skrll }
    550           1.1     skrll 
    551       1.1.1.2  christos 
    552       1.1.1.2  christos /* This function rewinds the requested file back to the line requested,
    553       1.1.1.2  christos    reads it in again into the buffer provided and then restores the file
    554       1.1.1.5  christos    back to its original location.  */
    555       1.1.1.2  christos 
    556       1.1.1.5  christos static void
    557       1.1.1.2  christos rebuffer_line (file_info_type *  file,
    558       1.1.1.2  christos 	       unsigned int      linenum,
    559       1.1.1.2  christos 	       char *            buffer,
    560       1.1.1.2  christos 	       unsigned int      size)
    561       1.1.1.2  christos {
    562       1.1.1.2  christos   unsigned int count = 0;
    563       1.1.1.4  christos   unsigned int current_line;
    564       1.1.1.2  christos   char * p = buffer;
    565       1.1.1.2  christos   long pos;
    566       1.1.1.4  christos   long pos2;
    567       1.1.1.2  christos   int c;
    568       1.1.1.4  christos   bfd_boolean found = FALSE;
    569       1.1.1.2  christos 
    570       1.1.1.2  christos   /* Sanity checks.  */
    571       1.1.1.4  christos   if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
    572       1.1.1.5  christos     return;
    573       1.1.1.2  christos 
    574       1.1.1.2  christos   /* Check the cache and see if we last used this file.  */
    575       1.1.1.2  christos   if (last_open_file_info == NULL || file != last_open_file_info)
    576       1.1.1.2  christos     {
    577       1.1.1.2  christos       if (last_open_file)
    578       1.1.1.2  christos 	{
    579       1.1.1.2  christos 	  last_open_file_info->pos = ftell (last_open_file);
    580       1.1.1.2  christos 	  fclose (last_open_file);
    581       1.1.1.2  christos 	}
    582       1.1.1.2  christos 
    583       1.1.1.2  christos       /* Open the file in the binary mode so that ftell above can
    584       1.1.1.2  christos 	 return a reliable value that we can feed to fseek below.  */
    585       1.1.1.2  christos       last_open_file_info = file;
    586       1.1.1.2  christos       last_open_file = fopen (file->filename, FOPEN_RB);
    587       1.1.1.2  christos       if (last_open_file == NULL)
    588       1.1.1.2  christos 	{
    589       1.1.1.2  christos 	  file->at_end = 1;
    590       1.1.1.5  christos 	  return;
    591       1.1.1.2  christos 	}
    592       1.1.1.2  christos 
    593       1.1.1.2  christos       /* Seek to where we were last time this file was open.  */
    594       1.1.1.2  christos       if (file->pos)
    595       1.1.1.2  christos 	fseek (last_open_file, file->pos, SEEK_SET);
    596       1.1.1.2  christos     }
    597       1.1.1.2  christos 
    598       1.1.1.2  christos   /* Remember where we are in the current file.  */
    599       1.1.1.4  christos   pos2 = pos = ftell (last_open_file);
    600       1.1.1.4  christos   if (pos < 3)
    601       1.1.1.5  christos     return;
    602       1.1.1.4  christos   current_line = file->linenum;
    603       1.1.1.2  christos 
    604       1.1.1.4  christos   /* Leave room for the nul at the end of the buffer.  */
    605       1.1.1.4  christos   size -= 1;
    606       1.1.1.4  christos   buffer[size] = 0;
    607       1.1.1.2  christos 
    608       1.1.1.4  christos   /* Increment the current line count by one.
    609       1.1.1.4  christos      This is to allow for the fact that we are searching for the
    610       1.1.1.4  christos      start of a previous line, but we do this by detecting end-of-line
    611       1.1.1.4  christos      character(s) not start-of-line characters.  */
    612       1.1.1.4  christos   ++ current_line;
    613       1.1.1.4  christos 
    614       1.1.1.4  christos   while (pos2 > 0 && ! found)
    615       1.1.1.2  christos     {
    616       1.1.1.4  christos       char * ptr;
    617       1.1.1.4  christos 
    618       1.1.1.4  christos       /* Move backwards through the file, looking for earlier lines.  */
    619       1.1.1.4  christos       pos2 = (long) size > pos2 ? 0 : pos2 - size;
    620       1.1.1.4  christos       fseek (last_open_file, pos2, SEEK_SET);
    621       1.1.1.4  christos 
    622       1.1.1.4  christos       /* Our caller has kindly provided us with a buffer, so we use it.  */
    623       1.1.1.4  christos       if (fread (buffer, 1, size, last_open_file) != size)
    624       1.1.1.2  christos 	{
    625       1.1.1.4  christos 	  as_warn (_("unable to rebuffer file: %s\n"), file->filename);
    626       1.1.1.5  christos 	  return;
    627       1.1.1.2  christos 	}
    628       1.1.1.2  christos 
    629       1.1.1.4  christos       for (ptr = buffer + size; ptr >= buffer; -- ptr)
    630       1.1.1.2  christos 	{
    631       1.1.1.4  christos 	  if (*ptr == '\n')
    632       1.1.1.4  christos 	    {
    633       1.1.1.4  christos 	      -- current_line;
    634       1.1.1.2  christos 
    635       1.1.1.4  christos 	      if (current_line == linenum)
    636       1.1.1.4  christos 		{
    637       1.1.1.4  christos 		  /* We have found the start of the line we seek.  */
    638       1.1.1.4  christos 		  found = TRUE;
    639       1.1.1.4  christos 
    640       1.1.1.4  christos 		  /* FIXME: We could skip the read-in-the-line code
    641       1.1.1.4  christos 		     below if we know that we already have the whole
    642       1.1.1.4  christos 		     line in the buffer.  */
    643       1.1.1.4  christos 
    644       1.1.1.4  christos 		  /* Advance pos2 to the newline character we have just located.  */
    645       1.1.1.4  christos 		  pos2 += (ptr - buffer);
    646       1.1.1.4  christos 
    647       1.1.1.4  christos 		  /* Skip the newline and, if present, the carriage return.  */
    648       1.1.1.4  christos 		  if (ptr + 1 == buffer + size)
    649       1.1.1.4  christos 		    {
    650       1.1.1.4  christos 		      ++pos2;
    651       1.1.1.4  christos 		      if (fgetc (last_open_file) == '\r')
    652       1.1.1.4  christos 			++ pos2;
    653       1.1.1.4  christos 		    }
    654       1.1.1.4  christos 		  else
    655       1.1.1.4  christos 		    pos2 += (ptr[1] == '\r' ? 2 : 1);
    656       1.1.1.4  christos 
    657       1.1.1.4  christos 		  /* Move the file pointer to this location.  */
    658       1.1.1.4  christos 		  fseek (last_open_file, pos2, SEEK_SET);
    659       1.1.1.4  christos 		  break;
    660       1.1.1.4  christos 		}
    661       1.1.1.4  christos 	    }
    662       1.1.1.2  christos 	}
    663       1.1.1.2  christos     }
    664       1.1.1.2  christos 
    665       1.1.1.2  christos   /* Read in the line.  */
    666       1.1.1.2  christos   c = fgetc (last_open_file);
    667       1.1.1.2  christos 
    668       1.1.1.2  christos   while (c != EOF && c != '\n' && c != '\r')
    669       1.1.1.2  christos     {
    670       1.1.1.2  christos       if (count < size)
    671       1.1.1.2  christos 	*p++ = c;
    672       1.1.1.2  christos       count++;
    673       1.1.1.2  christos 
    674       1.1.1.2  christos       c = fgetc (last_open_file);
    675       1.1.1.2  christos     }
    676       1.1.1.2  christos 
    677       1.1.1.2  christos   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
    678       1.1.1.2  christos      is followed by '\r', swallow that as well.  */
    679       1.1.1.2  christos   if (c == '\r' || c == '\n')
    680       1.1.1.2  christos     {
    681       1.1.1.2  christos       int next = fgetc (last_open_file);
    682       1.1.1.2  christos 
    683       1.1.1.2  christos       if ((c == '\r' && next != '\n')
    684       1.1.1.2  christos 	  || (c == '\n' && next != '\r'))
    685       1.1.1.2  christos 	ungetc (next, last_open_file);
    686       1.1.1.2  christos     }
    687       1.1.1.2  christos 
    688       1.1.1.2  christos   /* Terminate the line.  */
    689       1.1.1.2  christos   *p++ = 0;
    690       1.1.1.2  christos 
    691       1.1.1.2  christos   /* Reset the file position.  */
    692       1.1.1.2  christos   fseek (last_open_file, pos, SEEK_SET);
    693       1.1.1.2  christos }
    694       1.1.1.2  christos 
    695           1.1     skrll static const char *fn;
    696       1.1.1.5  christos static unsigned int eject;	/* Eject pending.  */
    697       1.1.1.5  christos static unsigned int page;	/* Current page number.  */
    698       1.1.1.5  christos static const char *title;	/* Current title.  */
    699       1.1.1.5  christos static const char *subtitle;	/* Current subtitle.  */
    700       1.1.1.5  christos static unsigned int on_page;	/* Number of lines printed on current page.  */
    701           1.1     skrll 
    702           1.1     skrll static void
    703           1.1     skrll listing_page (list_info_type *list)
    704           1.1     skrll {
    705           1.1     skrll   /* Grope around, see if we can see a title or subtitle edict coming up
    706           1.1     skrll      soon.  (we look down 10 lines of the page and see if it's there)  */
    707           1.1     skrll   if ((eject || (on_page >= (unsigned int) paper_height))
    708           1.1     skrll       && paper_height != 0)
    709           1.1     skrll     {
    710           1.1     skrll       unsigned int c = 10;
    711           1.1     skrll       int had_title = 0;
    712           1.1     skrll       int had_subtitle = 0;
    713           1.1     skrll 
    714           1.1     skrll       page++;
    715           1.1     skrll 
    716           1.1     skrll       while (c != 0 && list)
    717           1.1     skrll 	{
    718           1.1     skrll 	  if (list->edict == EDICT_SBTTL && !had_subtitle)
    719           1.1     skrll 	    {
    720           1.1     skrll 	      had_subtitle = 1;
    721           1.1     skrll 	      subtitle = list->edict_arg;
    722           1.1     skrll 	    }
    723           1.1     skrll 	  if (list->edict == EDICT_TITLE && !had_title)
    724           1.1     skrll 	    {
    725           1.1     skrll 	      had_title = 1;
    726           1.1     skrll 	      title = list->edict_arg;
    727           1.1     skrll 	    }
    728           1.1     skrll 	  list = list->next;
    729           1.1     skrll 	  c--;
    730           1.1     skrll 	}
    731           1.1     skrll 
    732           1.1     skrll       if (page > 1)
    733           1.1     skrll 	{
    734           1.1     skrll 	  fprintf (list_file, "\f");
    735           1.1     skrll 	}
    736           1.1     skrll 
    737           1.1     skrll       fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
    738           1.1     skrll       fprintf (list_file, "%s\n", title);
    739           1.1     skrll       fprintf (list_file, "%s\n", subtitle);
    740           1.1     skrll       on_page = 3;
    741           1.1     skrll       eject = 0;
    742           1.1     skrll     }
    743           1.1     skrll }
    744           1.1     skrll 
    745       1.1.1.2  christos /* Print a line into the list_file.  Update the line count
    746       1.1.1.2  christos    and if necessary start a new page.  */
    747       1.1.1.2  christos 
    748       1.1.1.2  christos static void
    749       1.1.1.2  christos emit_line (list_info_type * list, const char * format, ...)
    750       1.1.1.2  christos {
    751       1.1.1.2  christos   va_list args;
    752       1.1.1.2  christos 
    753       1.1.1.2  christos   va_start (args, format);
    754       1.1.1.2  christos 
    755       1.1.1.2  christos   vfprintf (list_file, format, args);
    756       1.1.1.2  christos   on_page++;
    757       1.1.1.2  christos   listing_page (list);
    758       1.1.1.2  christos 
    759       1.1.1.2  christos   va_end (args);
    760       1.1.1.2  christos }
    761       1.1.1.2  christos 
    762           1.1     skrll static unsigned int
    763           1.1     skrll calc_hex (list_info_type *list)
    764           1.1     skrll {
    765           1.1     skrll   int data_buffer_size;
    766           1.1     skrll   list_info_type *first = list;
    767           1.1     skrll   unsigned int address = ~(unsigned int) 0;
    768           1.1     skrll   fragS *frag;
    769           1.1     skrll   fragS *frag_ptr;
    770           1.1     skrll   unsigned int octet_in_frag;
    771           1.1     skrll 
    772           1.1     skrll   /* Find first frag which says it belongs to this line.  */
    773           1.1     skrll   frag = list->frag;
    774           1.1     skrll   while (frag && frag->line != list)
    775           1.1     skrll     frag = frag->fr_next;
    776           1.1     skrll 
    777           1.1     skrll   frag_ptr = frag;
    778           1.1     skrll 
    779           1.1     skrll   data_buffer_size = 0;
    780           1.1     skrll 
    781           1.1     skrll   /* Dump all the frags which belong to this line.  */
    782           1.1     skrll   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
    783           1.1     skrll     {
    784           1.1     skrll       /* Print as many bytes from the fixed part as is sensible.  */
    785           1.1     skrll       octet_in_frag = 0;
    786           1.1     skrll       while ((offsetT) octet_in_frag < frag_ptr->fr_fix
    787           1.1     skrll 	     && data_buffer_size < MAX_BYTES - 3)
    788           1.1     skrll 	{
    789           1.1     skrll 	  if (address == ~(unsigned int) 0)
    790           1.1     skrll 	    address = frag_ptr->fr_address / OCTETS_PER_BYTE;
    791           1.1     skrll 
    792           1.1     skrll 	  sprintf (data_buffer + data_buffer_size,
    793           1.1     skrll 		   "%02X",
    794           1.1     skrll 		   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
    795           1.1     skrll 	  data_buffer_size += 2;
    796           1.1     skrll 	  octet_in_frag++;
    797           1.1     skrll 	}
    798           1.1     skrll       if (frag_ptr->fr_type == rs_fill)
    799           1.1     skrll 	{
    800           1.1     skrll 	  unsigned int var_rep_max = octet_in_frag;
    801           1.1     skrll 	  unsigned int var_rep_idx = octet_in_frag;
    802           1.1     skrll 
    803           1.1     skrll 	  /* Print as many bytes from the variable part as is sensible.  */
    804           1.1     skrll 	  while (((offsetT) octet_in_frag
    805           1.1     skrll 		  < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
    806           1.1     skrll 		 && data_buffer_size < MAX_BYTES - 3)
    807           1.1     skrll 	    {
    808           1.1     skrll 	      if (address == ~(unsigned int) 0)
    809           1.1     skrll 		address = frag_ptr->fr_address / OCTETS_PER_BYTE;
    810           1.1     skrll 
    811           1.1     skrll 	      sprintf (data_buffer + data_buffer_size,
    812           1.1     skrll 		       "%02X",
    813           1.1     skrll 		       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
    814           1.1     skrll 	      data_buffer_size += 2;
    815           1.1     skrll 
    816           1.1     skrll 	      var_rep_idx++;
    817           1.1     skrll 	      octet_in_frag++;
    818           1.1     skrll 
    819           1.1     skrll 	      if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
    820           1.1     skrll 		var_rep_idx = var_rep_max;
    821           1.1     skrll 	    }
    822           1.1     skrll 	}
    823           1.1     skrll 
    824           1.1     skrll       frag_ptr = frag_ptr->fr_next;
    825           1.1     skrll     }
    826           1.1     skrll   data_buffer[data_buffer_size] = '\0';
    827           1.1     skrll   return address;
    828           1.1     skrll }
    829           1.1     skrll 
    830           1.1     skrll static void
    831           1.1     skrll print_lines (list_info_type *list, unsigned int lineno,
    832       1.1.1.5  christos 	     const char *string, unsigned int address)
    833           1.1     skrll {
    834           1.1     skrll   unsigned int idx;
    835           1.1     skrll   unsigned int nchars;
    836           1.1     skrll   unsigned int lines;
    837           1.1     skrll   unsigned int octet_in_word = 0;
    838           1.1     skrll   char *src = data_buffer;
    839           1.1     skrll   int cur;
    840       1.1.1.3  christos   struct list_message *msg;
    841           1.1     skrll 
    842           1.1     skrll   /* Print the stuff on the first line.  */
    843           1.1     skrll   listing_page (list);
    844           1.1     skrll   nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
    845           1.1     skrll 
    846           1.1     skrll   /* Print the hex for the first line.  */
    847           1.1     skrll   if (address == ~(unsigned int) 0)
    848           1.1     skrll     {
    849           1.1     skrll       fprintf (list_file, "% 4d     ", lineno);
    850           1.1     skrll       for (idx = 0; idx < nchars; idx++)
    851           1.1     skrll 	fprintf (list_file, " ");
    852           1.1     skrll 
    853       1.1.1.2  christos       emit_line (NULL, "\t%s\n", string ? string : "");
    854           1.1     skrll       return;
    855           1.1     skrll     }
    856           1.1     skrll 
    857           1.1     skrll   if (had_errors ())
    858           1.1     skrll     fprintf (list_file, "% 4d ???? ", lineno);
    859           1.1     skrll   else
    860           1.1     skrll     fprintf (list_file, "% 4d %04x ", lineno, address);
    861           1.1     skrll 
    862           1.1     skrll   /* And the data to go along with it.  */
    863           1.1     skrll   idx = 0;
    864           1.1     skrll   cur = 0;
    865           1.1     skrll   while (src[cur] && idx < nchars)
    866           1.1     skrll     {
    867           1.1     skrll       int offset;
    868           1.1     skrll       offset = cur;
    869           1.1     skrll       fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
    870           1.1     skrll       cur += 2;
    871           1.1     skrll       octet_in_word++;
    872           1.1     skrll 
    873           1.1     skrll       if (octet_in_word == LISTING_WORD_SIZE)
    874           1.1     skrll 	{
    875           1.1     skrll 	  fprintf (list_file, " ");
    876           1.1     skrll 	  idx++;
    877           1.1     skrll 	  octet_in_word = 0;
    878           1.1     skrll 	}
    879           1.1     skrll 
    880           1.1     skrll       idx += 2;
    881           1.1     skrll     }
    882           1.1     skrll 
    883           1.1     skrll   for (; idx < nchars; idx++)
    884           1.1     skrll     fprintf (list_file, " ");
    885           1.1     skrll 
    886       1.1.1.2  christos   emit_line (list, "\t%s\n", string ? string : "");
    887           1.1     skrll 
    888       1.1.1.3  christos   for (msg = list->messages; msg; msg = msg->next)
    889       1.1.1.3  christos     emit_line (list, "****  %s\n", msg->message);
    890           1.1     skrll 
    891           1.1     skrll   for (lines = 0;
    892           1.1     skrll        lines < (unsigned int) listing_lhs_cont_lines
    893           1.1     skrll 	 && src[cur];
    894           1.1     skrll        lines++)
    895           1.1     skrll     {
    896           1.1     skrll       nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
    897           1.1     skrll       idx = 0;
    898           1.1     skrll 
    899           1.1     skrll       /* Print any more lines of data, but more compactly.  */
    900           1.1     skrll       fprintf (list_file, "% 4d      ", lineno);
    901           1.1     skrll 
    902           1.1     skrll       while (src[cur] && idx < nchars)
    903           1.1     skrll 	{
    904           1.1     skrll 	  int offset;
    905           1.1     skrll 	  offset = cur;
    906           1.1     skrll 	  fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
    907           1.1     skrll 	  cur += 2;
    908           1.1     skrll 	  idx += 2;
    909           1.1     skrll 	  octet_in_word++;
    910           1.1     skrll 
    911           1.1     skrll 	  if (octet_in_word == LISTING_WORD_SIZE)
    912           1.1     skrll 	    {
    913           1.1     skrll 	      fprintf (list_file, " ");
    914           1.1     skrll 	      idx++;
    915           1.1     skrll 	      octet_in_word = 0;
    916           1.1     skrll 	    }
    917           1.1     skrll 	}
    918           1.1     skrll 
    919       1.1.1.2  christos       emit_line (list, "\n");
    920           1.1     skrll     }
    921           1.1     skrll }
    922           1.1     skrll 
    923           1.1     skrll static void
    924           1.1     skrll list_symbol_table (void)
    925           1.1     skrll {
    926           1.1     skrll   extern symbolS *symbol_rootP;
    927           1.1     skrll   int got_some = 0;
    928           1.1     skrll 
    929           1.1     skrll   symbolS *ptr;
    930           1.1     skrll   eject = 1;
    931       1.1.1.2  christos   listing_page (NULL);
    932           1.1     skrll 
    933           1.1     skrll   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
    934           1.1     skrll     {
    935           1.1     skrll       if (SEG_NORMAL (S_GET_SEGMENT (ptr))
    936           1.1     skrll 	  || S_GET_SEGMENT (ptr) == absolute_section)
    937           1.1     skrll 	{
    938           1.1     skrll 	  /* Don't report section symbols.  They are not interesting.  */
    939           1.1     skrll 	  if (symbol_section_p (ptr))
    940           1.1     skrll 	    continue;
    941           1.1     skrll 
    942           1.1     skrll 	  if (S_GET_NAME (ptr))
    943           1.1     skrll 	    {
    944           1.1     skrll 	      char buf[30], fmt[8];
    945           1.1     skrll 	      valueT val = S_GET_VALUE (ptr);
    946           1.1     skrll 
    947           1.1     skrll 	      /* @@ Note that this is dependent on the compilation options,
    948           1.1     skrll 		 not solely on the target characteristics.  */
    949           1.1     skrll 	      if (sizeof (val) == 4 && sizeof (int) == 4)
    950           1.1     skrll 		sprintf (buf, "%08lx", (unsigned long) val);
    951           1.1     skrll 	      else if (sizeof (val) <= sizeof (unsigned long))
    952           1.1     skrll 		{
    953           1.1     skrll 		  sprintf (fmt, "%%0%lulx",
    954           1.1     skrll 			   (unsigned long) (sizeof (val) * 2));
    955           1.1     skrll 		  sprintf (buf, fmt, (unsigned long) val);
    956           1.1     skrll 		}
    957           1.1     skrll #if defined (BFD64)
    958           1.1     skrll 	      else if (sizeof (val) > 4)
    959           1.1     skrll 		sprintf_vma (buf, val);
    960           1.1     skrll #endif
    961           1.1     skrll 	      else
    962           1.1     skrll 		abort ();
    963           1.1     skrll 
    964           1.1     skrll 	      if (!got_some)
    965           1.1     skrll 		{
    966           1.1     skrll 		  fprintf (list_file, "DEFINED SYMBOLS\n");
    967           1.1     skrll 		  on_page++;
    968           1.1     skrll 		  got_some = 1;
    969           1.1     skrll 		}
    970           1.1     skrll 
    971           1.1     skrll 	      if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
    972           1.1     skrll 		{
    973           1.1     skrll 		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
    974           1.1     skrll 			   symbol_get_frag (ptr)->line->file->filename,
    975           1.1     skrll 			   symbol_get_frag (ptr)->line->line,
    976           1.1     skrll 			   segment_name (S_GET_SEGMENT (ptr)),
    977           1.1     skrll 			   buf, S_GET_NAME (ptr));
    978           1.1     skrll 		}
    979           1.1     skrll 	      else
    980           1.1     skrll 		{
    981           1.1     skrll 		  fprintf (list_file, "%33s:%s %s\n",
    982           1.1     skrll 			   segment_name (S_GET_SEGMENT (ptr)),
    983           1.1     skrll 			   buf, S_GET_NAME (ptr));
    984           1.1     skrll 		}
    985           1.1     skrll 
    986           1.1     skrll 	      on_page++;
    987       1.1.1.2  christos 	      listing_page (NULL);
    988           1.1     skrll 	    }
    989           1.1     skrll 	}
    990           1.1     skrll 
    991           1.1     skrll     }
    992           1.1     skrll   if (!got_some)
    993           1.1     skrll     {
    994           1.1     skrll       fprintf (list_file, "NO DEFINED SYMBOLS\n");
    995           1.1     skrll       on_page++;
    996           1.1     skrll     }
    997       1.1.1.2  christos   emit_line (NULL, "\n");
    998           1.1     skrll 
    999           1.1     skrll   got_some = 0;
   1000           1.1     skrll 
   1001           1.1     skrll   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
   1002           1.1     skrll     {
   1003           1.1     skrll       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
   1004           1.1     skrll 	{
   1005           1.1     skrll 	  if (S_GET_SEGMENT (ptr) == undefined_section)
   1006           1.1     skrll 	    {
   1007           1.1     skrll 	      if (!got_some)
   1008           1.1     skrll 		{
   1009           1.1     skrll 		  got_some = 1;
   1010       1.1.1.2  christos 
   1011       1.1.1.2  christos 		  emit_line (NULL, "UNDEFINED SYMBOLS\n");
   1012           1.1     skrll 		}
   1013       1.1.1.2  christos 
   1014       1.1.1.2  christos 	      emit_line (NULL, "%s\n", S_GET_NAME (ptr));
   1015           1.1     skrll 	    }
   1016           1.1     skrll 	}
   1017           1.1     skrll     }
   1018       1.1.1.2  christos 
   1019           1.1     skrll   if (!got_some)
   1020       1.1.1.2  christos     emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
   1021           1.1     skrll }
   1022           1.1     skrll 
   1023       1.1.1.2  christos typedef struct cached_line
   1024           1.1     skrll {
   1025       1.1.1.2  christos   file_info_type * file;
   1026       1.1.1.2  christos   unsigned int     line;
   1027       1.1.1.2  christos   char             buffer [LISTING_RHS_WIDTH];
   1028       1.1.1.2  christos } cached_line;
   1029       1.1.1.2  christos 
   1030       1.1.1.2  christos static void
   1031       1.1.1.2  christos print_source (file_info_type *  current_file,
   1032       1.1.1.2  christos 	      list_info_type *  list,
   1033       1.1.1.2  christos 	      unsigned int      width)
   1034       1.1.1.2  christos {
   1035       1.1.1.2  christos #define NUM_CACHE_LINES  3
   1036       1.1.1.2  christos   static cached_line cached_lines[NUM_CACHE_LINES];
   1037       1.1.1.2  christos   static int next_free_line = 0;
   1038       1.1.1.2  christos   cached_line * cache = NULL;
   1039       1.1.1.2  christos 
   1040       1.1.1.2  christos   if (current_file->linenum > list->hll_line
   1041       1.1.1.2  christos       && list->hll_line > 0)
   1042       1.1.1.2  christos     {
   1043       1.1.1.2  christos       /* This can happen with modern optimizing compilers.  The source
   1044       1.1.1.2  christos 	 lines from the high level language input program are split up
   1045       1.1.1.2  christos 	 and interleaved, meaning the line number we want to display
   1046       1.1.1.2  christos 	 (list->hll_line) can have already been displayed.  We have
   1047       1.1.1.2  christos 	 three choices:
   1048       1.1.1.2  christos 
   1049       1.1.1.2  christos 	   a. Do nothing, since we have already displayed the source
   1050       1.1.1.2  christos 	      line.  This was the old behaviour.
   1051       1.1.1.2  christos 
   1052       1.1.1.2  christos 	   b. Display the particular line requested again, but only
   1053       1.1.1.2  christos 	      that line.  This is the new behaviour.
   1054       1.1.1.2  christos 
   1055       1.1.1.2  christos 	   c. Display the particular line requested again and reset
   1056       1.1.1.2  christos 	      the current_file->line_num value so that we redisplay
   1057       1.1.1.2  christos 	      all the following lines as well the next time we
   1058       1.1.1.2  christos 	      encounter a larger line number.  */
   1059       1.1.1.2  christos       int i;
   1060       1.1.1.2  christos 
   1061       1.1.1.2  christos       /* Check the cache, maybe we already have the line saved.  */
   1062       1.1.1.2  christos       for (i = 0; i < NUM_CACHE_LINES; i++)
   1063       1.1.1.2  christos 	if (cached_lines[i].file == current_file
   1064       1.1.1.2  christos 	    && cached_lines[i].line == list->hll_line)
   1065       1.1.1.2  christos 	  {
   1066       1.1.1.2  christos 	    cache = cached_lines + i;
   1067       1.1.1.2  christos 	    break;
   1068       1.1.1.2  christos 	  }
   1069       1.1.1.2  christos 
   1070       1.1.1.2  christos       if (i == NUM_CACHE_LINES)
   1071       1.1.1.2  christos 	{
   1072       1.1.1.2  christos 	  cache = cached_lines + next_free_line;
   1073       1.1.1.2  christos 	  next_free_line ++;
   1074       1.1.1.2  christos 	  if (next_free_line == NUM_CACHE_LINES)
   1075       1.1.1.2  christos 	    next_free_line = 0;
   1076       1.1.1.2  christos 
   1077       1.1.1.2  christos 	  cache->file = current_file;
   1078       1.1.1.2  christos 	  cache->line = list->hll_line;
   1079       1.1.1.2  christos 	  cache->buffer[0] = 0;
   1080       1.1.1.2  christos 	  rebuffer_line (current_file, cache->line, cache->buffer, width);
   1081       1.1.1.2  christos 	}
   1082       1.1.1.2  christos 
   1083       1.1.1.2  christos       emit_line (list, "%4u:%-13s **** %s\n",
   1084       1.1.1.2  christos 		 cache->line, cache->file->filename, cache->buffer);
   1085       1.1.1.2  christos       return;
   1086       1.1.1.2  christos     }
   1087       1.1.1.2  christos 
   1088           1.1     skrll   if (!current_file->at_end)
   1089           1.1     skrll     {
   1090       1.1.1.2  christos       int num_lines_shown = 0;
   1091       1.1.1.2  christos 
   1092           1.1     skrll       while (current_file->linenum < list->hll_line
   1093           1.1     skrll 	     && !current_file->at_end)
   1094           1.1     skrll 	{
   1095       1.1.1.5  christos 	  const char *p;
   1096       1.1.1.2  christos 
   1097       1.1.1.2  christos 	  cache = cached_lines + next_free_line;
   1098       1.1.1.2  christos 	  cache->file = current_file;
   1099       1.1.1.2  christos 	  cache->line = current_file->linenum + 1;
   1100       1.1.1.2  christos 	  cache->buffer[0] = 0;
   1101       1.1.1.2  christos 	  p = buffer_line (current_file, cache->buffer, width);
   1102       1.1.1.2  christos 
   1103       1.1.1.2  christos 	  /* Cache optimization:  If printing a group of lines
   1104       1.1.1.2  christos 	     cache the first and last lines in the group.  */
   1105       1.1.1.2  christos 	  if (num_lines_shown == 0)
   1106       1.1.1.2  christos 	    {
   1107       1.1.1.2  christos 	      next_free_line ++;
   1108       1.1.1.2  christos 	      if (next_free_line == NUM_CACHE_LINES)
   1109       1.1.1.2  christos 		next_free_line = 0;
   1110       1.1.1.2  christos 	    }
   1111           1.1     skrll 
   1112       1.1.1.2  christos 	  emit_line (list, "%4u:%-13s **** %s\n",
   1113       1.1.1.2  christos 		     cache->line, cache->file->filename, p);
   1114       1.1.1.2  christos 	  num_lines_shown ++;
   1115           1.1     skrll 	}
   1116           1.1     skrll     }
   1117           1.1     skrll }
   1118           1.1     skrll 
   1119           1.1     skrll /* Sometimes the user doesn't want to be bothered by the debugging
   1120           1.1     skrll    records inserted by the compiler, see if the line is suspicious.  */
   1121           1.1     skrll 
   1122           1.1     skrll static int
   1123           1.1     skrll debugging_pseudo (list_info_type *list, const char *line)
   1124           1.1     skrll {
   1125       1.1.1.2  christos #ifdef OBJ_ELF
   1126           1.1     skrll   static int in_debug;
   1127           1.1     skrll   int was_debug;
   1128       1.1.1.2  christos #endif
   1129           1.1     skrll 
   1130           1.1     skrll   if (list->debugging)
   1131           1.1     skrll     {
   1132       1.1.1.2  christos #ifdef OBJ_ELF
   1133           1.1     skrll       in_debug = 1;
   1134       1.1.1.2  christos #endif
   1135           1.1     skrll       return 1;
   1136           1.1     skrll     }
   1137       1.1.1.2  christos #ifdef OBJ_ELF
   1138           1.1     skrll   was_debug = in_debug;
   1139           1.1     skrll   in_debug = 0;
   1140       1.1.1.2  christos #endif
   1141           1.1     skrll 
   1142           1.1     skrll   while (ISSPACE (*line))
   1143           1.1     skrll     line++;
   1144           1.1     skrll 
   1145           1.1     skrll   if (*line != '.')
   1146           1.1     skrll     {
   1147           1.1     skrll #ifdef OBJ_ELF
   1148           1.1     skrll       /* The ELF compiler sometimes emits blank lines after switching
   1149           1.1     skrll          out of a debugging section.  If the next line drops us back
   1150           1.1     skrll          into debugging information, then don't print the blank line.
   1151           1.1     skrll          This is a hack for a particular compiler behaviour, not a
   1152           1.1     skrll          general case.  */
   1153           1.1     skrll       if (was_debug
   1154           1.1     skrll 	  && *line == '\0'
   1155           1.1     skrll 	  && list->next != NULL
   1156           1.1     skrll 	  && list->next->debugging)
   1157           1.1     skrll 	{
   1158           1.1     skrll 	  in_debug = 1;
   1159           1.1     skrll 	  return 1;
   1160           1.1     skrll 	}
   1161           1.1     skrll #endif
   1162           1.1     skrll 
   1163           1.1     skrll       return 0;
   1164           1.1     skrll     }
   1165           1.1     skrll 
   1166           1.1     skrll   line++;
   1167           1.1     skrll 
   1168           1.1     skrll   if (strncmp (line, "def", 3) == 0)
   1169           1.1     skrll     return 1;
   1170           1.1     skrll   if (strncmp (line, "val", 3) == 0)
   1171           1.1     skrll     return 1;
   1172           1.1     skrll   if (strncmp (line, "scl", 3) == 0)
   1173           1.1     skrll     return 1;
   1174           1.1     skrll   if (strncmp (line, "line", 4) == 0)
   1175           1.1     skrll     return 1;
   1176           1.1     skrll   if (strncmp (line, "endef", 5) == 0)
   1177           1.1     skrll     return 1;
   1178           1.1     skrll   if (strncmp (line, "ln", 2) == 0)
   1179           1.1     skrll     return 1;
   1180           1.1     skrll   if (strncmp (line, "type", 4) == 0)
   1181           1.1     skrll     return 1;
   1182           1.1     skrll   if (strncmp (line, "size", 4) == 0)
   1183           1.1     skrll     return 1;
   1184           1.1     skrll   if (strncmp (line, "dim", 3) == 0)
   1185           1.1     skrll     return 1;
   1186           1.1     skrll   if (strncmp (line, "tag", 3) == 0)
   1187           1.1     skrll     return 1;
   1188           1.1     skrll   if (strncmp (line, "stabs", 5) == 0)
   1189           1.1     skrll     return 1;
   1190           1.1     skrll   if (strncmp (line, "stabn", 5) == 0)
   1191           1.1     skrll     return 1;
   1192           1.1     skrll 
   1193           1.1     skrll   return 0;
   1194           1.1     skrll }
   1195           1.1     skrll 
   1196           1.1     skrll static void
   1197           1.1     skrll listing_listing (char *name ATTRIBUTE_UNUSED)
   1198           1.1     skrll {
   1199           1.1     skrll   list_info_type *list = head;
   1200           1.1     skrll   file_info_type *current_hll_file = (file_info_type *) NULL;
   1201           1.1     skrll   char *buffer;
   1202       1.1.1.5  christos   const char *p;
   1203           1.1     skrll   int show_listing = 1;
   1204           1.1     skrll   unsigned int width;
   1205           1.1     skrll 
   1206       1.1.1.5  christos   buffer = XNEWVEC (char, listing_rhs_width);
   1207       1.1.1.5  christos   data_buffer = XNEWVEC (char, MAX_BYTES);
   1208           1.1     skrll   eject = 1;
   1209           1.1     skrll   list = head->next;
   1210           1.1     skrll 
   1211           1.1     skrll   while (list)
   1212           1.1     skrll     {
   1213           1.1     skrll       unsigned int list_line;
   1214           1.1     skrll 
   1215           1.1     skrll       width = listing_rhs_width > paper_width ? paper_width :
   1216           1.1     skrll 	listing_rhs_width;
   1217           1.1     skrll 
   1218           1.1     skrll       list_line = list->line;
   1219           1.1     skrll       switch (list->edict)
   1220           1.1     skrll 	{
   1221           1.1     skrll 	case EDICT_LIST:
   1222           1.1     skrll 	  /* Skip all lines up to the current.  */
   1223           1.1     skrll 	  list_line--;
   1224           1.1     skrll 	  break;
   1225           1.1     skrll 	case EDICT_NOLIST:
   1226           1.1     skrll 	  show_listing--;
   1227           1.1     skrll 	  break;
   1228           1.1     skrll 	case EDICT_NOLIST_NEXT:
   1229           1.1     skrll 	  if (show_listing == 0)
   1230           1.1     skrll 	    list_line--;
   1231           1.1     skrll 	  break;
   1232           1.1     skrll 	case EDICT_EJECT:
   1233           1.1     skrll 	  break;
   1234           1.1     skrll 	case EDICT_NONE:
   1235           1.1     skrll 	  break;
   1236           1.1     skrll 	case EDICT_TITLE:
   1237           1.1     skrll 	  title = list->edict_arg;
   1238           1.1     skrll 	  break;
   1239           1.1     skrll 	case EDICT_SBTTL:
   1240           1.1     skrll 	  subtitle = list->edict_arg;
   1241           1.1     skrll 	  break;
   1242           1.1     skrll 	default:
   1243           1.1     skrll 	  abort ();
   1244           1.1     skrll 	}
   1245           1.1     skrll 
   1246           1.1     skrll       if (show_listing <= 0)
   1247           1.1     skrll 	{
   1248           1.1     skrll 	  while (list->file->linenum < list_line
   1249           1.1     skrll 		 && !list->file->at_end)
   1250           1.1     skrll 	    p = buffer_line (list->file, buffer, width);
   1251           1.1     skrll 	}
   1252           1.1     skrll 
   1253           1.1     skrll       if (list->edict == EDICT_LIST
   1254           1.1     skrll 	  || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
   1255           1.1     skrll 	{
   1256           1.1     skrll 	  /* Enable listing for the single line that caused the enable.  */
   1257           1.1     skrll 	  list_line++;
   1258           1.1     skrll 	  show_listing++;
   1259           1.1     skrll 	}
   1260           1.1     skrll 
   1261           1.1     skrll       if (show_listing > 0)
   1262           1.1     skrll 	{
   1263           1.1     skrll 	  /* Scan down the list and print all the stuff which can be done
   1264           1.1     skrll 	     with this line (or lines).  */
   1265           1.1     skrll 	  if (list->hll_file)
   1266           1.1     skrll 	    current_hll_file = list->hll_file;
   1267           1.1     skrll 
   1268           1.1     skrll 	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
   1269       1.1.1.2  christos 	    print_source (current_hll_file, list, width);
   1270           1.1     skrll 
   1271           1.1     skrll 	  if (list->line_contents)
   1272           1.1     skrll 	    {
   1273           1.1     skrll 	      if (!((listing & LISTING_NODEBUG)
   1274           1.1     skrll 		    && debugging_pseudo (list, list->line_contents)))
   1275           1.1     skrll 		print_lines (list,
   1276           1.1     skrll 			     list->file->linenum == 0 ? list->line : list->file->linenum,
   1277           1.1     skrll 			     list->line_contents, calc_hex (list));
   1278           1.1     skrll 
   1279           1.1     skrll 	      free (list->line_contents);
   1280           1.1     skrll 	      list->line_contents = NULL;
   1281           1.1     skrll 	    }
   1282           1.1     skrll 	  else
   1283           1.1     skrll 	    {
   1284           1.1     skrll 	      while (list->file->linenum < list_line
   1285           1.1     skrll 		     && !list->file->at_end)
   1286           1.1     skrll 		{
   1287           1.1     skrll 		  unsigned int address;
   1288           1.1     skrll 
   1289           1.1     skrll 		  p = buffer_line (list->file, buffer, width);
   1290           1.1     skrll 
   1291           1.1     skrll 		  if (list->file->linenum < list_line)
   1292           1.1     skrll 		    address = ~(unsigned int) 0;
   1293           1.1     skrll 		  else
   1294           1.1     skrll 		    address = calc_hex (list);
   1295           1.1     skrll 
   1296           1.1     skrll 		  if (!((listing & LISTING_NODEBUG)
   1297           1.1     skrll 			&& debugging_pseudo (list, p)))
   1298           1.1     skrll 		    print_lines (list, list->file->linenum, p, address);
   1299           1.1     skrll 		}
   1300           1.1     skrll 	    }
   1301           1.1     skrll 
   1302           1.1     skrll 	  if (list->edict == EDICT_EJECT)
   1303           1.1     skrll 	    eject = 1;
   1304           1.1     skrll 	}
   1305           1.1     skrll 
   1306           1.1     skrll       if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
   1307           1.1     skrll 	--show_listing;
   1308           1.1     skrll 
   1309           1.1     skrll       list = list->next;
   1310           1.1     skrll     }
   1311           1.1     skrll 
   1312           1.1     skrll   free (buffer);
   1313           1.1     skrll   free (data_buffer);
   1314           1.1     skrll   data_buffer = NULL;
   1315           1.1     skrll }
   1316           1.1     skrll 
   1317           1.1     skrll /* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
   1318           1.1     skrll 
   1319           1.1     skrll static void
   1320           1.1     skrll print_timestamp (void)
   1321           1.1     skrll {
   1322           1.1     skrll   const time_t now = time (NULL);
   1323           1.1     skrll   struct tm * timestamp;
   1324           1.1     skrll   char stampstr[MAX_DATELEN];
   1325           1.1     skrll 
   1326           1.1     skrll   /* Any portable way to obtain subsecond values???  */
   1327           1.1     skrll   timestamp = localtime (&now);
   1328           1.1     skrll   strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
   1329           1.1     skrll   fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
   1330           1.1     skrll }
   1331           1.1     skrll 
   1332           1.1     skrll static void
   1333           1.1     skrll print_single_option (char * opt, int *pos)
   1334           1.1     skrll {
   1335           1.1     skrll   int opt_len = strlen (opt);
   1336           1.1     skrll 
   1337           1.1     skrll    if ((*pos + opt_len) < paper_width)
   1338           1.1     skrll      {
   1339           1.1     skrll         fprintf (list_file, _("%s "), opt);
   1340           1.1     skrll         *pos = *pos + opt_len;
   1341           1.1     skrll      }
   1342           1.1     skrll    else
   1343           1.1     skrll      {
   1344           1.1     skrll         fprintf (list_file, _("\n\t%s "), opt);
   1345           1.1     skrll         *pos = opt_len;
   1346           1.1     skrll      }
   1347           1.1     skrll }
   1348           1.1     skrll 
   1349           1.1     skrll /* Print options passed to as.  */
   1350           1.1     skrll 
   1351           1.1     skrll static void
   1352           1.1     skrll print_options (char ** argv)
   1353           1.1     skrll {
   1354           1.1     skrll   const char *field_name = _("\n options passed\t: ");
   1355           1.1     skrll   int pos = strlen (field_name);
   1356           1.1     skrll   char **p;
   1357           1.1     skrll 
   1358           1.1     skrll   fputs (field_name, list_file);
   1359           1.1     skrll   for (p = &argv[1]; *p != NULL; p++)
   1360           1.1     skrll     if (**p == '-')
   1361           1.1     skrll       {
   1362           1.1     skrll         /* Ignore these.  */
   1363           1.1     skrll         if (strcmp (*p, "-o") == 0)
   1364           1.1     skrll           {
   1365           1.1     skrll             if (p[1] != NULL)
   1366           1.1     skrll               p++;
   1367           1.1     skrll             continue;
   1368           1.1     skrll           }
   1369           1.1     skrll         if (strcmp (*p, "-v") == 0)
   1370           1.1     skrll           continue;
   1371           1.1     skrll 
   1372           1.1     skrll         print_single_option (*p, &pos);
   1373           1.1     skrll       }
   1374           1.1     skrll }
   1375           1.1     skrll 
   1376           1.1     skrll /* Print a first section with basic info like file names, as version,
   1377           1.1     skrll    options passed, target, and timestamp.
   1378           1.1     skrll    The format of this section is as follows:
   1379           1.1     skrll 
   1380           1.1     skrll    AS VERSION
   1381           1.1     skrll 
   1382           1.1     skrll    fieldname TAB ':' fieldcontents
   1383           1.1     skrll   { TAB fieldcontents-cont }  */
   1384           1.1     skrll 
   1385           1.1     skrll static void
   1386           1.1     skrll listing_general_info (char ** argv)
   1387           1.1     skrll {
   1388           1.1     skrll   /* Print the stuff on the first line.  */
   1389           1.1     skrll   eject = 1;
   1390       1.1.1.2  christos   listing_page (NULL);
   1391           1.1     skrll 
   1392           1.1     skrll   fprintf (list_file,
   1393           1.1     skrll            _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
   1394           1.1     skrll            VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
   1395           1.1     skrll   print_options (argv);
   1396           1.1     skrll   fprintf (list_file, _("\n input file    \t: %s"), fn);
   1397           1.1     skrll   fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
   1398           1.1     skrll   fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
   1399           1.1     skrll   print_timestamp ();
   1400           1.1     skrll }
   1401           1.1     skrll 
   1402           1.1     skrll void
   1403           1.1     skrll listing_print (char *name, char **argv)
   1404           1.1     skrll {
   1405           1.1     skrll   int using_stdout;
   1406           1.1     skrll 
   1407           1.1     skrll   title = "";
   1408           1.1     skrll   subtitle = "";
   1409           1.1     skrll 
   1410           1.1     skrll   if (name == NULL)
   1411           1.1     skrll     {
   1412           1.1     skrll       list_file = stdout;
   1413           1.1     skrll       using_stdout = 1;
   1414           1.1     skrll     }
   1415           1.1     skrll   else
   1416           1.1     skrll     {
   1417           1.1     skrll       list_file = fopen (name, FOPEN_WT);
   1418           1.1     skrll       if (list_file != NULL)
   1419           1.1     skrll 	using_stdout = 0;
   1420           1.1     skrll       else
   1421           1.1     skrll 	{
   1422           1.1     skrll 	  as_warn (_("can't open %s: %s"), name, xstrerror (errno));
   1423           1.1     skrll 	  list_file = stdout;
   1424           1.1     skrll 	  using_stdout = 1;
   1425           1.1     skrll 	}
   1426           1.1     skrll     }
   1427           1.1     skrll 
   1428           1.1     skrll   if (listing & LISTING_NOFORM)
   1429           1.1     skrll     paper_height = 0;
   1430           1.1     skrll 
   1431           1.1     skrll   if (listing & LISTING_GENERAL)
   1432           1.1     skrll     listing_general_info (argv);
   1433           1.1     skrll 
   1434           1.1     skrll   if (listing & LISTING_LISTING)
   1435           1.1     skrll     listing_listing (name);
   1436           1.1     skrll 
   1437           1.1     skrll   if (listing & LISTING_SYMBOLS)
   1438           1.1     skrll     list_symbol_table ();
   1439           1.1     skrll 
   1440           1.1     skrll   if (! using_stdout)
   1441           1.1     skrll     {
   1442           1.1     skrll       if (fclose (list_file) == EOF)
   1443           1.1     skrll 	as_warn (_("can't close %s: %s"), name, xstrerror (errno));
   1444           1.1     skrll     }
   1445           1.1     skrll 
   1446           1.1     skrll   if (last_open_file)
   1447           1.1     skrll     fclose (last_open_file);
   1448           1.1     skrll }
   1449           1.1     skrll 
   1450           1.1     skrll void
   1451           1.1     skrll listing_file (const char *name)
   1452           1.1     skrll {
   1453           1.1     skrll   fn = name;
   1454           1.1     skrll }
   1455           1.1     skrll 
   1456           1.1     skrll void
   1457           1.1     skrll listing_eject (int ignore ATTRIBUTE_UNUSED)
   1458           1.1     skrll {
   1459           1.1     skrll   if (listing)
   1460           1.1     skrll     listing_tail->edict = EDICT_EJECT;
   1461           1.1     skrll }
   1462           1.1     skrll 
   1463           1.1     skrll /* Turn listing on or off.  An argument of 0 means to turn off
   1464           1.1     skrll    listing.  An argument of 1 means to turn on listing.  An argument
   1465           1.1     skrll    of 2 means to turn off listing, but as of the next line; that is,
   1466           1.1     skrll    the current line should be listed, but the next line should not.  */
   1467           1.1     skrll 
   1468           1.1     skrll void
   1469           1.1     skrll listing_list (int on)
   1470           1.1     skrll {
   1471           1.1     skrll   if (listing)
   1472           1.1     skrll     {
   1473           1.1     skrll       switch (on)
   1474           1.1     skrll 	{
   1475           1.1     skrll 	case 0:
   1476           1.1     skrll 	  if (listing_tail->edict == EDICT_LIST)
   1477           1.1     skrll 	    listing_tail->edict = EDICT_NONE;
   1478           1.1     skrll 	  else
   1479           1.1     skrll 	    listing_tail->edict = EDICT_NOLIST;
   1480           1.1     skrll 	  break;
   1481           1.1     skrll 	case 1:
   1482           1.1     skrll 	  if (listing_tail->edict == EDICT_NOLIST
   1483           1.1     skrll 	      || listing_tail->edict == EDICT_NOLIST_NEXT)
   1484           1.1     skrll 	    listing_tail->edict = EDICT_NONE;
   1485           1.1     skrll 	  else
   1486           1.1     skrll 	    listing_tail->edict = EDICT_LIST;
   1487           1.1     skrll 	  break;
   1488           1.1     skrll 	case 2:
   1489           1.1     skrll 	  listing_tail->edict = EDICT_NOLIST_NEXT;
   1490           1.1     skrll 	  break;
   1491           1.1     skrll 	default:
   1492           1.1     skrll 	  abort ();
   1493           1.1     skrll 	}
   1494           1.1     skrll     }
   1495           1.1     skrll }
   1496           1.1     skrll 
   1497           1.1     skrll void
   1498           1.1     skrll listing_psize (int width_only)
   1499           1.1     skrll {
   1500           1.1     skrll   if (! width_only)
   1501           1.1     skrll     {
   1502           1.1     skrll       paper_height = get_absolute_expression ();
   1503           1.1     skrll 
   1504           1.1     skrll       if (paper_height < 0 || paper_height > 1000)
   1505           1.1     skrll 	{
   1506           1.1     skrll 	  paper_height = 0;
   1507           1.1     skrll 	  as_warn (_("strange paper height, set to no form"));
   1508           1.1     skrll 	}
   1509           1.1     skrll 
   1510           1.1     skrll       if (*input_line_pointer != ',')
   1511           1.1     skrll 	{
   1512           1.1     skrll 	  demand_empty_rest_of_line ();
   1513           1.1     skrll 	  return;
   1514           1.1     skrll 	}
   1515           1.1     skrll 
   1516           1.1     skrll       ++input_line_pointer;
   1517           1.1     skrll     }
   1518           1.1     skrll 
   1519           1.1     skrll   paper_width = get_absolute_expression ();
   1520           1.1     skrll 
   1521           1.1     skrll   demand_empty_rest_of_line ();
   1522           1.1     skrll }
   1523           1.1     skrll 
   1524           1.1     skrll void
   1525           1.1     skrll listing_nopage (int ignore ATTRIBUTE_UNUSED)
   1526           1.1     skrll {
   1527           1.1     skrll   paper_height = 0;
   1528           1.1     skrll }
   1529           1.1     skrll 
   1530           1.1     skrll void
   1531           1.1     skrll listing_title (int depth)
   1532           1.1     skrll {
   1533           1.1     skrll   int quoted;
   1534           1.1     skrll   char *start;
   1535           1.1     skrll   char *ttl;
   1536           1.1     skrll   unsigned int length;
   1537           1.1     skrll 
   1538           1.1     skrll   SKIP_WHITESPACE ();
   1539           1.1     skrll   if (*input_line_pointer != '\"')
   1540           1.1     skrll     quoted = 0;
   1541           1.1     skrll   else
   1542           1.1     skrll     {
   1543           1.1     skrll       quoted = 1;
   1544           1.1     skrll       ++input_line_pointer;
   1545           1.1     skrll     }
   1546           1.1     skrll 
   1547           1.1     skrll   start = input_line_pointer;
   1548           1.1     skrll 
   1549           1.1     skrll   while (*input_line_pointer)
   1550           1.1     skrll     {
   1551           1.1     skrll       if (quoted
   1552           1.1     skrll 	  ? *input_line_pointer == '\"'
   1553           1.1     skrll 	  : is_end_of_line[(unsigned char) *input_line_pointer])
   1554           1.1     skrll 	{
   1555           1.1     skrll 	  if (listing)
   1556           1.1     skrll 	    {
   1557           1.1     skrll 	      length = input_line_pointer - start;
   1558       1.1.1.5  christos 	      ttl = xmemdup0 (start, length);
   1559           1.1     skrll 	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
   1560           1.1     skrll 	      listing_tail->edict_arg = ttl;
   1561           1.1     skrll 	    }
   1562           1.1     skrll 	  if (quoted)
   1563           1.1     skrll 	    input_line_pointer++;
   1564           1.1     skrll 	  demand_empty_rest_of_line ();
   1565           1.1     skrll 	  return;
   1566           1.1     skrll 	}
   1567           1.1     skrll       else if (*input_line_pointer == '\n')
   1568           1.1     skrll 	{
   1569           1.1     skrll 	  as_bad (_("new line in title"));
   1570           1.1     skrll 	  demand_empty_rest_of_line ();
   1571           1.1     skrll 	  return;
   1572           1.1     skrll 	}
   1573           1.1     skrll       else
   1574           1.1     skrll 	{
   1575           1.1     skrll 	  input_line_pointer++;
   1576           1.1     skrll 	}
   1577           1.1     skrll     }
   1578           1.1     skrll }
   1579           1.1     skrll 
   1580           1.1     skrll void
   1581           1.1     skrll listing_source_line (unsigned int line)
   1582           1.1     skrll {
   1583           1.1     skrll   if (listing)
   1584           1.1     skrll     {
   1585           1.1     skrll       new_frag ();
   1586           1.1     skrll       listing_tail->hll_line = line;
   1587           1.1     skrll       new_frag ();
   1588           1.1     skrll     }
   1589           1.1     skrll }
   1590           1.1     skrll 
   1591           1.1     skrll void
   1592           1.1     skrll listing_source_file (const char *file)
   1593           1.1     skrll {
   1594           1.1     skrll   if (listing)
   1595           1.1     skrll     listing_tail->hll_file = file_info (file);
   1596           1.1     skrll }
   1597           1.1     skrll 
   1598           1.1     skrll #else
   1599           1.1     skrll 
   1600           1.1     skrll /* Dummy functions for when compiled without listing enabled.  */
   1601           1.1     skrll 
   1602           1.1     skrll void
   1603           1.1     skrll listing_list (int on)
   1604           1.1     skrll {
   1605           1.1     skrll   s_ignore (0);
   1606           1.1     skrll }
   1607           1.1     skrll 
   1608           1.1     skrll void
   1609           1.1     skrll listing_eject (int ignore)
   1610           1.1     skrll {
   1611           1.1     skrll   s_ignore (0);
   1612           1.1     skrll }
   1613           1.1     skrll 
   1614           1.1     skrll void
   1615           1.1     skrll listing_psize (int ignore)
   1616           1.1     skrll {
   1617           1.1     skrll   s_ignore (0);
   1618           1.1     skrll }
   1619           1.1     skrll 
   1620           1.1     skrll void
   1621           1.1     skrll listing_nopage (int ignore)
   1622           1.1     skrll {
   1623           1.1     skrll   s_ignore (0);
   1624           1.1     skrll }
   1625           1.1     skrll 
   1626           1.1     skrll void
   1627           1.1     skrll listing_title (int depth)
   1628           1.1     skrll {
   1629           1.1     skrll   s_ignore (0);
   1630           1.1     skrll }
   1631           1.1     skrll 
   1632           1.1     skrll void
   1633           1.1     skrll listing_file (const char *name)
   1634           1.1     skrll {
   1635           1.1     skrll }
   1636           1.1     skrll 
   1637           1.1     skrll void
   1638           1.1     skrll listing_newline (char *name)
   1639           1.1     skrll {
   1640           1.1     skrll }
   1641           1.1     skrll 
   1642           1.1     skrll void
   1643           1.1     skrll listing_source_line (unsigned int n)
   1644           1.1     skrll {
   1645           1.1     skrll }
   1646           1.1     skrll 
   1647           1.1     skrll void
   1648           1.1     skrll listing_source_file (const char *n)
   1649           1.1     skrll {
   1650           1.1     skrll }
   1651           1.1     skrll 
   1652           1.1     skrll #endif
   1653