home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / ld / ldmisc.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  11KB  |  530 lines

  1. /* ldmisc.c
  2.    Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
  3.    Written by Steve Chamberlain of Cygnus Support.
  4.  
  5. This file is part of GLD, the Gnu Linker.
  6.  
  7. GLD is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GLD is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GLD; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "libiberty.h"
  24. #include "demangle.h"
  25.  
  26. #ifdef ANSI_PROTOTYPES
  27. #include <stdarg.h>
  28. #define USE_STDARG 1
  29. #else
  30. #include <varargs.h>
  31. #define USE_STDARG 0
  32. #endif
  33.  
  34. #include "ld.h"
  35. #include "ldmisc.h"
  36. #include "ldexp.h"
  37. #include "ldlang.h"
  38. #include "ldgram.h"
  39. #include "ldlex.h"
  40. #include "ldmain.h"
  41. #include "ldfile.h"
  42.  
  43. /*
  44.  %% literal %
  45.  %F error is fatal
  46.  %P print program name
  47.  %S print script file and linenumber
  48.  %E current bfd error or errno
  49.  %I filename from a lang_input_statement_type
  50.  %B filename from a bfd
  51.  %T symbol name
  52.  %X no object output, fail return
  53.  %V hex bfd_vma
  54.  %v hex bfd_vma, no leading zeros
  55.  %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
  56.  %C clever filename:linenumber with function
  57.  %D like %C, but no function name
  58.  %G like %D, but only function name
  59.  %R info about a relent
  60.  %s arbitrary string, like printf
  61.  %d integer, like printf
  62.  %u integer, like printf
  63. */
  64.  
  65. char *
  66. demangle (string)
  67.      const char *string;
  68. {
  69.   char *res;
  70.  
  71.   if (output_bfd != NULL
  72.       && bfd_get_symbol_leading_char (output_bfd) == string[0])
  73.     ++string;
  74.  
  75.   /* This is a hack for better error reporting on XCOFF.  */
  76.   if (string[0] == '.')
  77.     ++string;
  78.  
  79.   res = cplus_demangle (string, DMGL_ANSI | DMGL_PARAMS);
  80.   return res ? res : xstrdup (string);
  81. }
  82.  
  83. static void
  84. vfinfo (fp, fmt, arg)
  85.      FILE *fp;
  86.      const char *fmt;
  87.      va_list arg;
  88. {
  89.   boolean fatal = false;
  90.  
  91.   while (*fmt != '\0')
  92.     {
  93.       while (*fmt != '%' && *fmt != '\0') 
  94.     {
  95.       putc (*fmt, fp);
  96.       fmt++;
  97.     }
  98.  
  99.       if (*fmt == '%') 
  100.     {
  101.       fmt ++;
  102.       switch (*fmt++) 
  103.         {
  104.         default:
  105.           fprintf (fp,"%%%c", fmt[-1]);
  106.           break;
  107.  
  108.         case '%':
  109.           /* literal % */
  110.           putc ('%', fp);
  111.           break;
  112.  
  113.         case 'X':
  114.           /* no object output, fail return */
  115.           config.make_executable = false;
  116.           break;
  117.  
  118.         case 'V':
  119.           /* hex bfd_vma */
  120.           {
  121.         bfd_vma value = va_arg (arg, bfd_vma);
  122.         fprintf_vma (fp, value);
  123.           }
  124.           break;
  125.  
  126.         case 'v':
  127.           /* hex bfd_vma, no leading zeros */
  128.           {
  129.         char buf[100];
  130.         char *p = buf;
  131.         bfd_vma value = va_arg (arg, bfd_vma);
  132.         sprintf_vma (p, value);
  133.         while (*p == '0')
  134.           p++;
  135.         if (!*p)
  136.           p--;
  137.         fputs (p, fp);
  138.           }
  139.           break;
  140.  
  141.         case 'W':
  142.           /* hex bfd_vma with 0x with no leading zeroes taking up
  143.                  8 spaces.  */
  144.           {
  145.         char buf[100];
  146.         bfd_vma value;
  147.         char *p;
  148.         int len;
  149.  
  150.         value = va_arg (arg, bfd_vma);
  151.         sprintf_vma (buf, value);
  152.         for (p = buf; *p == '0'; ++p)
  153.           ;
  154.         if (*p == '\0')
  155.           --p;
  156.         len = strlen (p);
  157.         while (len < 8)
  158.           {
  159.             putc (' ', fp);
  160.             ++len;
  161.           }
  162.         fprintf (fp, "0x%s", p);
  163.           }
  164.           break;
  165.  
  166.         case 'T':
  167.           /* Symbol name.  */
  168.           {
  169.         const char *name = va_arg (arg, const char *);
  170.  
  171.         if (name == (const char *) NULL)
  172.           fprintf (fp, "no symbol");
  173.         else
  174.           {
  175.             char *demangled;
  176.  
  177.             demangled = demangle (name);
  178.             fprintf (fp, "%s", demangled);
  179.             free (demangled);
  180.           }
  181.           }
  182.           break;
  183.  
  184.         case 'B':
  185.           /* filename from a bfd */
  186.           { 
  187.         bfd *abfd = va_arg (arg, bfd *);
  188.         if (abfd->my_archive)
  189.           fprintf (fp, "%s(%s)", abfd->my_archive->filename,
  190.                abfd->filename);
  191.         else
  192.           fprintf (fp, "%s", abfd->filename);
  193.           }
  194.           break;
  195.  
  196.         case 'F':
  197.           /* error is fatal */
  198.           fatal = true;
  199.           break;
  200.  
  201.         case 'P':
  202.           /* print program name */
  203.           fprintf (fp, "%s", program_name);
  204.           break;
  205.  
  206.         case 'E':
  207.           /* current bfd error or errno */
  208.           fprintf (fp, bfd_errmsg (bfd_get_error ()));
  209.           break;
  210.  
  211.         case 'I':
  212.           /* filename from a lang_input_statement_type */
  213.           {
  214.         lang_input_statement_type *i;
  215.  
  216.         i = va_arg (arg, lang_input_statement_type *);
  217.         if (bfd_my_archive (i->the_bfd) != NULL)
  218.           fprintf (fp, "(%s)",
  219.                bfd_get_filename (bfd_my_archive (i->the_bfd)));
  220.         fprintf (fp, "%s", i->local_sym_name);
  221.         if (bfd_my_archive (i->the_bfd) == NULL
  222.             && strcmp (i->local_sym_name, i->filename) != 0)
  223.           fprintf (fp, " (%s)", i->filename);
  224.           }
  225.           break;
  226.  
  227.         case 'S':
  228.           /* print script file and linenumber */
  229.           if (parsing_defsym)
  230.         fprintf (fp, "--defsym %s", lex_string);
  231.           else if (ldfile_input_filename != NULL)
  232.         fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
  233.           else
  234.         fprintf (fp, "built in linker script:%u", lineno);
  235.           break;
  236.  
  237.         case 'R':
  238.           /* Print all that's interesting about a relent */
  239.           {
  240.         arelent *relent = va_arg (arg, arelent *);
  241.     
  242.         finfo (fp, "%s+0x%v (type %s)",
  243.                (*(relent->sym_ptr_ptr))->name,
  244.                relent->addend,
  245.                relent->howto->name);
  246.           }
  247.           break;
  248.     
  249.         case 'C':
  250.         case 'D':
  251.         case 'G':
  252.           /* Clever filename:linenumber with function name if possible,
  253.          or section name as a last resort.  The arguments are a BFD,
  254.          a section, and an offset.  */
  255.           {
  256.         static bfd *last_bfd;
  257.         static char *last_file = NULL;
  258.         static char *last_function = NULL;
  259.         bfd *abfd;
  260.         asection *section;
  261.         bfd_vma offset;
  262.         lang_input_statement_type *entry;
  263.         asymbol **asymbols;
  264.         const char *filename;
  265.         const char *functionname;
  266.         unsigned int linenumber;
  267.         boolean discard_last;
  268.  
  269.         abfd = va_arg (arg, bfd *);
  270.         section = va_arg (arg, asection *);
  271.         offset = va_arg (arg, bfd_vma);
  272.  
  273.         entry = (lang_input_statement_type *) abfd->usrdata;
  274.         if (entry != (lang_input_statement_type *) NULL
  275.             && entry->asymbols != (asymbol **) NULL)
  276.           asymbols = entry->asymbols;
  277.         else
  278.           {
  279.             long symsize;
  280.             long symbol_count;
  281.  
  282.             symsize = bfd_get_symtab_upper_bound (abfd);
  283.             if (symsize < 0)
  284.               einfo ("%B%F: could not read symbols\n", abfd);
  285.             asymbols = (asymbol **) xmalloc (symsize);
  286.             symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
  287.             if (symbol_count < 0)
  288.               einfo ("%B%F: could not read symbols\n", abfd);
  289.             if (entry != (lang_input_statement_type *) NULL)
  290.               {
  291.             entry->asymbols = asymbols;
  292.             entry->symbol_count = symbol_count;
  293.               }
  294.           }
  295.  
  296.         discard_last = true;
  297.         if (bfd_find_nearest_line (abfd, section, asymbols, offset,
  298.                        &filename, &functionname,
  299.                        &linenumber))
  300.           {
  301.             if (functionname != NULL && fmt[-1] == 'G')
  302.               {
  303.             finfo (fp, "%B:", abfd);
  304.             if (filename != NULL
  305.                 && strcmp (filename, bfd_get_filename (abfd)) != 0)
  306.               fprintf (fp, "%s:", filename);
  307.             finfo (fp, "%T", functionname);
  308.               }
  309.             else if (functionname != NULL && fmt[-1] == 'C')
  310.               {
  311.             if (filename == (char *) NULL)
  312.               filename = abfd->filename;
  313.  
  314.             if (last_bfd == NULL
  315.                 || last_file == NULL
  316.                 || last_function == NULL
  317.                 || last_bfd != abfd
  318.                 || strcmp (last_file, filename) != 0
  319.                 || strcmp (last_function, functionname) != 0)
  320.               {
  321.                 /* We use abfd->filename in this initial line,
  322.                    in case filename is a .h file or something
  323.                    similarly unhelpful.  */
  324.                 finfo (fp, "%B: In function `%T':\n",
  325.                    abfd, functionname);
  326.  
  327.                 last_bfd = abfd;
  328.                 if (last_file != NULL)
  329.                   free (last_file);
  330.                 last_file = buystring (filename);
  331.                 if (last_function != NULL)
  332.                   free (last_function);
  333.                 last_function = buystring (functionname);
  334.               }
  335.             discard_last = false;
  336.             if (linenumber != 0)
  337.               fprintf (fp, "%s:%u", filename, linenumber);
  338.             else
  339.               finfo (fp, "%s(%s+0x%v)", filename, section->name,
  340.                  offset);
  341.               }
  342.             else if (filename == NULL
  343.                  || strcmp (filename, abfd->filename) == 0)
  344.               {
  345.             finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
  346.             if (linenumber != 0)
  347.               finfo (fp, ":%u", linenumber);
  348.               }
  349.             else if (linenumber != 0) 
  350.               finfo (fp, "%B:%s:%u", abfd, filename, linenumber);
  351.             else
  352.               finfo (fp, "%B(%s+0x%v):%s", abfd, section->name, offset,
  353.                  filename);
  354.           }
  355.         else
  356.           finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
  357.  
  358.         if (discard_last)
  359.           {
  360.             last_bfd = NULL;
  361.             if (last_file != NULL)
  362.               {
  363.             free (last_file);
  364.             last_file = NULL;
  365.               }
  366.             if (last_function != NULL)
  367.               {
  368.             free (last_function);
  369.             last_function = NULL;
  370.               }
  371.           }
  372.           }
  373.           break;
  374.         
  375.         case 's':
  376.           /* arbitrary string, like printf */
  377.           fprintf (fp, "%s", va_arg (arg, char *));
  378.           break;
  379.  
  380.         case 'd':
  381.           /* integer, like printf */
  382.           fprintf (fp, "%d", va_arg (arg, int));
  383.           break;
  384.  
  385.         case 'u':
  386.           /* unsigned integer, like printf */
  387.           fprintf (fp, "%u", va_arg (arg, unsigned int));
  388.           break;
  389.         }
  390.     }
  391.     }
  392.  
  393.   if (fatal == true) 
  394.     xexit(1);
  395. }
  396.  
  397. /* Format info message and print on stdout. */
  398.  
  399. /* (You would think this should be called just "info", but then you
  400.    would hosed by LynxOS, which defines that name in its libc.)  */
  401.  
  402. void
  403. #if USE_STDARG
  404. info_msg (const char *fmt, ...)
  405. #else
  406. info_msg (va_alist)
  407.      va_dcl
  408. #endif
  409. {
  410.   va_list arg;
  411.  
  412. #if ! USE_STDARG
  413.   const char *fmt;
  414.  
  415.   va_start (arg);
  416.   fmt = va_arg (arg, const char *);
  417. #else
  418.   va_start (arg, fmt);
  419. #endif
  420.  
  421.   vfinfo (stdout, fmt, arg);
  422.   va_end (arg);
  423. }
  424.  
  425. /* ('e' for error.) Format info message and print on stderr. */
  426.  
  427. void
  428. #if USE_STDARG
  429. einfo (const char *fmt, ...)
  430. #else
  431. einfo (va_alist)
  432.      va_dcl
  433. #endif
  434. {
  435.   va_list arg;
  436.  
  437. #if ! USE_STDARG
  438.   const char *fmt;
  439.  
  440.   va_start (arg);
  441.   fmt = va_arg (arg, const char *);
  442. #else
  443.   va_start (arg, fmt);
  444. #endif
  445.  
  446.   vfinfo (stderr, fmt, arg);
  447.   va_end (arg);
  448. }
  449.  
  450. void 
  451. info_assert (file, line)
  452.      const char *file;
  453.      unsigned int line;
  454. {
  455.   einfo ("%F%P: internal error %s %d\n", file, line);
  456. }
  457.  
  458. char *
  459. buystring (x)
  460.      CONST char *CONST x;
  461. {
  462.   size_t l = strlen(x)+1;
  463.   char *r = xmalloc(l);
  464.   memcpy(r, x,l);
  465.   return r;
  466. }
  467.  
  468. /* ('m' for map) Format info message and print on map. */
  469.  
  470. void
  471. #if USE_STDARG
  472. minfo (const char *fmt, ...)
  473. #else
  474. minfo (va_alist)
  475.      va_dcl
  476. #endif
  477. {
  478.   va_list arg;
  479.  
  480. #if ! USE_STDARG
  481.   const char *fmt;
  482.   va_start (arg);
  483.   fmt = va_arg (arg, const char *);
  484. #else
  485.   va_start (arg, fmt);
  486. #endif
  487.  
  488.   vfinfo (config.map_file, fmt, arg);
  489.   va_end (arg);
  490. }
  491.  
  492. void
  493. #if USE_STDARG
  494. finfo (FILE *file, const char *fmt, ...)
  495. #else
  496. finfo (va_alist)
  497.      va_dcl
  498. #endif
  499. {
  500.   va_list arg;
  501.  
  502. #if ! USE_STDARG
  503.   FILE *file;
  504.   const char *fmt;
  505.  
  506.   va_start (arg);
  507.   file = va_arg (arg, FILE *);
  508.   fmt = va_arg (arg, const char *);
  509. #else
  510.   va_start (arg, fmt);
  511. #endif
  512.  
  513.   vfinfo (file, fmt, arg);
  514.   va_end (arg);
  515. }
  516.  
  517. /* Functions to print the link map.  */
  518.  
  519. void 
  520. print_space ()
  521. {
  522.   fprintf (config.map_file, " ");
  523. }
  524.  
  525. void 
  526. print_nl ()
  527. {
  528.   fprintf (config.map_file, "\n");
  529. }
  530.