stabs.c revision 33965
1/* Generic stabs parsing for gas. 2 Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 1997 3 Free Software Foundation, Inc. 4 5This file is part of GAS, the GNU Assembler. 6 7GAS is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as 9published by the Free Software Foundation; either version 2, 10or (at your option) any later version. 11 12GAS is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15the GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GAS; see the file COPYING. If not, write to the Free 19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2002111-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 32static void s_stab_generic PARAMS ((int, char *, char *)); 33 34/* Allow backends to override the names used for the stab sections. */ 35#ifndef STAB_SECTION_NAME 36#define STAB_SECTION_NAME ".stab" 37#endif 38 39#ifndef STAB_STRING_SECTION_NAME 40#define STAB_STRING_SECTION_NAME ".stabstr" 41#endif 42 43/* 44 * Handle .stabX directives, which used to be open-coded. 45 * So much creeping featurism overloaded the semantics that we decided 46 * to put all .stabX thinking in one place. Here. 47 * 48 * We try to make any .stabX directive legal. Other people's AS will often 49 * do assembly-time consistency checks: eg assigning meaning to n_type bits 50 * and "protecting" you from setting them to certain values. (They also zero 51 * certain bits before emitting symbols. Tut tut.) 52 * 53 * If an expression is not absolute we either gripe or use the relocation 54 * information. Other people's assemblers silently forget information they 55 * don't need and invent information they need that you didn't supply. 56 */ 57 58/* 59 * Build a string dictionary entry for a .stabX symbol. 60 * The symbol is added to the .<secname>str section. 61 */ 62 63#ifndef SEPARATE_STAB_SECTIONS 64#define SEPARATE_STAB_SECTIONS 0 65#endif 66 67unsigned int 68get_stab_string_offset (string, stabstr_secname) 69 const char *string; 70 const char *stabstr_secname; 71{ 72 unsigned int length; 73 unsigned int retval; 74 75 if (! SEPARATE_STAB_SECTIONS) 76 abort (); 77 78 retval = 0; 79 length = strlen (string); 80 if (length > 0) 81 { /* Ordinary case. */ 82 segT save_seg; 83 subsegT save_subseg; 84 segT seg; 85 char *p; 86 87 save_seg = now_seg; 88 save_subseg = now_subseg; 89 90 /* Create the stab string section. */ 91 seg = subseg_new (stabstr_secname, 0); 92 93 retval = seg_info (seg)->stabu.stab_string_size; 94 if (retval <= 0) 95 { 96 /* Make sure the first string is empty. */ 97 p = frag_more (1); 98 *p = 0; 99 retval = seg_info (seg)->stabu.stab_string_size = 1; 100#ifdef BFD_ASSEMBLER 101 bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING); 102 if (seg->name == stabstr_secname) 103 seg->name = xstrdup (stabstr_secname); 104#endif 105 } 106 107 p = frag_more (length + 1); 108 strcpy (p, string); 109 110 seg_info (seg)->stabu.stab_string_size += length + 1; 111 112 subseg_set (save_seg, save_subseg); 113 } 114 115 return retval; 116} 117 118#ifdef AOUT_STABS 119#ifndef OBJ_PROCESS_STAB 120#define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D) 121#endif 122 123static void aout_process_stab PARAMS ((int, const char *, int, int, int)); 124 125static void 126aout_process_stab (what, string, type, other, desc) 127 int what; 128 const char *string; 129 int type, other, desc; 130{ 131 /* Put the stab information in the symbol table. */ 132 symbolS *symbol; 133 134 /* Create the symbol now, but only insert it into the symbol chain 135 after any symbols mentioned in the value expression get into the 136 symbol chain. This is to avoid "continuation symbols" (where one 137 ends in "\" and the debug info is continued in the next .stabs 138 directive) from being separated by other random symbols. */ 139 symbol = symbol_create (string, undefined_section, 0, 140 (struct frag *) NULL); 141 if (what == 's' || what == 'n') 142 { 143 /* Pick up the value from the input line. */ 144 symbol->sy_frag = &zero_address_frag; 145 pseudo_set (symbol); 146 } 147 else 148 { 149 /* .stabd sets the name to NULL. Why? */ 150 S_SET_NAME (symbol, NULL); 151 symbol->sy_frag = frag_now; 152 S_SET_VALUE (symbol, (valueT) frag_now_fix ()); 153 } 154 155 symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP); 156 157 S_SET_TYPE (symbol, type); 158 S_SET_OTHER (symbol, other); 159 S_SET_DESC (symbol, desc); 160} 161#endif 162 163/* This can handle different kinds of stabs (s,n,d) and different 164 kinds of stab sections. */ 165 166static void 167s_stab_generic (what, stab_secname, stabstr_secname) 168 int what; 169 char *stab_secname; 170 char *stabstr_secname; 171{ 172 long longint; 173 char *string; 174 int type; 175 int other; 176 int desc; 177 178 /* The general format is: 179 .stabs "STRING",TYPE,OTHER,DESC,VALUE 180 .stabn TYPE,OTHER,DESC,VALUE 181 .stabd TYPE,OTHER,DESC 182 At this point input_line_pointer points after the pseudo-op and 183 any trailing whitespace. The argument what is one of 's', 'n' or 184 'd' indicating which type of .stab this is. */ 185 186 if (what != 's') 187 string = ""; 188 else 189 { 190 int length; 191 192 string = demand_copy_C_string (&length); 193 SKIP_WHITESPACE (); 194 if (*input_line_pointer == ',') 195 input_line_pointer++; 196 else 197 { 198 as_warn (".stabs: Missing comma"); 199 ignore_rest_of_line (); 200 return; 201 } 202 } 203 204 if (get_absolute_expression_and_terminator (&longint) != ',') 205 { 206 as_warn (".stab%c: Missing comma", what); 207 ignore_rest_of_line (); 208 return; 209 } 210 type = longint; 211 212 if (get_absolute_expression_and_terminator (&longint) != ',') 213 { 214 as_warn (".stab%c: Missing comma", what); 215 ignore_rest_of_line (); 216 return; 217 } 218 other = longint; 219 220 desc = get_absolute_expression (); 221 if (what == 's' || what == 'n') 222 { 223 if (*input_line_pointer != ',') 224 { 225 as_warn (".stab%c: Missing comma", what); 226 ignore_rest_of_line (); 227 return; 228 } 229 input_line_pointer++; 230 SKIP_WHITESPACE (); 231 } 232 233#ifdef TC_PPC 234#ifdef OBJ_ELF 235 /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were 236 given 4 arguments, make it a .stabn */ 237 else if (what == 'd') 238 { 239 char *save_location = input_line_pointer; 240 241 SKIP_WHITESPACE (); 242 if (*input_line_pointer == ',') 243 { 244 input_line_pointer++; 245 what = 'n'; 246 } 247 else 248 input_line_pointer = save_location; 249 } 250#endif /* OBJ_ELF */ 251#endif /* TC_PPC */ 252 253#ifndef NO_LISTING 254 if (listing) 255 { 256 switch (type) 257 { 258 case N_SLINE: 259 listing_source_line ((unsigned int) desc); 260 break; 261 case N_SO: 262 case N_SOL: 263 listing_source_file (string); 264 break; 265 } 266 } 267#endif /* ! NO_LISTING */ 268 269 /* We have now gathered the type, other, and desc information. For 270 .stabs or .stabn, input_line_pointer is now pointing at the 271 value. */ 272 273 if (SEPARATE_STAB_SECTIONS) 274 /* Output the stab information in a separate section. This is used 275 at least for COFF and ELF. */ 276 { 277 segT saved_seg = now_seg; 278 subsegT saved_subseg = now_subseg; 279 fragS *saved_frag = frag_now; 280 valueT dot; 281 segT seg; 282 unsigned int stroff; 283 char *p; 284 285 static segT cached_sec; 286 static char *cached_secname; 287 288 dot = frag_now_fix (); 289 290 if (cached_secname && !strcmp (cached_secname, stab_secname)) 291 { 292 seg = cached_sec; 293 subseg_set (seg, 0); 294 } 295 else 296 { 297 seg = subseg_new (stab_secname, 0); 298 if (cached_secname) 299 free (cached_secname); 300 cached_secname = xstrdup (stab_secname); 301 cached_sec = seg; 302 } 303 304 if (! seg_info (seg)->hadone) 305 { 306#ifdef BFD_ASSEMBLER 307 bfd_set_section_flags (stdoutput, seg, 308 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING); 309#endif 310#ifdef INIT_STAB_SECTION 311 INIT_STAB_SECTION (seg); 312#endif 313 seg_info (seg)->hadone = 1; 314 } 315 316 stroff = get_stab_string_offset (string, stabstr_secname); 317 if (what == 's') 318 { 319 /* release the string */ 320 obstack_free (¬es, string); 321 } 322 323 /* At least for now, stabs in a special stab section are always 324 output as 12 byte blocks of information. */ 325 p = frag_more (8); 326 md_number_to_chars (p, (valueT) stroff, 4); 327 md_number_to_chars (p + 4, (valueT) type, 1); 328 md_number_to_chars (p + 5, (valueT) other, 1); 329 md_number_to_chars (p + 6, (valueT) desc, 2); 330 331 if (what == 's' || what == 'n') 332 { 333 /* Pick up the value from the input line. */ 334 cons (4); 335 input_line_pointer--; 336 } 337 else 338 { 339 const char *fake; 340 symbolS *symbol; 341 expressionS exp; 342 343 /* Arrange for a value representing the current location. */ 344 fake = FAKE_LABEL_NAME; 345 symbol = symbol_new (fake, saved_seg, dot, saved_frag); 346 347 exp.X_op = O_symbol; 348 exp.X_add_symbol = symbol; 349 exp.X_add_number = 0; 350 351 emit_expr (&exp, 4); 352 } 353 354#ifdef OBJ_PROCESS_STAB 355 OBJ_PROCESS_STAB (seg, what, string, type, other, desc); 356#endif 357 358 subseg_set (saved_seg, saved_subseg); 359 } 360 else 361 { 362#ifdef OBJ_PROCESS_STAB 363 OBJ_PROCESS_STAB (0, what, string, type, other, desc); 364#else 365 abort (); 366#endif 367 } 368 369 demand_empty_rest_of_line (); 370} 371 372/* Regular stab directive. */ 373 374void 375s_stab (what) 376 int what; 377{ 378 s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME); 379} 380 381/* "Extended stabs", used in Solaris only now. */ 382 383void 384s_xstab (what) 385 int what; 386{ 387 int length; 388 char *stab_secname, *stabstr_secname; 389 static char *saved_secname, *saved_strsecname; 390 391 /* @@ MEMORY LEAK: This allocates a copy of the string, but in most 392 cases it will be the same string, so we could release the storage 393 back to the obstack it came from. */ 394 stab_secname = demand_copy_C_string (&length); 395 SKIP_WHITESPACE (); 396 if (*input_line_pointer == ',') 397 input_line_pointer++; 398 else 399 { 400 as_bad ("comma missing in .xstabs"); 401 ignore_rest_of_line (); 402 return; 403 } 404 405 /* To get the name of the stab string section, simply add "str" to 406 the stab section name. */ 407 if (saved_secname == 0 || strcmp (saved_secname, stab_secname)) 408 { 409 stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4); 410 strcpy (stabstr_secname, stab_secname); 411 strcat (stabstr_secname, "str"); 412 if (saved_secname) 413 { 414 free (saved_secname); 415 free (saved_strsecname); 416 } 417 saved_secname = stab_secname; 418 saved_strsecname = stabstr_secname; 419 } 420 s_stab_generic (what, saved_secname, saved_strsecname); 421} 422 423#ifdef S_SET_DESC 424 425/* Frob invented at RMS' request. Set the n_desc of a symbol. */ 426 427void 428s_desc (ignore) 429 int ignore; 430{ 431 char *name; 432 char c; 433 char *p; 434 symbolS *symbolP; 435 int temp; 436 437 name = input_line_pointer; 438 c = get_symbol_end (); 439 p = input_line_pointer; 440 *p = c; 441 SKIP_WHITESPACE (); 442 if (*input_line_pointer != ',') 443 { 444 *p = 0; 445 as_bad ("Expected comma after name \"%s\"", name); 446 *p = c; 447 ignore_rest_of_line (); 448 } 449 else 450 { 451 input_line_pointer++; 452 temp = get_absolute_expression (); 453 *p = 0; 454 symbolP = symbol_find_or_make (name); 455 *p = c; 456 S_SET_DESC (symbolP, temp); 457 } 458 demand_empty_rest_of_line (); 459} /* s_desc() */ 460 461#endif /* defined (S_SET_DESC) */ 462