Mon Oct 5 08:55:14 1992 Steve Chamberlain (sac@thepub.cygnus.com)
[deliverable/binutils-gdb.git] / ld / ldmisc.c
index d3671c85db9df2635ec485e7caf0b3dee8b9eeae..b35e0218e8b2914a8779db4808a51ed1010ab2d7 100644 (file)
@@ -1,10 +1,13 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* ldmisc.c
+   Copyright (C) 1991 Free Software Foundation, Inc.
+
+   Written by Steve Chamberlain of Cygnus Support.
 
 This file is part of GLD, the Gnu Linker.
 
 GLD is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GLD is distributed in the hope that it will be useful,
@@ -16,23 +19,15 @@ You should have received a copy of the GNU General Public License
 along with GLD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/*
- * $Id$ 
- */
-
-/*
-  ldmisc.c
-
-*/
-
+#include "bfd.h"
 #include "sysdep.h"
 #include <varargs.h>
-#include "bfd.h"
+#include <demangle.h>
 
 #include "ld.h"
 #include "ldmisc.h"
 #include "ldlang.h"
-
+#include "ldlex.h"
 /* IMPORTS */
 
 extern char *program_name;
@@ -41,12 +36,6 @@ extern FILE *ldlex_input_stack;
 extern char *ldfile_input_filename;
 extern ld_config_type config;
 
-void
-yyerror(arg) 
-char *arg;
-{ 
-  info("%P%F: %S %s\n",arg);
-}
 
 extern int errno;
 extern   int  sys_nerr;
@@ -63,184 +52,263 @@ extern char *sys_errlist[];
  %X no object output, fail return
  %V hex bfd_vma
  %C Clever filename:linenumber 
+ %R info about a relent
  %
 */
