133965Sjdp/* ldmisc.c 2218822Sdim Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3218822Sdim 2001, 2002, 2003, 2004, 2005, 2006, 2007 460484Sobrien Free Software Foundation, Inc. 533965Sjdp Written by Steve Chamberlain of Cygnus Support. 633965Sjdp 7130561Sobrien This file is part of GLD, the Gnu Linker. 833965Sjdp 9130561Sobrien GLD is free software; you can redistribute it and/or modify 10130561Sobrien it under the terms of the GNU General Public License as published by 11130561Sobrien the Free Software Foundation; either version 2, or (at your option) 12130561Sobrien any later version. 1333965Sjdp 14130561Sobrien GLD is distributed in the hope that it will be useful, 15130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 16130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17130561Sobrien GNU General Public License for more details. 1833965Sjdp 19130561Sobrien You should have received a copy of the GNU General Public License 20130561Sobrien along with GLD; see the file COPYING. If not, write to the Free 21218822Sdim Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 22218822Sdim 02110-1301, USA. */ 2333965Sjdp 24218822Sdim#include "sysdep.h" 2533965Sjdp#include "bfd.h" 26130561Sobrien#include "bfdlink.h" 2733965Sjdp#include "libiberty.h" 2833965Sjdp#include "demangle.h" 2933965Sjdp#include <stdarg.h> 3033965Sjdp#include "ld.h" 3133965Sjdp#include "ldmisc.h" 3233965Sjdp#include "ldexp.h" 3333965Sjdp#include "ldlang.h" 34107492Sobrien#include <ldgram.h> 3533965Sjdp#include "ldlex.h" 3633965Sjdp#include "ldmain.h" 3733965Sjdp#include "ldfile.h" 38218822Sdim#include "elf-bfd.h" 3933965Sjdp 4033965Sjdp/* 4133965Sjdp %% literal % 42218822Sdim %A section name from a section 43218822Sdim %B filename from a bfd 44218822Sdim %C clever filename:linenumber with function 45218822Sdim %D like %C, but no function name 46218822Sdim %E current bfd error or errno 4733965Sjdp %F error is fatal 48218822Sdim %G like %D, but only function name 49218822Sdim %I filename from a lang_input_statement_type 5033965Sjdp %P print program name 51218822Sdim %R info about a relent 5233965Sjdp %S print script file and linenumber 5333965Sjdp %T symbol name 5433965Sjdp %V hex bfd_vma 5533965Sjdp %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces 56218822Sdim %X no object output, fail return 57218822Sdim %d integer, like printf 58218822Sdim %ld long, like printf 59218822Sdim %lu unsigned long, like printf 6033965Sjdp %s arbitrary string, like printf 6133965Sjdp %u integer, like printf 62218822Sdim %v hex bfd_vma, no leading zeros 6333965Sjdp*/ 6433965Sjdp 6533965Sjdpstatic void 66218822Sdimvfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning) 6733965Sjdp{ 68130561Sobrien bfd_boolean fatal = FALSE; 6933965Sjdp 7033965Sjdp while (*fmt != '\0') 7133965Sjdp { 7277298Sobrien while (*fmt != '%' && *fmt != '\0') 7333965Sjdp { 7433965Sjdp putc (*fmt, fp); 7533965Sjdp fmt++; 7633965Sjdp } 7733965Sjdp 7877298Sobrien if (*fmt == '%') 7933965Sjdp { 8077298Sobrien fmt++; 8177298Sobrien switch (*fmt++) 8233965Sjdp { 8333965Sjdp case '%': 8433965Sjdp /* literal % */ 8533965Sjdp putc ('%', fp); 8633965Sjdp break; 8733965Sjdp 8833965Sjdp case 'X': 8933965Sjdp /* no object output, fail return */ 90130561Sobrien config.make_executable = FALSE; 9133965Sjdp break; 9233965Sjdp 9333965Sjdp case 'V': 9433965Sjdp /* hex bfd_vma */ 9533965Sjdp { 9633965Sjdp bfd_vma value = va_arg (arg, bfd_vma); 9733965Sjdp fprintf_vma (fp, value); 9833965Sjdp } 9933965Sjdp break; 10033965Sjdp 10133965Sjdp case 'v': 10233965Sjdp /* hex bfd_vma, no leading zeros */ 10333965Sjdp { 10433965Sjdp char buf[100]; 10533965Sjdp char *p = buf; 10633965Sjdp bfd_vma value = va_arg (arg, bfd_vma); 10733965Sjdp sprintf_vma (p, value); 10833965Sjdp while (*p == '0') 10933965Sjdp p++; 11033965Sjdp if (!*p) 11133965Sjdp p--; 11233965Sjdp fputs (p, fp); 11333965Sjdp } 11433965Sjdp break; 11533965Sjdp 11633965Sjdp case 'W': 11733965Sjdp /* hex bfd_vma with 0x with no leading zeroes taking up 118130561Sobrien 8 spaces. */ 11933965Sjdp { 12033965Sjdp char buf[100]; 12133965Sjdp bfd_vma value; 12233965Sjdp char *p; 12333965Sjdp int len; 12433965Sjdp 12533965Sjdp value = va_arg (arg, bfd_vma); 12633965Sjdp sprintf_vma (buf, value); 12733965Sjdp for (p = buf; *p == '0'; ++p) 12833965Sjdp ; 12933965Sjdp if (*p == '\0') 13033965Sjdp --p; 13133965Sjdp len = strlen (p); 13233965Sjdp while (len < 8) 13333965Sjdp { 13433965Sjdp putc (' ', fp); 13533965Sjdp ++len; 13633965Sjdp } 13733965Sjdp fprintf (fp, "0x%s", p); 13833965Sjdp } 13933965Sjdp break; 14033965Sjdp 14133965Sjdp case 'T': 14233965Sjdp /* Symbol name. */ 14333965Sjdp { 14433965Sjdp const char *name = va_arg (arg, const char *); 14533965Sjdp 146130561Sobrien if (name == NULL || *name == 0) 14733965Sjdp { 148218822Sdim fprintf (fp, _("no symbol")); 149218822Sdim break; 150218822Sdim } 151218822Sdim else if (demangling) 152218822Sdim { 15333965Sjdp char *demangled; 15433965Sjdp 155218822Sdim demangled = bfd_demangle (output_bfd, name, 156218822Sdim DMGL_ANSI | DMGL_PARAMS); 157218822Sdim if (demangled != NULL) 158218822Sdim { 159218822Sdim fprintf (fp, "%s", demangled); 160218822Sdim free (demangled); 161218822Sdim break; 162218822Sdim } 16333965Sjdp } 164218822Sdim fprintf (fp, "%s", name); 16533965Sjdp } 16633965Sjdp break; 16733965Sjdp 168218822Sdim case 'A': 169218822Sdim /* section name from a section */ 170218822Sdim { 171218822Sdim asection *sec = va_arg (arg, asection *); 172218822Sdim bfd *abfd = sec->owner; 173218822Sdim const char *group = NULL; 174218822Sdim struct coff_comdat_info *ci; 175218822Sdim 176218822Sdim fprintf (fp, "%s", sec->name); 177218822Sdim if (abfd != NULL 178218822Sdim && bfd_get_flavour (abfd) == bfd_target_elf_flavour 179218822Sdim && elf_next_in_group (sec) != NULL 180218822Sdim && (sec->flags & SEC_GROUP) == 0) 181218822Sdim group = elf_group_name (sec); 182218822Sdim else if (abfd != NULL 183218822Sdim && bfd_get_flavour (abfd) == bfd_target_coff_flavour 184218822Sdim && (ci = bfd_coff_get_comdat_section (sec->owner, 185218822Sdim sec)) != NULL) 186218822Sdim group = ci->name; 187218822Sdim if (group != NULL) 188218822Sdim fprintf (fp, "[%s]", group); 189218822Sdim } 190218822Sdim break; 191218822Sdim 19233965Sjdp case 'B': 19333965Sjdp /* filename from a bfd */ 19477298Sobrien { 19533965Sjdp bfd *abfd = va_arg (arg, bfd *); 196218822Sdim 197218822Sdim if (abfd == NULL) 198218822Sdim fprintf (fp, "%s generated", program_name); 199218822Sdim else if (abfd->my_archive) 20033965Sjdp fprintf (fp, "%s(%s)", abfd->my_archive->filename, 20133965Sjdp abfd->filename); 20233965Sjdp else 20333965Sjdp fprintf (fp, "%s", abfd->filename); 20433965Sjdp } 20533965Sjdp break; 20633965Sjdp 20733965Sjdp case 'F': 20877298Sobrien /* Error is fatal. */ 209130561Sobrien fatal = TRUE; 21033965Sjdp break; 21133965Sjdp 21233965Sjdp case 'P': 21377298Sobrien /* Print program name. */ 21433965Sjdp fprintf (fp, "%s", program_name); 21533965Sjdp break; 21633965Sjdp 21733965Sjdp case 'E': 21833965Sjdp /* current bfd error or errno */ 21960484Sobrien fprintf (fp, "%s", bfd_errmsg (bfd_get_error ())); 22033965Sjdp break; 22133965Sjdp 22233965Sjdp case 'I': 22333965Sjdp /* filename from a lang_input_statement_type */ 22433965Sjdp { 22533965Sjdp lang_input_statement_type *i; 22633965Sjdp 22733965Sjdp i = va_arg (arg, lang_input_statement_type *); 22833965Sjdp if (bfd_my_archive (i->the_bfd) != NULL) 22933965Sjdp fprintf (fp, "(%s)", 23033965Sjdp bfd_get_filename (bfd_my_archive (i->the_bfd))); 23133965Sjdp fprintf (fp, "%s", i->local_sym_name); 23233965Sjdp if (bfd_my_archive (i->the_bfd) == NULL 23333965Sjdp && strcmp (i->local_sym_name, i->filename) != 0) 23433965Sjdp fprintf (fp, " (%s)", i->filename); 23533965Sjdp } 23633965Sjdp break; 23733965Sjdp 23833965Sjdp case 'S': 23977298Sobrien /* Print script file and linenumber. */ 24033965Sjdp if (parsing_defsym) 24133965Sjdp fprintf (fp, "--defsym %s", lex_string); 24233965Sjdp else if (ldfile_input_filename != NULL) 24333965Sjdp fprintf (fp, "%s:%u", ldfile_input_filename, lineno); 24433965Sjdp else 24560484Sobrien fprintf (fp, _("built in linker script:%u"), lineno); 24633965Sjdp break; 24733965Sjdp 24833965Sjdp case 'R': 24977298Sobrien /* Print all that's interesting about a relent. */ 25033965Sjdp { 25133965Sjdp arelent *relent = va_arg (arg, arelent *); 25277298Sobrien 25338889Sjdp lfinfo (fp, "%s+0x%v (type %s)", 25438889Sjdp (*(relent->sym_ptr_ptr))->name, 25538889Sjdp relent->addend, 25638889Sjdp relent->howto->name); 25733965Sjdp } 25833965Sjdp break; 25977298Sobrien 26033965Sjdp case 'C': 26133965Sjdp case 'D': 26233965Sjdp case 'G': 263130561Sobrien /* Clever filename:linenumber with function name if possible. 264130561Sobrien The arguments are a BFD, a section, and an offset. */ 26533965Sjdp { 26633965Sjdp static bfd *last_bfd; 26733965Sjdp static char *last_file = NULL; 26833965Sjdp static char *last_function = NULL; 26933965Sjdp bfd *abfd; 27033965Sjdp asection *section; 27133965Sjdp bfd_vma offset; 27233965Sjdp lang_input_statement_type *entry; 27333965Sjdp asymbol **asymbols; 27433965Sjdp const char *filename; 27533965Sjdp const char *functionname; 27633965Sjdp unsigned int linenumber; 277130561Sobrien bfd_boolean discard_last; 27833965Sjdp 27933965Sjdp abfd = va_arg (arg, bfd *); 28033965Sjdp section = va_arg (arg, asection *); 28133965Sjdp offset = va_arg (arg, bfd_vma); 28233965Sjdp 283218822Sdim if (abfd == NULL) 284218822Sdim { 285218822Sdim entry = NULL; 286218822Sdim asymbols = NULL; 287218822Sdim } 28833965Sjdp else 28933965Sjdp { 290218822Sdim entry = (lang_input_statement_type *) abfd->usrdata; 291218822Sdim if (entry != (lang_input_statement_type *) NULL 292218822Sdim && entry->asymbols != (asymbol **) NULL) 293218822Sdim asymbols = entry->asymbols; 294218822Sdim else 295218822Sdim { 296218822Sdim long symsize; 297218822Sdim long sym_count; 29833965Sjdp 299218822Sdim symsize = bfd_get_symtab_upper_bound (abfd); 300218822Sdim if (symsize < 0) 301218822Sdim einfo (_("%B%F: could not read symbols\n"), abfd); 302218822Sdim asymbols = xmalloc (symsize); 303218822Sdim sym_count = bfd_canonicalize_symtab (abfd, asymbols); 304218822Sdim if (sym_count < 0) 305218822Sdim einfo (_("%B%F: could not read symbols\n"), abfd); 306218822Sdim if (entry != (lang_input_statement_type *) NULL) 307218822Sdim { 308218822Sdim entry->asymbols = asymbols; 309218822Sdim entry->symbol_count = sym_count; 310218822Sdim } 31133965Sjdp } 31233965Sjdp } 31333965Sjdp 314218822Sdim /* The GNU Coding Standard requires that error messages 315218822Sdim be of the form: 316218822Sdim 317218822Sdim source-file-name:lineno: message 318130561Sobrien 319218822Sdim We do not always have a line number available so if 320218822Sdim we cannot find them we print out the section name and 321218822Sdim offset instread. */ 322130561Sobrien discard_last = TRUE; 323218822Sdim if (abfd != NULL 324218822Sdim && bfd_find_nearest_line (abfd, section, asymbols, offset, 325218822Sdim &filename, &functionname, 326218822Sdim &linenumber)) 32733965Sjdp { 328130561Sobrien if (functionname != NULL && fmt[-1] == 'C') 32933965Sjdp { 330218822Sdim /* Detect the case where we are printing out a 331218822Sdim message for the same function as the last 332218822Sdim call to vinfo ("%C"). In this situation do 333218822Sdim not print out the ABFD filename or the 334218822Sdim function name again. Note - we do still 335218822Sdim print out the source filename, as this will 336218822Sdim allow programs that parse the linker's output 337218822Sdim (eg emacs) to correctly locate multiple 338218822Sdim errors in the same source file. */ 33933965Sjdp if (last_bfd == NULL 34033965Sjdp || last_file == NULL 34133965Sjdp || last_function == NULL 34233965Sjdp || last_bfd != abfd 343130561Sobrien || (filename != NULL 344130561Sobrien && strcmp (last_file, filename) != 0) 34533965Sjdp || strcmp (last_function, functionname) != 0) 34633965Sjdp { 347218822Sdim lfinfo (fp, _("%B: In function `%T':\n"), 348218822Sdim abfd, functionname); 34933965Sjdp 35033965Sjdp last_bfd = abfd; 35133965Sjdp if (last_file != NULL) 35233965Sjdp free (last_file); 353130561Sobrien last_file = NULL; 354130561Sobrien if (filename) 355130561Sobrien last_file = xstrdup (filename); 35633965Sjdp if (last_function != NULL) 35733965Sjdp free (last_function); 35878828Sobrien last_function = xstrdup (functionname); 35933965Sjdp } 360130561Sobrien discard_last = FALSE; 36133965Sjdp } 362218822Sdim else 363218822Sdim lfinfo (fp, "%B:", abfd); 364130561Sobrien 365130561Sobrien if (filename != NULL) 366218822Sdim fprintf (fp, "%s:", filename); 367130561Sobrien 368130561Sobrien if (functionname != NULL && fmt[-1] == 'G') 369218822Sdim lfinfo (fp, "%T", functionname); 370130561Sobrien else if (filename != NULL && linenumber != 0) 371218822Sdim fprintf (fp, "%u", linenumber); 372218822Sdim else 373218822Sdim lfinfo (fp, "(%A+0x%v)", section, offset); 37433965Sjdp } 375218822Sdim else 376218822Sdim lfinfo (fp, "%B:(%A+0x%v)", abfd, section, offset); 37733965Sjdp 378130561Sobrien if (asymbols != NULL && entry == NULL) 379130561Sobrien free (asymbols); 380130561Sobrien 38133965Sjdp if (discard_last) 38233965Sjdp { 38333965Sjdp last_bfd = NULL; 38433965Sjdp if (last_file != NULL) 38533965Sjdp { 38633965Sjdp free (last_file); 38733965Sjdp last_file = NULL; 38833965Sjdp } 38933965Sjdp if (last_function != NULL) 39033965Sjdp { 39133965Sjdp free (last_function); 39233965Sjdp last_function = NULL; 39333965Sjdp } 39433965Sjdp } 39533965Sjdp } 39633965Sjdp break; 39777298Sobrien 39833965Sjdp case 's': 39933965Sjdp /* arbitrary string, like printf */ 40033965Sjdp fprintf (fp, "%s", va_arg (arg, char *)); 40133965Sjdp break; 40233965Sjdp 40333965Sjdp case 'd': 40433965Sjdp /* integer, like printf */ 40533965Sjdp fprintf (fp, "%d", va_arg (arg, int)); 40633965Sjdp break; 40733965Sjdp 40833965Sjdp case 'u': 40933965Sjdp /* unsigned integer, like printf */ 41033965Sjdp fprintf (fp, "%u", va_arg (arg, unsigned int)); 41133965Sjdp break; 412218822Sdim 413218822Sdim case 'l': 414218822Sdim if (*fmt == 'd') 415218822Sdim { 416218822Sdim fprintf (fp, "%ld", va_arg (arg, long)); 417218822Sdim ++fmt; 418218822Sdim break; 419218822Sdim } 420218822Sdim else if (*fmt == 'u') 421218822Sdim { 422218822Sdim fprintf (fp, "%lu", va_arg (arg, unsigned long)); 423218822Sdim ++fmt; 424218822Sdim break; 425218822Sdim } 426218822Sdim /* Fall thru */ 427218822Sdim 428218822Sdim default: 429218822Sdim fprintf (fp, "%%%c", fmt[-1]); 430218822Sdim break; 43133965Sjdp } 43233965Sjdp } 43333965Sjdp } 43433965Sjdp 435218822Sdim if (is_warning && config.fatal_warnings) 436130561Sobrien config.make_executable = FALSE; 43789857Sobrien 438130561Sobrien if (fatal) 43977298Sobrien xexit (1); 44033965Sjdp} 44133965Sjdp 44277298Sobrien/* Format info message and print on stdout. */ 44333965Sjdp 44433965Sjdp/* (You would think this should be called just "info", but then you 445130561Sobrien would be hosed by LynxOS, which defines that name in its libc.) */ 44633965Sjdp 44733965Sjdpvoid 448130561Sobrieninfo_msg (const char *fmt, ...) 44933965Sjdp{ 450130561Sobrien va_list arg; 45133965Sjdp 452130561Sobrien va_start (arg, fmt); 453218822Sdim vfinfo (stdout, fmt, arg, FALSE); 454130561Sobrien va_end (arg); 45533965Sjdp} 45633965Sjdp 45777298Sobrien/* ('e' for error.) Format info message and print on stderr. */ 45833965Sjdp 45933965Sjdpvoid 460130561Sobrieneinfo (const char *fmt, ...) 46133965Sjdp{ 462130561Sobrien va_list arg; 46333965Sjdp 464130561Sobrien va_start (arg, fmt); 465218822Sdim vfinfo (stderr, fmt, arg, TRUE); 466130561Sobrien va_end (arg); 46733965Sjdp} 46833965Sjdp 46977298Sobrienvoid 470130561Sobrieninfo_assert (const char *file, unsigned int line) 47133965Sjdp{ 47260484Sobrien einfo (_("%F%P: internal error %s %d\n"), file, line); 47333965Sjdp} 47433965Sjdp 47577298Sobrien/* ('m' for map) Format info message and print on map. */ 47633965Sjdp 47733965Sjdpvoid 478130561Sobrienminfo (const char *fmt, ...) 47933965Sjdp{ 480218822Sdim if (config.map_file != NULL) 481218822Sdim { 482218822Sdim va_list arg; 48333965Sjdp 484218822Sdim va_start (arg, fmt); 485218822Sdim vfinfo (config.map_file, fmt, arg, FALSE); 486218822Sdim va_end (arg); 487218822Sdim } 48833965Sjdp} 48933965Sjdp 49033965Sjdpvoid 491130561Sobrienlfinfo (FILE *file, const char *fmt, ...) 49233965Sjdp{ 493130561Sobrien va_list arg; 49433965Sjdp 495130561Sobrien va_start (arg, fmt); 496218822Sdim vfinfo (file, fmt, arg, FALSE); 497130561Sobrien va_end (arg); 49833965Sjdp} 49933965Sjdp 50033965Sjdp/* Functions to print the link map. */ 50133965Sjdp 50277298Sobrienvoid 503130561Sobrienprint_space (void) 50433965Sjdp{ 50533965Sjdp fprintf (config.map_file, " "); 50633965Sjdp} 50733965Sjdp 50877298Sobrienvoid 509130561Sobrienprint_nl (void) 51033965Sjdp{ 51133965Sjdp fprintf (config.map_file, "\n"); 51233965Sjdp} 51360484Sobrien 51460484Sobrien/* A more or less friendly abort message. In ld.h abort is defined to 51560484Sobrien call this function. */ 51660484Sobrien 51760484Sobrienvoid 518130561Sobrienld_abort (const char *file, int line, const char *fn) 51960484Sobrien{ 52060484Sobrien if (fn != NULL) 52160484Sobrien einfo (_("%P: internal error: aborting at %s line %d in %s\n"), 52260484Sobrien file, line, fn); 52360484Sobrien else 52460484Sobrien einfo (_("%P: internal error: aborting at %s line %d\n"), 52560484Sobrien file, line); 52660484Sobrien einfo (_("%P%F: please report this bug\n")); 52760484Sobrien xexit (1); 52860484Sobrien} 529