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