1 /* Generic stabs parsing for gas. 2 Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 98, 1999 3 Free Software Foundation, Inc. 4 5 This file is part of GAS, the GNU Assembler. 6 7 GAS is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2, 10 or (at your option) any later version. 11 12 GAS is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 the GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GAS; see the file COPYING. If not, write to the Free 19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. */ 21 22 #include "as.h" 23 #include "obstack.h" 24 #include "subsegs.h" 25 #include "ecoff.h" 26 27 /* We need this, despite the apparent object format dependency, since 28 it defines stab types, which all object formats can use now. */ 29 30 #include "aout/stab_gnu.h" 31 32 static void s_stab_generic PARAMS ((int, char *, char *)); 33 static void generate_asm_file PARAMS ((int, char *)); 34 35 /* Allow backends to override the names used for the stab sections. */ 36 #ifndef STAB_SECTION_NAME 37 #define STAB_SECTION_NAME ".stab" 38 #endif 39 40 #ifndef STAB_STRING_SECTION_NAME 41 #define STAB_STRING_SECTION_NAME ".stabstr" 42 #endif 43 44 /* Non-zero if we're in the middle of a .func function, in which case 45 stabs_generate_asm_lineno emits function relative line number stabs. 46 Otherwise it emits line number stabs with absolute addresses. Note that 47 both cases only apply to assembler code assembled with -gstabs. */ 48 static int in_dot_func_p; 49 50 /* Label at start of current function if in_dot_func_p != 0. */ 51 static const char *current_function_label; 52 53 /* 54 * Handle .stabX directives, which used to be open-coded. 55 * So much creeping featurism overloaded the semantics that we decided 56 * to put all .stabX thinking in one place. Here. 57 * 58 * We try to make any .stabX directive legal. Other people's AS will often 59 * do assembly-time consistency checks: eg assigning meaning to n_type bits 60 * and "protecting" you from setting them to certain values. (They also zero 61 * certain bits before emitting symbols. Tut tut.) 62 * 63 * If an expression is not absolute we either gripe or use the relocation 64 * information. Other people's assemblers silently forget information they 65 * don't need and invent information they need that you didn't supply. 66 */ 67 68 /* 69 * Build a string dictionary entry for a .stabX symbol. 70 * The symbol is added to the .<secname>str section. 71 */ 72 73 #ifndef SEPARATE_STAB_SECTIONS 74 #define SEPARATE_STAB_SECTIONS 0 75 #endif 76 77 unsigned int 78 get_stab_string_offset (string, stabstr_secname) 79 const char *string; 80 const char *stabstr_secname; 81 { 82 unsigned int length; 83 unsigned int retval; 84 segT save_seg; 85 subsegT save_subseg; 86 segT seg; 87 char *p; 88 89 if (! SEPARATE_STAB_SECTIONS) 90 abort (); 91 92 length = strlen (string); 93 94 save_seg = now_seg; 95 save_subseg = now_subseg; 96 97 /* Create the stab string section. */ 98 seg = subseg_new (stabstr_secname, 0); 99 100 retval = seg_info (seg)->stabu.stab_string_size; 101 if (retval <= 0) 102 { 103 /* Make sure the first string is empty. */ 104 p = frag_more (1); 105 *p = 0; 106 retval = seg_info (seg)->stabu.stab_string_size = 1; 107 #ifdef BFD_ASSEMBLER 108 bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING); 109 if (seg->name == stabstr_secname) 110 seg->name = xstrdup (stabstr_secname); 111 #endif 112 } 113 114 if (length > 0) 115 { /* Ordinary case. */ 116 p = frag_more (length + 1); 117 strcpy (p, string); 118 119 seg_info (seg)->stabu.stab_string_size += length + 1; 120 } 121 else 122 retval = 0; 123 124 subseg_set (save_seg, save_subseg); 125 126 return retval; 127 } 128 129 #ifdef AOUT_STABS 130 #ifndef OBJ_PROCESS_STAB 131 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D) 132 #endif 133 134 static void aout_process_stab PARAMS ((int, const char *, int, int, int)); 135 136 static void 137 aout_process_stab (what, string, type, other, desc) 138 int what; 139 const char *string; 140 int type, other, desc; 141 { 142 /* Put the stab information in the symbol table. */ 143 symbolS *symbol; 144 145 /* Create the symbol now, but only insert it into the symbol chain 146 after any symbols mentioned in the value expression get into the 147 symbol chain. This is to avoid "continuation symbols" (where one 148 ends in "\" and the debug info is continued in the next .stabs 149 directive) from being separated by other random symbols. */ 150 symbol = symbol_create (string, undefined_section, 0, 151 (struct frag *) NULL); 152 if (what == 's' || what == 'n') 153 { 154 /* Pick up the value from the input line. */ 155 symbol_set_frag (symbol, &zero_address_frag); 156 pseudo_set (symbol); 157 } 158 else 159 { 160 /* .stabd sets the name to NULL. Why? */ 161 S_SET_NAME (symbol, NULL); 162 symbol_set_frag (symbol, frag_now); 163 S_SET_VALUE (symbol, (valueT) frag_now_fix ()); 164 } 165 166 symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP); 167 168 S_SET_TYPE (symbol, type); 169 S_SET_OTHER (symbol, other); 170 S_SET_DESC (symbol, desc); 171 } 172 #endif 173 174 /* This can handle different kinds of stabs (s,n,d) and different 175 kinds of stab sections. */ 176 177 static void 178 s_stab_generic (what, stab_secname, stabstr_secname) 179 int what; 180 char *stab_secname; 181 char *stabstr_secname; 182 { 183 long longint; 184 char *string; 185 int type; 186 int other; 187 int desc; 188 189 /* The general format is: 190 .stabs "STRING",TYPE,OTHER,DESC,VALUE 191 .stabn TYPE,OTHER,DESC,VALUE 192 .stabd TYPE,OTHER,DESC 193 At this point input_line_pointer points after the pseudo-op and 194 any trailing whitespace. The argument what is one of 's', 'n' or 195 'd' indicating which type of .stab this is. */ 196 197 if (what != 's') 198 string = ""; 199 else 200 { 201 int length; 202 203 string = demand_copy_C_string (&length); 204 SKIP_WHITESPACE (); 205 if (*input_line_pointer == ',') 206 input_line_pointer++; 207 else 208 { 209 as_warn (_(".stabs: Missing comma")); 210 ignore_rest_of_line (); 211 return; 212 } 213 } 214 215 if (get_absolute_expression_and_terminator (&longint) != ',') 216 { 217 as_warn (_(".stab%c: Missing comma"), what); 218 ignore_rest_of_line (); 219 return; 220 } 221 type = longint; 222 223 if (get_absolute_expression_and_terminator (&longint) != ',') 224 { 225 as_warn (_(".stab%c: Missing comma"), what); 226 ignore_rest_of_line (); 227 return; 228 } 229 other = longint; 230 231 desc = get_absolute_expression (); 232 if (what == 's' || what == 'n') 233 { 234 if (*input_line_pointer != ',') 235 { 236 as_warn (_(".stab%c: Missing comma"), what); 237 ignore_rest_of_line (); 238 return; 239 } 240 input_line_pointer++; 241 SKIP_WHITESPACE (); 242 } 243 244 #ifdef TC_PPC 245 #ifdef OBJ_ELF 246 /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were 247 given 4 arguments, make it a .stabn */ 248 else if (what == 'd') 249 { 250 char *save_location = input_line_pointer; 251 252 SKIP_WHITESPACE (); 253 if (*input_line_pointer == ',') 254 { 255 input_line_pointer++; 256 what = 'n'; 257 } 258 else 259 input_line_pointer = save_location; 260 } 261 #endif /* OBJ_ELF */ 262 #endif /* TC_PPC */ 263 264 #ifndef NO_LISTING 265 if (listing) 266 { 267 switch (type) 268 { 269 case N_SLINE: 270 listing_source_line ((unsigned int) desc); 271 break; 272 case N_SO: 273 case N_SOL: 274 listing_source_file (string); 275 break; 276 } 277 } 278 #endif /* ! NO_LISTING */ 279 280 /* We have now gathered the type, other, and desc information. For 281 .stabs or .stabn, input_line_pointer is now pointing at the 282 value. */ 283 284 if (SEPARATE_STAB_SECTIONS) 285 /* Output the stab information in a separate section. This is used 286 at least for COFF and ELF. */ 287 { 288 segT saved_seg = now_seg; 289 subsegT saved_subseg = now_subseg; 290 fragS *saved_frag = frag_now; 291 valueT dot; 292 segT seg; 293 unsigned int stroff; 294 char *p; 295 296 static segT cached_sec; 297 static char *cached_secname; 298 299 dot = frag_now_fix (); 300 301 #ifdef md_flush_pending_output 302 md_flush_pending_output (); 303 #endif 304 305 if (cached_secname && !strcmp (cached_secname, stab_secname)) 306 { 307 seg = cached_sec; 308 subseg_set (seg, 0); 309 } 310 else 311 { 312 seg = subseg_new (stab_secname, 0); 313 if (cached_secname) 314 free (cached_secname); 315 cached_secname = xstrdup (stab_secname); 316 cached_sec = seg; 317 } 318 319 if (! seg_info (seg)->hadone) 320 { 321 #ifdef BFD_ASSEMBLER 322 bfd_set_section_flags (stdoutput, seg, 323 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING); 324 #endif 325 #ifdef INIT_STAB_SECTION 326 INIT_STAB_SECTION (seg); 327 #endif 328 seg_info (seg)->hadone = 1; 329 } 330 331 stroff = get_stab_string_offset (string, stabstr_secname); 332 if (what == 's') 333 { 334 /* release the string */ 335 obstack_free (¬es, string); 336 } 337 338 /* At least for now, stabs in a special stab section are always 339 output as 12 byte blocks of information. */ 340 p = frag_more (8); 341 md_number_to_chars (p, (valueT) stroff, 4); 342 md_number_to_chars (p + 4, (valueT) type, 1); 343 md_number_to_chars (p + 5, (valueT) other, 1); 344 md_number_to_chars (p + 6, (valueT) desc, 2); 345 346 if (what == 's' || what == 'n') 347 { 348 /* Pick up the value from the input line. */ 349 cons (4); 350 input_line_pointer--; 351 } 352 else 353 { 354 const char *fake; 355 symbolS *symbol; 356 expressionS exp; 357 358 /* Arrange for a value representing the current location. */ 359 fake = FAKE_LABEL_NAME; 360 symbol = symbol_new (fake, saved_seg, dot, saved_frag); 361 362 exp.X_op = O_symbol; 363 exp.X_add_symbol = symbol; 364 exp.X_add_number = 0; 365 366 emit_expr (&exp, 4); 367 } 368 369 #ifdef OBJ_PROCESS_STAB 370 OBJ_PROCESS_STAB (seg, what, string, type, other, desc); 371 #endif 372 373 subseg_set (saved_seg, saved_subseg); 374 } 375 else 376 { 377 #ifdef OBJ_PROCESS_STAB 378 OBJ_PROCESS_STAB (0, what, string, type, other, desc); 379 #else 380 abort (); 381 #endif 382 } 383 384 demand_empty_rest_of_line (); 385 } 386 387 /* Regular stab directive. */ 388 389 void 390 s_stab (what) 391 int what; 392 { 393 s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME); 394 } 395 396 /* "Extended stabs", used in Solaris only now. */ 397 398 void 399 s_xstab (what) 400 int what; 401 { 402 int length; 403 char *stab_secname, *stabstr_secname; 404 static char *saved_secname, *saved_strsecname; 405 406 /* @@ MEMORY LEAK: This allocates a copy of the string, but in most 407 cases it will be the same string, so we could release the storage 408 back to the obstack it came from. */ 409 stab_secname = demand_copy_C_string (&length); 410 SKIP_WHITESPACE (); 411 if (*input_line_pointer == ',') 412 input_line_pointer++; 413 else 414 { 415 as_bad (_("comma missing in .xstabs")); 416 ignore_rest_of_line (); 417 return; 418 } 419 420 /* To get the name of the stab string section, simply add "str" to 421 the stab section name. */ 422 if (saved_secname == 0 || strcmp (saved_secname, stab_secname)) 423 { 424 stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4); 425 strcpy (stabstr_secname, stab_secname); 426 strcat (stabstr_secname, "str"); 427 if (saved_secname) 428 { 429 free (saved_secname); 430 free (saved_strsecname); 431 } 432 saved_secname = stab_secname; 433 saved_strsecname = stabstr_secname; 434 } 435 s_stab_generic (what, saved_secname, saved_strsecname); 436 } 437 438 #ifdef S_SET_DESC 439 440 /* Frob invented at RMS' request. Set the n_desc of a symbol. */ 441 442 void 443 s_desc (ignore) 444 int ignore; 445 { 446 char *name; 447 char c; 448 char *p; 449 symbolS *symbolP; 450 int temp; 451 452 name = input_line_pointer; 453 c = get_symbol_end (); 454 p = input_line_pointer; 455 *p = c; 456 SKIP_WHITESPACE (); 457 if (*input_line_pointer != ',') 458 { 459 *p = 0; 460 as_bad (_("Expected comma after name \"%s\""), name); 461 *p = c; 462 ignore_rest_of_line (); 463 } 464 else 465 { 466 input_line_pointer++; 467 temp = get_absolute_expression (); 468 *p = 0; 469 symbolP = symbol_find_or_make (name); 470 *p = c; 471 S_SET_DESC (symbolP, temp); 472 } 473 demand_empty_rest_of_line (); 474 } /* s_desc() */ 475 476 #endif /* defined (S_SET_DESC) */ 477 478 /* Generate stabs debugging information to denote the main source file. */ 479 480 void 481 stabs_generate_asm_file () 482 { 483 char *file; 484 unsigned int lineno; 485 486 as_where (&file, &lineno); 487 generate_asm_file (N_SO, file); 488 } 489 490 /* Generate stabs debugging information to denote the source file. 491 TYPE is one of N_SO, N_SOL. */ 492 493 static void 494 generate_asm_file (type, file) 495 int type; 496 char *file; 497 { 498 static char *last_file; 499 static int label_count; 500 char *hold; 501 char *buf = xmalloc (2 * strlen (file) + 10); 502 char sym[30]; 503 504 /* Rather than try to do this in some efficient fashion, we just 505 generate a string and then parse it again. That lets us use the 506 existing stabs hook, which expect to see a string, rather than 507 inventing new ones. */ 508 509 hold = input_line_pointer; 510 511 if (last_file == NULL 512 || strcmp (last_file, file) != 0) 513 { 514 char *tmp = file; 515 char *endp = file + strlen(file); 516 char *bufp = buf; 517 518 sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count); 519 ++label_count; 520 521 *bufp++ = '"'; 522 while (tmp < endp) 523 { 524 char *bslash = strchr (tmp, '\\'); 525 int len = (bslash ? (bslash - tmp + 1) : strlen (tmp)); 526 /* double all backslashes, since demand_copy_C_string (used by 527 s_stab to extract the part in quotes) will try to replace them as 528 escape sequences. backslash may appear in a filespec. */ 529 strncpy (bufp, tmp, len); 530 tmp += len; 531 bufp += len; 532 if (bslash != NULL) 533 *bufp++ = '\\'; 534 } 535 sprintf (bufp, "\",%d,0,0,%s\n", type, sym); 536 input_line_pointer = buf; 537 s_stab ('s'); 538 colon (sym); 539 540 if (last_file != NULL) 541 free (last_file); 542 last_file = xstrdup (file); 543 } 544 545 input_line_pointer = hold; 546 free (buf); 547 } 548 549 /* Generate stabs debugging information for the current line. This is 550 used to produce debugging information for an assembler file. */ 551 552 void 553 stabs_generate_asm_lineno () 554 { 555 static int label_count; 556 char *hold; 557 char *file; 558 unsigned int lineno; 559 char *buf; 560 char sym[30]; 561 562 /* Rather than try to do this in some efficient fashion, we just 563 generate a string and then parse it again. That lets us use the 564 existing stabs hook, which expect to see a string, rather than 565 inventing new ones. */ 566 567 hold = input_line_pointer; 568 569 as_where (&file, &lineno); 570 571 generate_asm_file (N_SOL, file); 572 573 sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count); 574 ++label_count; 575 576 if (in_dot_func_p) 577 { 578 buf = (char *) alloca (100 + strlen (current_function_label)); 579 sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno, 580 sym, current_function_label); 581 } 582 else 583 { 584 buf = (char *) alloca (100); 585 sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym); 586 } 587 input_line_pointer = buf; 588 s_stab ('n'); 589 colon (sym); 590 591 input_line_pointer = hold; 592 } 593 594 /* Emit a function stab. 595 All assembler functions are assumed to have return type `void'. */ 596 597 void 598 stabs_generate_asm_func (funcname, startlabname) 599 const char *funcname; 600 const char *startlabname; 601 { 602 static int void_emitted_p; 603 char *hold = input_line_pointer; 604 char *buf; 605 char *file; 606 unsigned int lineno; 607 608 if (! void_emitted_p) 609 { 610 input_line_pointer = "\"void:t1=1\",128,0,0,0"; 611 s_stab ('s'); 612 void_emitted_p = 1; 613 } 614 615 as_where (&file, &lineno); 616 asprintf (&buf, "\"%s:F1\",%d,0,%d,%s", 617 funcname, N_FUN, lineno + 1, startlabname); 618 input_line_pointer = buf; 619 s_stab ('s'); 620 free (buf); 621 622 input_line_pointer = hold; 623 current_function_label = xstrdup (startlabname); 624 in_dot_func_p = 1; 625 } 626 627 /* Emit a stab to record the end of a function. */ 628 629 void 630 stabs_generate_asm_endfunc (funcname, startlabname) 631 const char *funcname ATTRIBUTE_UNUSED; 632 const char *startlabname; 633 { 634 static int label_count; 635 char *hold = input_line_pointer; 636 char *buf; 637 char sym[30]; 638 639 sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count); 640 ++label_count; 641 colon (sym); 642 643 asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname); 644 input_line_pointer = buf; 645 s_stab ('s'); 646 free (buf); 647 648 input_line_pointer = hold; 649 in_dot_func_p = 0; 650 current_function_label = NULL; 651 } 652