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