Home | History | Annotate | Line # | Download | only in ld
      1 /* ldmisc.c
      2    Copyright (C) 1991-2026 Free Software Foundation, Inc.
      3    Written by Steve Chamberlain of Cygnus Support.
      4 
      5    This file is part of the GNU Binutils.
      6 
      7    This program 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 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program 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 this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 #include "sysdep.h"
     23 #include "bfd.h"
     24 #include "bfdlink.h"
     25 #include "libiberty.h"
     26 #include "ctf-api.h"
     27 #include "safe-ctype.h"
     28 #include "filenames.h"
     29 #include "demangle.h"
     30 #include <stdarg.h>
     31 #include "ld.h"
     32 #include "ldmisc.h"
     33 #include "ldexp.h"
     34 #include "ldlang.h"
     35 #include <ldgram.h>
     36 #include "ldlex.h"
     37 #include "ldmain.h"
     38 #include "ldfile.h"
     39 
     40 static size_t
     41 count_modifiers (const char *scan)
     42 {
     43   size_t mods = strspn (scan, "-+ #0");
     44 
     45   while (scan[mods] != '0' && ISDIGIT (scan[mods]))
     46     ++mods;
     47   if (scan[mods] == '.')
     48     ++mods;
     49   while (scan[mods] != '0' && ISDIGIT (scan[mods]))
     50     ++mods;
     51 
     52   return mods;
     53 }
     54 
     55 static char *
     56 make_cfmt (const char *fmt, int nr)
     57 {
     58   return xasprintf ("%%%.*s", nr, fmt);
     59 }
     60 
     61 /*
     62  %% literal %
     63  %C clever filename:linenumber with function
     64  %D like %C, but no function name
     65  %E current bfd error or errno
     66  %G like %D, but only function name
     67  %H like %C but in addition emit section+offset
     68  %P print program name
     69  %V hex bfd_vma
     70  %W hex bfd_vma with 0x with no leading zeros taking up 10 spaces
     71  %X no object output, fail return
     72  %d integer, like printf
     73  %ld long, like printf
     74  %lu unsigned long, like printf
     75  %lx unsigned long, like printf
     76  %p native (host) void* pointer, like printf
     77  %pA section name from a section
     78  %pB filename from a bfd
     79  %pI filename from a lang_input_statement_type
     80  %pR info about a relent
     81  %pS print script file and linenumber from etree_type.
     82  %pT symbol name
     83  %pU print script file without linenumber from etree_type.
     84  %s arbitrary string, like printf
     85  %u integer, like printf
     86  %v hex bfd_vma, no leading zeros
     87  %x integer, like printf
     88 */
     89 
     90 void
     91 vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
     92 {
     93   const char *scan;
     94   int arg_type;
     95   unsigned int arg_count = 0;
     96   unsigned int arg_no;
     97   union vfinfo_args
     98   {
     99     int i;
    100     long l;
    101     long long ll;
    102     void *p;
    103     bfd_vma v;
    104     struct {
    105       bfd *abfd;
    106       asection *sec;
    107       bfd_vma off;
    108     } reladdr;
    109     enum
    110       {
    111 	Bad,
    112 	Int,
    113 	Long,
    114 	LongLong,
    115 	Ptr,
    116 	Vma,
    117 	RelAddr
    118       } type;
    119   } args[9];
    120 
    121   if (is_warning && config.no_warnings)
    122     return;
    123 
    124   for (arg_no = 0; arg_no < sizeof (args) / sizeof (args[0]); arg_no++)
    125     args[arg_no].type = Bad;
    126 
    127   arg_count = 0;
    128   scan = fmt;
    129   while (*scan != '\0')
    130     {
    131       while (*scan != '%' && *scan != '\0')
    132 	scan++;
    133 
    134       if (*scan == '%')
    135 	{
    136 	  scan++;
    137 
    138 	  arg_no = arg_count;
    139 	  if (*scan != '0' && ISDIGIT (*scan) && scan[1] == '$')
    140 	    {
    141 	      arg_no = *scan - '1';
    142 	      scan += 2;
    143 	    }
    144 
    145 	  /* Skip most modifiers that printf() permits.  */
    146 	  scan += count_modifiers (scan);
    147 
    148 	  arg_type = Bad;
    149 	  switch (*scan++)
    150 	    {
    151 	    case '\0':
    152 	      --scan;
    153 	      break;
    154 
    155 	    case 'V':
    156 	    case 'v':
    157 	    case 'W':
    158 	      arg_type = Vma;
    159 	      break;
    160 
    161 	    case 's':
    162 	      arg_type = Ptr;
    163 	      break;
    164 
    165 	    case 'p':
    166 	      if (*scan == 'A' || *scan == 'B' || *scan == 'I'
    167 		  || *scan == 'R' || *scan == 'S' || *scan ==  'T')
    168 		scan++;
    169 	      arg_type = Ptr;
    170 	      break;
    171 
    172 	    case 'C':
    173 	    case 'D':
    174 	    case 'G':
    175 	    case 'H':
    176 	      arg_type = RelAddr;
    177 	      break;
    178 
    179 	    case 'd':
    180 	    case 'u':
    181 	    case 'x':
    182 	      arg_type = Int;
    183 	      break;
    184 
    185 	    case 'l':
    186 	      {
    187 		bool ll_type = false;
    188 		if (*scan == 'l')
    189 		  {
    190 		    ll_type = true;
    191 		    ++scan;
    192 		  }
    193 		if (*scan == 'd' || *scan == 'u' || *scan == 'x')
    194 		  {
    195 		    ++scan;
    196 		    arg_type = (ll_type ? LongLong : Long);
    197 		  }
    198 	      }
    199 	      break;
    200 
    201 	    default:
    202 	      break;
    203 	    }
    204 	  if (arg_type != Bad)
    205 	    {
    206 	      if (arg_no >= sizeof (args) / sizeof (args[0]))
    207 		abort ();
    208 	      args[arg_no].type = arg_type;
    209 	      ++arg_count;
    210 	    }
    211 	}
    212     }
    213 
    214   for (arg_no = 0; arg_no < arg_count; arg_no++)
    215     {
    216       switch (args[arg_no].type)
    217 	{
    218 	case Int:
    219 	  args[arg_no].i = va_arg (ap, int);
    220 	  break;
    221 	case Long:
    222 	  args[arg_no].l = va_arg (ap, long);
    223 	  break;
    224 	case LongLong:
    225 	  args[arg_no].ll = va_arg (ap, long long);
    226 	  break;
    227 	case Ptr:
    228 	  args[arg_no].p = va_arg (ap, void *);
    229 	  break;
    230 	case Vma:
    231 	  args[arg_no].v = va_arg (ap, bfd_vma);
    232 	  break;
    233 	case RelAddr:
    234 	  args[arg_no].reladdr.abfd = va_arg (ap, bfd *);
    235 	  args[arg_no].reladdr.sec = va_arg (ap, asection *);
    236 	  args[arg_no].reladdr.off = va_arg (ap, bfd_vma);
    237 	  break;
    238 	default:
    239 	  abort ();
    240 	}
    241     }
    242 
    243   arg_count = 0;
    244   while (*fmt != '\0')
    245     {
    246       const char *str = fmt;
    247       while (*fmt != '%' && *fmt != '\0')
    248 	fmt++;
    249       if (fmt != str)
    250 	if (fwrite (str, 1, fmt - str, fp))
    251 	  {
    252 	    /* Ignore.  */
    253 	  }
    254 
    255       if (*fmt == '%')
    256 	{
    257 	  size_t mods;
    258 
    259 	  fmt++;
    260 
    261 	  arg_no = arg_count;
    262 	  if (*fmt != '0' && ISDIGIT (*fmt) && fmt[1] == '$')
    263 	    {
    264 	      arg_no = *fmt - '1';
    265 	      fmt += 2;
    266 	    }
    267 
    268 	  /* Record modifiers that printf() permits and that we support.  */
    269 	  mods = count_modifiers (fmt);
    270 	  fmt += mods;
    271 
    272 	  switch (*fmt++)
    273 	    {
    274 	      char *cfmt;
    275 
    276 	    case '\0':
    277 	      --fmt;
    278 	      /* Fall through.  */
    279 
    280 	    case '%':
    281 	      /* literal % */
    282 	      putc ('%', fp);
    283 	      break;
    284 
    285 	    case 'X':
    286 	      /* no object output, fail return */
    287 	      config.make_executable = false;
    288 	      break;
    289 
    290 	    case 'V':
    291 	      /* hex bfd_vma */
    292 	      {
    293 		char buf[32];
    294 		bfd_vma value;
    295 
    296 		value = args[arg_no].v;
    297 		++arg_count;
    298 		bfd_sprintf_vma (link_info.output_bfd, buf, value);
    299 		fprintf (fp, "%s", buf);
    300 	      }
    301 	      break;
    302 
    303 	    case 'v':
    304 	      /* hex bfd_vma, no leading zeros */
    305 	      {
    306 		uint64_t value = args[arg_no].v;
    307 		++arg_count;
    308 		fprintf (fp, "%" PRIx64, value);
    309 	      }
    310 	      break;
    311 
    312 	    case 'W':
    313 	      /* hex bfd_vma with 0x with no leading zeroes taking up
    314 		 10 spaces (including the 0x).  */
    315 	      {
    316 		char buf[32];
    317 		uint64_t value;
    318 
    319 		value = args[arg_no].v;
    320 		++arg_count;
    321 		sprintf (buf, "0x%" PRIx64, value);
    322 		fprintf (fp, "%10s", buf);
    323 	      }
    324 	      break;
    325 
    326 	    case 'P':
    327 	      /* Print program name.  */
    328 	      fprintf (fp, "%s", program_name);
    329 	      break;
    330 
    331 	    case 'E':
    332 	      /* current bfd error or errno */
    333 	      fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
    334 	      break;
    335 
    336 	    case 'C':
    337 	    case 'D':
    338 	    case 'G':
    339 	    case 'H':
    340 	      /* Clever filename:linenumber with function name if possible.
    341 		 The arguments are a BFD, a section, and an offset.  */
    342 	      {
    343 		static bfd *last_bfd;
    344 		static char *last_file;
    345 		static char *last_function;
    346 		bfd *abfd;
    347 		asection *section;
    348 		bfd_vma offset;
    349 		asymbol **asymbols = NULL;
    350 		const char *filename;
    351 		const char *functionname;
    352 		unsigned int linenumber;
    353 		bool discard_last;
    354 		bool done;
    355 		bfd_error_type last_bfd_error = bfd_get_error ();
    356 
    357 		abfd = args[arg_no].reladdr.abfd;
    358 		section = args[arg_no].reladdr.sec;
    359 		offset = args[arg_no].reladdr.off;
    360 		++arg_count;
    361 
    362 		if (abfd != NULL)
    363 		  {
    364 		    if (!bfd_generic_link_read_symbols (abfd))
    365 		      fatal (_("%P: %pB: could not read symbols: %E\n"), abfd);
    366 
    367 		    asymbols = bfd_get_outsymbols (abfd);
    368 		  }
    369 
    370 		/* The GNU Coding Standard requires that error messages
    371 		   be of the form:
    372 
    373 		     source-file-name:lineno: message
    374 
    375 		   We do not always have a line number available so if
    376 		   we cannot find them we print out the section name and
    377 		   offset instead.  */
    378 		discard_last = true;
    379 		if (abfd != NULL
    380 		    && bfd_find_nearest_line (abfd, section, asymbols, offset,
    381 					      &filename, &functionname,
    382 					      &linenumber))
    383 		  {
    384 		    if (functionname != NULL
    385 			&& (fmt[-1] == 'C' || fmt[-1] == 'H'))
    386 		      {
    387 			/* Detect the case where we are printing out a
    388 			   message for the same function as the last
    389 			   call to vinfo ("%C").  In this situation do
    390 			   not print out the ABFD filename or the
    391 			   function name again.  Note - we do still
    392 			   print out the source filename, as this will
    393 			   allow programs that parse the linker's output
    394 			   (eg emacs) to correctly locate multiple
    395 			   errors in the same source file.  */
    396 			if (last_bfd == NULL
    397 			    || last_function == NULL
    398 			    || last_bfd != abfd
    399 			    || (last_file == NULL) != (filename == NULL)
    400 			    || (filename != NULL
    401 				&& filename_cmp (last_file, filename) != 0)
    402 			    || strcmp (last_function, functionname) != 0)
    403 			  {
    404 			    lfinfo (fp, _("%pB: in function `%pT':\n"),
    405 				    abfd, functionname);
    406 
    407 			    last_bfd = abfd;
    408 			    free (last_file);
    409 			    last_file = NULL;
    410 			    if (filename)
    411 			      last_file = xstrdup (filename);
    412 			    free (last_function);
    413 			    last_function = xstrdup (functionname);
    414 			  }
    415 			discard_last = false;
    416 		      }
    417 		    else
    418 		      lfinfo (fp, "%pB:", abfd);
    419 
    420 		    if (filename != NULL)
    421 		      fprintf (fp, "%s:", filename);
    422 
    423 		    done = fmt[-1] != 'H';
    424 		    if (functionname != NULL && fmt[-1] == 'G')
    425 		      lfinfo (fp, "%pT", functionname);
    426 		    else if (filename != NULL && linenumber != 0)
    427 		      fprintf (fp, "%u%s", linenumber, done ? "" : ":");
    428 		    else
    429 		      done = false;
    430 		  }
    431 		else
    432 		  {
    433 		    lfinfo (fp, "%pB:", abfd);
    434 		    done = false;
    435 		  }
    436 		if (!done)
    437 		  lfinfo (fp, "(%pA+0x%v)", section, offset);
    438 		bfd_set_error (last_bfd_error);
    439 
    440 		if (discard_last)
    441 		  {
    442 		    last_bfd = NULL;
    443 		    free (last_file);
    444 		    last_file = NULL;
    445 		    free (last_function);
    446 		    last_function = NULL;
    447 		  }
    448 	      }
    449 	      break;
    450 
    451 	    case 'p':
    452 	      if (*fmt == 'A')
    453 		{
    454 		  /* section name from a section */
    455 		  asection *sec;
    456 		  bfd *abfd;
    457 
    458 		  fmt++;
    459 		  sec = (asection *) args[arg_no].p;
    460 		  ++arg_count;
    461 		  fprintf (fp, "%s", sec->name);
    462 		  abfd = sec->owner;
    463 		  if (abfd != NULL)
    464 		    {
    465 		      const char *group = bfd_group_name (abfd, sec);
    466 		      if (group != NULL)
    467 			fprintf (fp, "[%s]", group);
    468 		    }
    469 		}
    470 	      else if (*fmt == 'B')
    471 		{
    472 		  /* filename from a bfd */
    473 		  bfd *abfd = (bfd *) args[arg_no].p;
    474 
    475 		  fmt++;
    476 		  ++arg_count;
    477 		  if (abfd == NULL)
    478 		    fprintf (fp, "%s generated", program_name);
    479 		  else if (abfd->my_archive != NULL
    480 			   && !bfd_is_thin_archive (abfd->my_archive))
    481 		    fprintf (fp, "%s(%s)",
    482 			     bfd_get_filename (abfd->my_archive),
    483 			     bfd_get_filename (abfd));
    484 		  else
    485 		    fprintf (fp, "%s", bfd_get_filename (abfd));
    486 		}
    487 	      else if (*fmt == 'I')
    488 		{
    489 		  /* filename from a lang_input_statement_type */
    490 		  lang_input_statement_type *i;
    491 
    492 		  fmt++;
    493 		  i = (lang_input_statement_type *) args[arg_no].p;
    494 		  ++arg_count;
    495 		  if (i->the_bfd != NULL
    496 		      && i->the_bfd->my_archive != NULL
    497 		      && !bfd_is_thin_archive (i->the_bfd->my_archive))
    498 		    fprintf (fp, "(%s)%s",
    499 			     bfd_get_filename (i->the_bfd->my_archive),
    500 			     i->local_sym_name);
    501 		  else
    502 		    fprintf (fp, "%s", i->filename);
    503 		}
    504 	      else if (*fmt == 'R')
    505 		{
    506 		  /* Print all that's interesting about a relent.  */
    507 		  arelent *relent = (arelent *) args[arg_no].p;
    508 
    509 		  fmt++;
    510 		  ++arg_count;
    511 		  lfinfo (fp, "%s+0x%v (type %s)",
    512 			  (*(relent->sym_ptr_ptr))->name,
    513 			  relent->addend,
    514 			  relent->howto->name);
    515 		}
    516 	      else if (*fmt == 'S' || *fmt == 'U')
    517 		{
    518 		  /* Print script file and perhaps the associated linenumber.  */
    519 		  etree_type node;
    520 		  etree_type *tp = (etree_type *) args[arg_no].p;
    521 
    522 		  fmt++;
    523 		  ++arg_count;
    524 		  if (tp == NULL)
    525 		    {
    526 		      tp = &node;
    527 		      tp->type.filename = ldlex_filename ();
    528 		      tp->type.lineno = lineno;
    529 		    }
    530 		  if (tp->type.filename != NULL && fmt[-1] == 'S')
    531 		    fprintf (fp, "%s:%u", tp->type.filename, tp->type.lineno);
    532 		  else if (tp->type.filename != NULL && fmt[-1] == 'U')
    533 		    fprintf (fp, "%s", tp->type.filename);
    534 		}
    535 	      else if (*fmt == 'T')
    536 		{
    537 		  /* Symbol name.  */
    538 		  const char *name = (const char *) args[arg_no].p;
    539 
    540 		  fmt++;
    541 		  ++arg_count;
    542 		  if (name == NULL || *name == 0)
    543 		    {
    544 		      fprintf (fp, _("no symbol"));
    545 		      break;
    546 		    }
    547 		  else if (demangling)
    548 		    {
    549 		      char *demangled;
    550 
    551 		      demangled = bfd_demangle (link_info.output_bfd, name,
    552 						DMGL_ANSI | DMGL_PARAMS);
    553 		      if (demangled != NULL)
    554 			{
    555 			  fprintf (fp, "%s", demangled);
    556 			  free (demangled);
    557 			  break;
    558 			}
    559 		    }
    560 		  fprintf (fp, "%s", name);
    561 		}
    562 	      else /* Native (host) void* pointer, like printf().  */
    563 		{
    564 		  /* Fallthru */
    565 	    case 's': /* Arbitrary string, like printf().  */
    566 		  cfmt = make_cfmt (fmt - 1 - mods, mods + 1);
    567 		  fprintf (fp, cfmt, args[arg_no].p);
    568 		  free (cfmt);
    569 		  ++arg_count;
    570 		}
    571 	      break;
    572 
    573 	    case 'd': /* Integer, like printf().  */
    574 	    case 'u': /* Unsigned integer, like printf().  */
    575 	    case 'x': /* Unsigned integer, like printf().  */
    576 	      cfmt = make_cfmt (fmt - 1 - mods, mods + 1);
    577 	      fprintf (fp, cfmt, args[arg_no].i);
    578 	      free (cfmt);
    579 	      ++arg_count;
    580 	      break;
    581 
    582 	    case 'l': /* (Unsigned) (long) long integer, like printf().  */
    583 	      {
    584 		bool ll_type = false;
    585 		if (*fmt == 'l')
    586 		  {
    587 		    fmt++;
    588 		    ll_type = true;
    589 		  }
    590 		if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x')
    591 		  {
    592 		    unsigned int mods_len = (ll_type ? 2 : 1);
    593 		    cfmt = make_cfmt (fmt - mods_len - mods, mods + mods_len + 1);
    594 		    if (ll_type)
    595 		      fprintf (fp, cfmt, args[arg_no].ll);
    596 		    else
    597 		      fprintf (fp, cfmt, args[arg_no].l);
    598 		    free (cfmt);
    599 		    ++arg_count;
    600 		    ++fmt;
    601 		    break;
    602 		  }
    603 	      }
    604 	      /* Fallthru */
    605 
    606 	    default:
    607 	      fprintf (fp, "%%%c", fmt[-1]);
    608 	      break;
    609 	    }
    610 	}
    611     }
    612 
    613   if (is_warning && config.fatal_warnings)
    614     config.make_executable = false;
    615 }
    616 
    617 /* Format info message and print on stdout.  */
    618 
    619 /* (You would think this should be called just "info", but then you
    620    would be hosed by LynxOS, which defines that name in its libc.)  */
    621 
    622 void
    623 info_msg (const char *fmt, ...)
    624 {
    625   va_list arg;
    626 
    627   va_start (arg, fmt);
    628   vfinfo (stdout, fmt, arg, false);
    629   va_end (arg);
    630 }
    631 
    632 /* ('e' for error.) Format info message and print on stderr.  */
    633 
    634 void
    635 einfo (const char *fmt, ...)
    636 {
    637   va_list arg;
    638 
    639   fflush (stdout);
    640   va_start (arg, fmt);
    641   vfinfo (stderr, fmt, arg, true);
    642   va_end (arg);
    643   fflush (stderr);
    644 }
    645 
    646 /* Fatal error.  */
    647 
    648 void
    649 fatal (const char *fmt, ...)
    650 {
    651   va_list arg;
    652 
    653   fflush (stdout);
    654   va_start (arg, fmt);
    655   vfinfo (stderr, fmt, arg, true);
    656   va_end (arg);
    657   fflush (stderr);
    658   xexit (1);
    659 }
    660 
    661 /* The buffer size for each command-line option warning.  */
    662 #define CMDLINE_WARNING_SIZE	256
    663 
    664 /* A linked list of command-line option warnings.  */
    665 
    666 struct cmdline_warning_list
    667 {
    668   struct cmdline_warning_list *next;
    669   char *warning;
    670 };
    671 
    672 /* The head of the linked list of command-line option warnings.  */
    673 static struct cmdline_warning_list *cmdline_warning_head = NULL;
    674 
    675 /* The tail of the linked list of command-line option warnings.  */
    676 static struct cmdline_warning_list **cmdline_warning_tail
    677   = &cmdline_warning_head;
    678 
    679 /* Queue an unknown command-line option warning.  */
    680 
    681 void
    682 queue_unknown_cmdline_warning (const char *fmt, ...)
    683 {
    684   va_list arg;
    685   struct cmdline_warning_list *warning_ptr
    686     = xmalloc (sizeof (*warning_ptr));
    687   warning_ptr->warning = xmalloc (CMDLINE_WARNING_SIZE);
    688   warning_ptr->next = NULL;
    689   int written;
    690 
    691   va_start (arg, fmt);
    692   written = vsnprintf (warning_ptr->warning, CMDLINE_WARNING_SIZE, fmt,
    693 		       arg);
    694   if (written < 0 || written >= CMDLINE_WARNING_SIZE)
    695     {
    696       /* If vsnprintf fails or truncates, output the warning directly.  */
    697       fflush (stdout);
    698       va_start (arg, fmt);
    699       vfinfo (stderr, fmt, arg, true);
    700       fflush (stderr);
    701     }
    702   else
    703     {
    704       *cmdline_warning_tail = warning_ptr;
    705       cmdline_warning_tail = &warning_ptr->next;
    706     }
    707   va_end (arg);
    708 }
    709 
    710 /* Output queued unknown command-line option warnings.  */
    711 
    712 void
    713 output_unknown_cmdline_warnings (void)
    714 {
    715   struct cmdline_warning_list *list = cmdline_warning_head;
    716   struct cmdline_warning_list *next;
    717   if (list == NULL)
    718     return;
    719 
    720   fflush (stdout);
    721 
    722   for (; list != NULL; list = next)
    723     {
    724       next = list->next;
    725       if (config.fatal_warnings)
    726 	einfo (_("%P: error: unsupported option: %s\n"), list->warning);
    727       else
    728 	einfo (_("%P: warning: %s ignored\n"), list->warning);
    729       free (list->warning);
    730       free (list);
    731     }
    732 
    733   fflush (stderr);
    734 }
    735 
    736 void
    737 info_assert (const char *file, unsigned int line)
    738 {
    739   fatal (_("%P: internal error %s %d\n"), file, line);
    740 }
    741 
    742 /* ('m' for map) Format info message and print on map.  */
    743 
    744 void
    745 minfo (const char *fmt, ...)
    746 {
    747   if (config.map_file != NULL)
    748     {
    749       va_list arg;
    750 
    751       va_start (arg, fmt);
    752       if (fmt[0] == '%' && fmt[1] == '!' && fmt[2] == 0)
    753 	{
    754 	  /* Stash info about --as-needed shared libraries.  Print
    755 	     later so they don't appear intermingled with archive
    756 	     library info.  */
    757 	  struct asneeded_minfo *m = xmalloc (sizeof *m);
    758 
    759 	  m->next = NULL;
    760 	  m->soname = va_arg (arg, const char *);
    761 	  m->ref = va_arg (arg, bfd *);
    762 	  m->name = va_arg (arg, const char *);
    763 	  *asneeded_list_tail = m;
    764 	  asneeded_list_tail = &m->next;
    765 	}
    766       else
    767 	vfinfo (config.map_file, fmt, arg, false);
    768       va_end (arg);
    769     }
    770 }
    771 
    772 void
    773 lfinfo (FILE *file, const char *fmt, ...)
    774 {
    775   va_list arg;
    776 
    777   va_start (arg, fmt);
    778   vfinfo (file, fmt, arg, false);
    779   va_end (arg);
    780 }
    781 
    782 /* Functions to print the link map.  */
    784 
    785 void
    786 print_spaces (int count)
    787 {
    788   fprintf (config.map_file, "%*s", count, "");
    789 }
    790 
    791 void
    792 print_nl (void)
    793 {
    794   fprintf (config.map_file, "\n");
    795 }
    796 
    797 /* A more or less friendly abort message.  In ld.h abort is defined to
    798    call this function.  */
    799 
    800 void
    801 ld_abort (const char *file, int line, const char *fn)
    802 {
    803   if (fn != NULL)
    804     einfo (_("%P: internal error: aborting at %s:%d in %s\n"),
    805 	   file, line, fn);
    806   else
    807     einfo (_("%P: internal error: aborting at %s:%d\n"),
    808 	   file, line);
    809   fatal (_("%P: please report this bug\n"));
    810 }
    811 
    812 /* Decode a hexadecimal character. Return -1 on error. */
    813 static int
    814 hexdecode (char c)
    815 {
    816   if ('0' <= c && c <= '9')
    817     return c - '0';
    818   if ('A' <= c && c <= 'F')
    819     return c - 'A' + 10;
    820   if ('a' <= c && c <= 'f')
    821     return c - 'a' + 10;
    822   return -1;
    823 }
    824 
    825 /* Decode a percent and/or %[string] encoded string. dst must be at least
    826    the same size as src. It can be converted in place.
    827 
    828    Following %[string] encodings are supported:
    829 
    830    %[comma] for ,
    831    %[lbrace] for {
    832    %[quot] for "
    833    %[rbrace] for }
    834    %[space] for ' '
    835 
    836    The percent decoding behaves the same as Python's urllib.parse.unquote. */
    837 void
    838 percent_decode (const char *src, char *dst)
    839 {
    840   while (*src != '\0')
    841     {
    842       char c = *src++;
    843       if (c == '%')
    844 	{
    845 	  char next1 = *src;
    846 	  int hex1 = hexdecode (next1);
    847 	  if (hex1 != -1)
    848 	    {
    849 	      int hex2 = hexdecode (*(src + 1));
    850 	      if (hex2 != -1)
    851 		{
    852 		  c = (char) ((hex1 << 4) + hex2);
    853 		  src += 2;
    854 		}
    855 	    }
    856 	  else if (next1 == '[')
    857 	    {
    858 	      if (strncmp (src + 1, "comma]", 6) == 0)
    859 		{
    860 		  c = ',';
    861 		  src += 7;
    862 		}
    863 	      else if (strncmp (src + 1, "lbrace]", 7) == 0)
    864 		{
    865 		  c = '{';
    866 		  src += 8;
    867 		}
    868 	      else if (strncmp (src + 1, "quot]", 5) == 0)
    869 		{
    870 		  c = '"';
    871 		  src += 6;
    872 		}
    873 	      else if (strncmp (src + 1, "rbrace]", 7) == 0)
    874 		{
    875 		  c = '}';
    876 		  src += 8;
    877 		}
    878 	      else if (strncmp (src + 1, "space]", 6) == 0)
    879 		{
    880 		  c = ' ';
    881 		  src += 7;
    882 		}
    883 	    }
    884 	}
    885       *dst++ = c;
    886     }
    887   *dst = '\0';
    888 }
    889