home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / src / binutils.2 / ld / ldmisc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  7.9 KB  |  425 lines

  1. /* ldmisc.c
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.  
  4.    Written by Steve Chamberlain of Cygnus Support.
  5.  
  6. This file is part of GLD, the Gnu Linker.
  7.  
  8. GLD is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2, or (at your option)
  11. any later version.
  12.  
  13. GLD is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with GLD; see the file COPYING.  If not, write to
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22. #include "bfd.h"
  23. #include "sysdep.h"
  24. #include <varargs.h>
  25. #include <demangle.h>
  26.  
  27. #include "ld.h"
  28. #include "ldmisc.h"
  29. #include "ldlang.h"
  30. #include "ldlex.h"
  31. /* IMPORTS */
  32.  
  33. extern char *program_name;
  34.  
  35. extern FILE *ldlex_input_stack;
  36. extern char *ldfile_input_filename;
  37. extern ld_config_type config;
  38.  
  39.  
  40. extern int errno;
  41. extern   int  sys_nerr;
  42. extern char *sys_errlist[];
  43.  
  44. /*
  45.  %F error is fatal
  46.  %P print progam 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 table entry
  52.  %X no object output, fail return
  53.  %V hex bfd_vma
  54.  %C Clever filename:linenumber 
  55.  %R info about a relent
  56.  %
  57. */
  58. extern bfd *output_bfd;
  59.  
  60. static char *
  61. demangle(string, remove_underscore)
  62. char *string;
  63. int remove_underscore;
  64. {
  65.   char *res;
  66.   if (remove_underscore && output_bfd) 
  67.   {
  68.     if (bfd_get_symbol_leading_char(output_bfd) == string[0])
  69.      string++;
  70.   }
  71.   /* Note that there's a memory leak here, we keep buying memory
  72.      for demangled names, and never free.  But if you have so many
  73.      errors that you run out of VM with the error messages, then
  74.      there's something up */
  75.   res = cplus_demangle(string, DMGL_ANSI|DMGL_PARAMS);
  76.   return res ? res : string;
  77. }
  78.  
  79. static void
  80. vfinfo(fp, fmt, arg)
  81.      FILE *fp;
  82.      char *fmt;
  83.      va_list arg;
  84. {
  85.   boolean fatal = false;
  86.   while (*fmt) 
  87.   {
  88.     while (*fmt != '%' && *fmt != '\0') 
  89.     {
  90.       putc(*fmt, fp);
  91.       fmt++;
  92.     }
  93.     if (*fmt == '%') 
  94.     {
  95.       fmt ++;
  96.       switch (*fmt++) 
  97.       {
  98.        case 'X':
  99.     config.make_executable = false;
  100.     break;
  101.        case 'V':
  102.        {
  103.      bfd_vma value = va_arg(arg, bfd_vma);
  104.      fprintf_vma(fp, value);
  105.        }
  106.     break;
  107.        case 'T':
  108.        {
  109.      asymbol *symbol = va_arg(arg, asymbol *);
  110.      if (symbol) 
  111.      {
  112.  
  113.         
  114.        asection *section = symbol->section;
  115.        char *cplusname =   demangle(symbol->name, 1);
  116.        CONST char *section_name =  section->name;
  117.        if (section != &bfd_und_section) 
  118.        {
  119.          fprintf(fp,"%s (%s)", cplusname, section_name);
  120.        }
  121.        else 
  122.        {
  123.          fprintf(fp,"%s", cplusname);
  124.        }
  125.      }
  126.      else 
  127.      {
  128.        fprintf(fp,"no symbol");
  129.      }
  130.        }
  131.     break;
  132.        case 'B':
  133.        { 
  134.      bfd *abfd = va_arg(arg, bfd *);
  135.      if (abfd->my_archive) {
  136.        fprintf(fp,"%s(%s)", abfd->my_archive->filename,
  137.            abfd->filename);
  138.      }
  139.      else {
  140.        fprintf(fp,"%s", abfd->filename);
  141.  
  142.      }
  143.        }
  144.     break;
  145.        case 'F':
  146.     fatal = true;
  147.     break;
  148.        case 'P':
  149.     fprintf(fp,"%s", program_name);
  150.     break;
  151.        case 'E':
  152.     /* Replace with the most recent errno explanation */
  153.  
  154.  
  155.     fprintf(fp, bfd_errmsg(bfd_error));
  156.  
  157.  
  158.     break;
  159.        case 'I':
  160.        {
  161.      lang_input_statement_type *i =
  162.       va_arg(arg,lang_input_statement_type *);
  163.     
  164.      fprintf(fp,"%s", i->local_sym_name);
  165.        }
  166.     break;
  167.        case 'S':
  168.     /* Print source script file and line number */
  169.  
  170.        {
  171.     
  172.      
  173.      extern unsigned int lineno;
  174.      if (ldfile_input_filename == (char *)NULL) {
  175.        fprintf(fp,"command line");
  176.      }
  177.      else {
  178.        fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
  179.      }
  180.        }
  181.     
  182.     break;
  183.  
  184.        case 'R':
  185.     /* Print all that's interesting about a relent */
  186.        {
  187.      arelent *relent = va_arg(arg, arelent *);
  188.     
  189.      fprintf(fp,"%s+0x%x (type %s)",
  190.          (*(relent->sym_ptr_ptr))->name,
  191.          relent->addend,
  192.          relent->howto->name);
  193.     
  194.  
  195.        }
  196.     break;
  197.     
  198.  
  199.  
  200.     
  201.        case 'C':
  202.        {
  203.      CONST char *filename;
  204.      CONST char *functionname;
  205.      char *cplus_name;
  206.      
  207.      unsigned int linenumber;
  208.      bfd *abfd = va_arg(arg, bfd *);
  209.      asection *section = va_arg(arg, asection *);
  210.      asymbol **symbols = va_arg(arg, asymbol **);
  211.      bfd_vma offset = va_arg(arg, bfd_vma);
  212.      
  213.      if (bfd_find_nearest_line(abfd,
  214.                    section,
  215.                    symbols,
  216.                    offset,
  217.                    &filename,
  218.                    &functionname,
  219.                    &linenumber))
  220.      {
  221.        if (filename == (char *)NULL)     
  222.         filename = abfd->filename;
  223.        if (functionname != (char *)NULL) 
  224.        {
  225.          /* There is no initial '_' to remove here. */
  226.          cplus_name = demangle(functionname, 0);
  227.          fprintf(fp,"%s:%u: (%s)", filename, linenumber, cplus_name);
  228.        }
  229.         
  230.        else if (linenumber != 0) 
  231.         fprintf(fp,"%s:%u", filename, linenumber);
  232.        else
  233.         fprintf(fp,"%s(%s+%0x)", filename,
  234.             section->name,
  235.             offset);
  236.  
  237.      }
  238.      else {
  239.        fprintf(fp,"%s(%s+%0x)", abfd->filename,
  240.            section->name,
  241.            offset);
  242.      }
  243.        }
  244.     break;
  245.         
  246.        case 's':
  247.     fprintf(fp,"%s", va_arg(arg, char *));
  248.     break;
  249.        case 'd':
  250.     fprintf(fp,"%d", va_arg(arg, int));
  251.     break;
  252.        default:
  253.     fprintf(fp,"%s", va_arg(arg, char *));
  254.     break;
  255.       }
  256.     }
  257.   }
  258.   if (fatal == true) 
  259.   {
  260.     extern char *output_filename;
  261.     if (output_filename) 
  262.     {
  263.       char *new = malloc(strlen(output_filename)+2);
  264.       extern bfd *output_bfd;
  265.       
  266.       strcpy(new, output_filename);
  267.       if (output_bfd && output_bfd->iostream)
  268.        fclose((FILE *)(output_bfd->iostream));
  269.       unlink(new);
  270.     }
  271.     exit(1);
  272.   }
  273. }
  274.  
  275. /* Format info message and print on stdout. */
  276.  
  277. void info(va_alist)
  278. va_dcl
  279. {
  280.   char *fmt;
  281.   va_list arg;
  282.   va_start(arg);
  283.   fmt = va_arg(arg, char *);
  284.   vfinfo(stdout, fmt, arg);
  285.   va_end(arg);
  286. }
  287.  
  288. /* ('e' for error.) Format info message and print on stderr. */
  289.  
  290. void einfo(va_alist)
  291. va_dcl
  292. {
  293.   char *fmt;
  294.   va_list arg;
  295.   va_start(arg);
  296.   fmt = va_arg(arg, char *);
  297.   vfinfo(stderr, fmt, arg);
  298.   va_end(arg);
  299. }
  300.  
  301. void 
  302. info_assert(file, line)
  303. char *file;
  304. unsigned int line;
  305. {
  306.   einfo("%F%P internal error %s %d\n", file,line);
  307. }
  308.  
  309. /* Return a newly-allocated string
  310.    whose contents concatenate those of S1, S2, S3.  */
  311.  
  312. char *
  313. DEFUN(concat, (s1, s2, s3),
  314.       CONST char *s1 AND
  315.       CONST char *s2 AND
  316.       CONST char *s3)
  317. {
  318.   bfd_size_type len1 = strlen (s1);
  319.   bfd_size_type len2 = strlen (s2);
  320.   bfd_size_type len3 = strlen (s3);
  321.   char *result = ldmalloc (len1 + len2 + len3 + 1);
  322.  
  323.   if (len1 != 0)
  324.     memcpy(result, s1, len1);
  325.   if (len2 != 0)
  326.     memcpy(result+len1, s2, len2);
  327.   if (len3 != 0)
  328.     memcpy(result+len1+len2, s2, len3);
  329.   *(result + len1 + len2 + len3) = 0;
  330.  
  331.   return result;
  332. }
  333.  
  334.  
  335. PTR
  336. DEFUN(ldmalloc, (size),
  337. bfd_size_type size)
  338. {
  339.   PTR result =  malloc ((int)size);
  340.  
  341.   if (result == (char *)NULL && size != 0)
  342.     einfo("%F%P virtual memory exhausted\n");
  343.  
  344.   return result;
  345.  
  346. PTR
  347. DEFUN(xmalloc,(size),
  348. int size)
  349. {
  350. return ldmalloc(size);
  351. }
  352.  
  353.  
  354. PTR
  355. DEFUN(ldrealloc, (ptr, size),
  356. PTR ptr AND
  357. bfd_size_type size)
  358. {
  359.   PTR result =  realloc (ptr, (int)size);
  360.  
  361.   if (result == (char *)NULL && size != 0)
  362.     einfo("%F%P virtual memory exhausted\n");
  363.  
  364.   return result;
  365.  
  366. PTR
  367. DEFUN(xrealloc, (ptr, size),
  368. PTR ptr AND
  369. bfd_size_type size)
  370. {
  371. return ldrealloc(ptr, size);
  372. }
  373.  
  374.  
  375. char *DEFUN(buystring,(x),
  376.         CONST char *CONST x)
  377. {
  378.   bfd_size_type  l = strlen(x)+1;
  379.   char *r = ldmalloc(l);
  380.   memcpy(r, x,l);
  381.   return r;
  382. }
  383.  
  384.  
  385. /* ('m' for map) Format info message and print on map. */
  386.  
  387. void minfo(va_alist)
  388. va_dcl
  389. {
  390.   char *fmt;
  391.   va_list arg;
  392.   va_start(arg);
  393.   fmt = va_arg(arg, char *);
  394.   vfinfo(config.map_file, fmt, arg);
  395.   va_end(arg);
  396. }
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403. /*----------------------------------------------------------------------
  404.   Functions to print the link map 
  405.  */
  406.  
  407. void 
  408. DEFUN_VOID(print_space)
  409. {
  410.   fprintf(config.map_file, " ");
  411. }
  412. void 
  413. DEFUN_VOID(print_nl)
  414. {
  415.   fprintf(config.map_file, "\n");
  416. }
  417. void 
  418. DEFUN(print_address,(value),
  419.       bfd_vma value)
  420. {
  421.   fprintf_vma(config.map_file, value);
  422. }
  423.