-void info(va_alist)
-va_dcl
+static void
+vfinfo(fp, fmt, arg)
+     FILE *fp;
+     char *fmt;
+     va_list arg;
 {
-  char *fmt;
   boolean fatal = false;
-  va_list arg;
-  va_start(arg);
-  fmt = va_arg(arg, char *);
-  while (*fmt) {
-    while (*fmt != '%' && *fmt != '\0') {
-      fputc(*fmt, stderr);
+  while (*fmt) 
+  {
+    while (*fmt != '%' && *fmt != '\0') 
+    {
+      putc(*fmt, fp);
       fmt++;
     }
-    if (*fmt == '%') {
+    if (*fmt == '%') 
+    {
       fmt ++;
-      switch (*fmt++) {
-      case 'X':
+      switch (*fmt++) 
+      {
+       case 'X':
        config.make_executable = false;
        break;
-      case 'V':
-       fprintf(stderr,"%08lx", va_arg(arg, bfd_vma));
+       case 'V':
+       {
+        bfd_vma value = va_arg(arg, bfd_vma);
+        fprintf_vma(fp, value);
+       }
        break;
-      case 'T':
-       {
-         asymbol *symbol = va_arg(arg, asymbol *);
-         if (symbol) {
-           asection *section = symbol->section;
-           if ((symbol->flags & BSF_UNDEFINED) == 0) {
-             char *section_name = section == (asection *)NULL ?
-               "absolute" : section->name;
-             fprintf(stderr,"%s (%s)", symbol->name, section_name);
-           }
-           else {
-             fprintf(stderr,"%s", symbol->name);
-           }
-         }
-         else {
-           fprintf(stderr,"no symbol");
-         }
-       }
+       case 'T':
+       {
+        asymbol *symbol = va_arg(arg, asymbol *);
+        if (symbol) 
+        {
+
+           
+          asection *section = symbol->section;
+          char *cplusname =
+              cplus_demangle(symbol->name, DMGL_ANSI|DMGL_PARAMS);
+          CONST char *section_name =  section->name;
+          if (section != &bfd_und_section) 
+          {
+            fprintf(fp,"%s (%s)", cplusname ? cplusname :
+                    symbol->name, section_name);
+          }
+          else 
+          {
+            fprintf(fp,"%s", cplusname ? cplusname : symbol->name);
+          }
+           
+          if (cplusname) 
+          {
+            free(cplusname);
+          }
+           
+        }
+        else 
+        {
+          fprintf(fp,"no symbol");
+        }
+       }
        break;
-      case 'B':
-       { 
-         bfd *abfd = va_arg(arg, bfd *);
-         if (abfd->my_archive) {
-           fprintf(stderr,"%s(%s)", abfd->my_archive->filename,
-                   abfd->filename);
-         }
-         else {
-           fprintf(stderr,"%s", abfd->filename);
-
-         }
-       }
+       case 'B':
+       { 
+        bfd *abfd = va_arg(arg, bfd *);
+        if (abfd->my_archive) {
+          fprintf(fp,"%s(%s)", abfd->my_archive->filename,
+                  abfd->filename);
+        }
+        else {
+          fprintf(fp,"%s", abfd->filename);
+
+        }
+       }
        break;
-      case 'F':
+       case 'F':
        fatal = true;
        break;
-      case 'P':
-       fprintf(stderr,"%s", program_name);
+       case 'P':
+       fprintf(fp,"%s", program_name);
        break;
-      case 'E':
+       case 'E':
        /* Replace with the most recent errno explanation */
 
 
-       fprintf(stderr, bfd_errmsg(bfd_error));
+       fprintf(fp, bfd_errmsg(bfd_error));
 
 
        break;
-      case 'I':
-       {
-         lang_input_statement_type *i =
-           va_arg(arg,lang_input_statement_type *);
+       case 'I':
+       {
+        lang_input_statement_type *i =
+         va_arg(arg,lang_input_statement_type *);
        
-         fprintf(stderr,"%s", i->local_sym_name);
-       }
+        fprintf(fp,"%s", i->local_sym_name);
+       }
        break;
-      case 'S':
+       case 'S':
        /* Print source script file and line number */
 
-       if (ldlex_input_stack) {
-         extern unsigned int lineno;
-         if (ldfile_input_filename == (char *)NULL) {
-           fprintf(stderr,"command line");
-         }
-         else {
-           fprintf(stderr,"%s:%u", ldfile_input_filename, lineno );
-         }
-       }
-       else {
-         int ch;
-         int n = 0;
-         fprintf(stderr,"command (before <");
-         ch = lex_input();
-         while (ch != 0 && n < 10) {
-           fprintf(stderr, "%c", ch);
-           ch = lex_input();
-           n++;
-         }
-         fprintf(stderr,")");
-           
-       }
+       {
+       
+        
+        extern unsigned int lineno;
+        if (ldfile_input_filename == (char *)NULL) {
+          fprintf(fp,"command line");
+        }
+        else {
+          fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
+        }
+       }
+       
+       break;
+
+       case 'R':
+       /* Print all that's interesting about a relent */
+       {
+        arelent *relent = va_arg(arg, arelent *);
+       
+        fprintf(fp,"%s+0x%x (type %s)",
+                (*(relent->sym_ptr_ptr))->name,
+                relent->addend,
+                relent->howto->name);
+       
+
+       }
        break;
-      case 'C':
-       {
-         char *filename;
-         char *functionname;
-         unsigned int linenumber;
-         bfd *abfd = va_arg(arg, bfd *);
-         asection *section = va_arg(arg, asection *);
-         asymbol **symbols = va_arg(arg, asymbol **);
-         bfd_vma offset = va_arg(arg, bfd_vma);
+       
+
+
+       
+       case 'C':
+       {
+        CONST char *filename;
+        CONST char *functionname;
+        char *cplus_name;
+        
+        unsigned int linenumber;
+        bfd *abfd = va_arg(arg, bfd *);
+        asection *section = va_arg(arg, asection *);
+        asymbol **symbols = va_arg(arg, asymbol **);
+        bfd_vma offset = va_arg(arg, bfd_vma);
         
-         if (bfd_find_nearest_line(abfd,
-                                   section,
-                                   symbols,
-                                   offset,
-                                   &filename,
-                                   &functionname,
-                                   &linenumber))
-           {
-               if (filename == (char *)NULL)   
-                   filename = abfd->filename;
-               if (functionname != (char *)NULL)
-                   fprintf(stderr,"%s:%u: (%s)", filename, linenumber,  functionname);
-               else if (linenumber != 0) 
-                   fprintf(stderr,"%s:%u", filename, linenumber);
-               else
-                   fprintf(stderr,"%s", filename);
-
-           }
-         else {
-           fprintf(stderr,"%s", abfd->filename);
-         }
-       }
+        if (bfd_find_nearest_line(abfd,
+                                  section,
+                                  symbols,
+                                  offset,
+                                  &filename,
+                                  &functionname,
+                                  &linenumber))
+        {
+          if (filename == (char *)NULL)        
+           filename = abfd->filename;
+          if (functionname != (char *)NULL) 
+          {
+            cplus_name = cplus_demangle(functionname, DMGL_ANSI|DMGL_PARAMS);
+            fprintf(fp,"%s:%u: (%s)", filename, linenumber,
+                    cplus_name? cplus_name: functionname);
+            if (cplus_name) 
+             free(cplus_name);
+                 
+
+          }
+               
+          else if (linenumber != 0) 
+           fprintf(fp,"%s:%u", filename, linenumber);
+          else
+           fprintf(fp,"%s(%s+%0x)", filename,
+                   section->name,
+                   offset);
+
+        }
+        else {
+          fprintf(fp,"%s(%s+%0x)", abfd->filename,
+                  section->name,
+                  offset);
+        }
+       }
        break;
                
-      case 's':
-       fprintf(stderr,"%s", va_arg(arg, char *));
+       case 's':
+       fprintf(fp,"%s", va_arg(arg, char *));
        break;
-      case 'd':
-       fprintf(stderr,"%d", va_arg(arg, int));
+       case 'd':
+       fprintf(fp,"%d", va_arg(arg, int));
        break;
-      default:
-       fprintf(stderr,"%s", va_arg(arg, char *));
+       default:
+       fprintf(fp,"%s", va_arg(arg, char *));
        break;
       }
     }
   }
-  if (fatal == true) {
+  if (fatal == true) 
+  {
     extern char *output_filename;
-    if (output_filename)
-      unlink(output_filename);
+    if (output_filename) 
+    {
+      char *new = malloc(strlen(output_filename)+2);
+      extern bfd *output_bfd;
+      
+      strcpy(new, output_filename);
+      if (output_bfd && output_bfd->iostream)
+       fclose((FILE *)(output_bfd->iostream));
+      unlink(new);
+    }
     exit(1);
   }
+}
+
+/* Format info message and print on stdout. */
+
+void info(va_alist)
+va_dcl
+{
+  char *fmt;
+  va_list arg;
+  va_start(arg);
+  fmt = va_arg(arg, char *);
+  vfinfo(stdout, fmt, arg);
   va_end(arg);
 }
 
+/* ('e' for error.) Format info message and print on stderr. */
+
+void einfo(va_alist)
+va_dcl
+{
+  char *fmt;
+  va_list arg;
+  va_start(arg);
+  fmt = va_arg(arg, char *);
+  vfinfo(stderr, fmt, arg);
+  va_end(arg);
+}
 
 void 
 info_assert(file, line)
 char *file;
 unsigned int line;
 {
-  info("%F%P internal error %s %d\n", file,line);
+  einfo("%F%P internal error %s %d\n", file,line);
 }
 
 /* Return a newly-allocated string
    whose contents concatenate those of S1, S2, S3.  */
 
 char *
-concat (s1, s2, s3)
-     char *s1, *s2, *s3;
+DEFUN(concat, (s1, s2, s3),
+      CONST char *s1 AND
+      CONST char *s2 AND
+      CONST char *s3)
 {
-  size_t len1 = strlen (s1);
-  size_t len2 = strlen (s2);
-  size_t len3 = strlen (s3);
+  bfd_size_type len1 = strlen (s1);
+  bfd_size_type len2 = strlen (s2);
+  bfd_size_type len3 = strlen (s3);
   char *result = ldmalloc (len1 + len2 + len3 + 1);
 
   if (len1 != 0)
@@ -255,25 +323,86 @@ concat (s1, s2, s3)
 }
 
 
+PTR
+DEFUN(ldmalloc, (size),
+bfd_size_type size)
+{
+  PTR result =  malloc ((int)size);
+
+  if (result == (char *)NULL && size != 0)
+    einfo("%F%P virtual memory exhausted\n");
+
+  return result;
+} 
+
+PTR
+DEFUN(xmalloc,(size),
+int size)
+{
+return ldmalloc(size);
+}
+
 
-char  *ldmalloc (size)
-size_t size;
+PTR
+DEFUN(ldrealloc, (ptr, size),
+PTR ptr AND
+bfd_size_type size)
 {
-  char * result =  malloc (size);
+  PTR result =  realloc (ptr, (int)size);
 
   if (result == (char *)NULL && size != 0)
-    info("%F%P virtual memory exhausted\n");
+    einfo("%F%P virtual memory exhausted\n");
 
   return result;
 } 
 
 
 
-char *buystring(x)
-char *x;
+char *DEFUN(buystring,(x),
+           CONST char *CONST x)
 {
-  size_t  l = strlen(x)+1;
+  bfd_size_type  l = strlen(x)+1;
   char *r = ldmalloc(l);
   memcpy(r, x,l);
   return r;
 }
+
+
+/* ('m' for map) Format info message and print on map. */
+
+void minfo(va_alist)
+va_dcl
+{
+  char *fmt;
+  va_list arg;
+  va_start(arg);
+  fmt = va_arg(arg, char *);
+  vfinfo(config.map_file, fmt, arg);
+  va_end(arg);
+}
+
+
+
+
+
+
+/*----------------------------------------------------------------------
+  Functions to print the link map 
+ */
+
+void 
+DEFUN_VOID(print_space)
+{
+  fprintf(config.map_file, " ");
+}
+void 
+DEFUN_VOID(print_nl)
+{
+  fprintf(config.map_file, "\n");
+}
+void 
+DEFUN(print_address,(value),
+      bfd_vma value)
+{
+  fprintf_vma(config.map_file, value);
+}
This page took 0.032039 seconds and 4 git commands to generate.