📄 dbxout.c
字号:
output_quoted_string (asmfile, cwd); fprintf (asmfile, ",%d,0,0,%s\n", N_SO, <ext_label_name[1]);#endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ } }#ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME /* This should NOT be DBX_OUTPUT_SOURCE_FILENAME. That would give us an N_SOL, and we want an N_SO. */ DBX_OUTPUT_MAIN_SOURCE_FILENAME (asmfile, input_file_name);#else /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ /* We include outputting `Ltext:' here, because that gives you a way to override it. */ /* Used to put `Ltext:' before the reference, but that loses on sun 4. */ fprintf (asmfile, "%s ", ASM_STABS_OP); output_quoted_string (asmfile, input_file_name); fprintf (asmfile, ",%d,0,0,%s\n", N_SO, <ext_label_name[1]); text_section (); ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0);#endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ /* Possibly output something to inform GDB that this compilation was by GCC. It's easier for GDB to parse it when after the N_SO's. This is used in Solaris 2. */#ifdef ASM_IDENTIFY_GCC_AFTER_SOURCE ASM_IDENTIFY_GCC_AFTER_SOURCE (asmfile);#endif lastfile = input_file_name; next_type_number = 1; next_block_number = 2; /* Make sure that types `int' and `char' have numbers 1 and 2. Definitions of other integer types will refer to those numbers. (Actually it should no longer matter what their numbers are. Also, if any types with tags have been defined, dbxout_symbol will output them first, so the numbers won't be 1 and 2. That happens in C++. So it's a good thing it should no longer matter). */#ifdef DBX_OUTPUT_STANDARD_TYPES DBX_OUTPUT_STANDARD_TYPES (syms);#else dbxout_symbol (TYPE_NAME (integer_type_node), 0); dbxout_symbol (TYPE_NAME (char_type_node), 0);#endif /* Get all permanent types that have typedef names, and output them all, except for those already output. */ dbxout_typedefs (syms);}/* Output any typedef names for types described by TYPE_DECLs in SYMS, in the reverse order from that which is found in SYMS. */static voiddbxout_typedefs (syms) tree syms;{ if (syms) { dbxout_typedefs (TREE_CHAIN (syms)); if (TREE_CODE (syms) == TYPE_DECL) { tree type = TREE_TYPE (syms); if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ! TREE_ASM_WRITTEN (TYPE_NAME (type))) dbxout_symbol (TYPE_NAME (type), 0); } }}/* Output debugging info to FILE to switch to sourcefile FILENAME. */voiddbxout_source_file (file, filename) FILE *file; char *filename;{ char ltext_label_name[100]; if (filename && (lastfile == 0 || strcmp (filename, lastfile))) {#ifdef DBX_OUTPUT_SOURCE_FILENAME DBX_OUTPUT_SOURCE_FILENAME (file, filename);#else ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", source_label_number); fprintf (file, "%s ", ASM_STABS_OP); output_quoted_string (file, filename); fprintf (file, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); if (current_function_decl != NULL_TREE && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) ; /* Don't change section amid function. */ else text_section (); ASM_OUTPUT_INTERNAL_LABEL (file, "Ltext", source_label_number); source_label_number++;#endif lastfile = filename; }}/* Output a line number symbol entry into output stream FILE, for source file FILENAME and line number LINENO. */voiddbxout_source_line (file, filename, lineno) FILE *file; char *filename; int lineno;{ dbxout_source_file (file, filename);#ifdef ASM_OUTPUT_SOURCE_LINE ASM_OUTPUT_SOURCE_LINE (file, lineno);#else fprintf (file, "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno);#endif}/* At the end of compilation, finish writing the symbol table. Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is to do nothing. */voiddbxout_finish (file, filename) FILE *file; char *filename;{#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename);#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */}/* Continue a symbol-description that gets too big. End one symbol table entry with a double-backslash and start a new one, eventually producing something like .stabs "start......\\",code,0,value .stabs "...rest",code,0,value */static voiddbxout_continue (){#ifdef DBX_CONTIN_CHAR fprintf (asmfile, "%c", DBX_CONTIN_CHAR);#else fprintf (asmfile, "\\\\");#endif dbxout_finish_symbol (NULL_TREE); fprintf (asmfile, "%s \"", ASM_STABS_OP); current_sym_nchars = 0;}/* Subroutine of `dbxout_type'. Output the type fields of TYPE. This must be a separate function because anonymous unions require recursive calls. */static voiddbxout_type_fields (type) tree type;{ tree tem; /* Output the name, type, position (in bits), size (in bits) of each field. */ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) { /* Omit here local type decls until we know how to support them. */ if (TREE_CODE (tem) == TYPE_DECL) continue; /* Omit fields whose position or size are variable. */ else if (TREE_CODE (tem) == FIELD_DECL && (TREE_CODE (DECL_FIELD_BITPOS (tem)) != INTEGER_CST || TREE_CODE (DECL_SIZE (tem)) != INTEGER_CST)) continue; /* Omit here the nameless fields that are used to skip bits. */ else if (TREE_CODE (tem) != CONST_DECL) { /* Continue the line if necessary, but not before the first field. */ if (tem != TYPE_FIELDS (type)) CONTIN; if (use_gnu_debug_info_extensions && flag_minimal_debug && TREE_CODE (tem) == FIELD_DECL && DECL_VIRTUAL_P (tem) && DECL_ASSEMBLER_NAME (tem)) { have_used_extensions = 1; CHARS (3 + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (tem))); fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile); dbxout_type (DECL_FCONTEXT (tem), 0, 0); fprintf (asmfile, ":"); dbxout_type (TREE_TYPE (tem), 0, 0); fprintf (asmfile, ",%d;", TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); continue; } if (DECL_NAME (tem)) { fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem))); CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem))); } else { fprintf (asmfile, ":"); CHARS (2); } if (use_gnu_debug_info_extensions && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem) || TREE_CODE (tem) != FIELD_DECL)) { have_used_extensions = 1; putc ('/', asmfile); putc ((TREE_PRIVATE (tem) ? '0' : TREE_PROTECTED (tem) ? '1' : '2'), asmfile); CHARS (2); } dbxout_type ((TREE_CODE (tem) == FIELD_DECL && DECL_BIT_FIELD_TYPE (tem)) ? DECL_BIT_FIELD_TYPE (tem) : TREE_TYPE (tem), 0, 0); if (TREE_CODE (tem) == VAR_DECL) { if (TREE_STATIC (tem) && use_gnu_debug_info_extensions) { char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); have_used_extensions = 1; fprintf (asmfile, ":%s;", name); CHARS (strlen (name)); } else { /* If TEM is non-static, GDB won't understand it. */ fprintf (asmfile, ",0,0;"); } } else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) { fprintf (asmfile, ",%d,%d;", TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)), TREE_INT_CST_LOW (DECL_SIZE (tem))); } CHARS (23); } }}/* Subroutine of `dbxout_type_methods'. Output debug info about the method described DECL. DEBUG_NAME is an encoding of the method's type signature. ??? We may be able to do without DEBUG_NAME altogether now. */static voiddbxout_type_method_1 (decl, debug_name) tree decl; char *debug_name;{ char c1 = 'A', c2; if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) c2 = '?'; else /* it's a METHOD_TYPE. */ { tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))); /* A for normal functions. B for `const' member functions. C for `volatile' member functions. D for `const volatile' member functions. */ if (TYPE_READONLY (TREE_TYPE (firstarg))) c1 += 1; if (TYPE_VOLATILE (TREE_TYPE (firstarg))) c1 += 2; if (DECL_VINDEX (decl)) c2 = '*'; else c2 = '.'; } fprintf (asmfile, ":%s;%c%c%c", debug_name, TREE_PRIVATE (decl) ? '0' : TREE_PROTECTED (decl) ? '1' : '2', c1, c2); CHARS (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 6 - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))); if (DECL_VINDEX (decl)) { fprintf (asmfile, "%d;", TREE_INT_CST_LOW (DECL_VINDEX (decl))); dbxout_type (DECL_CONTEXT (decl), 0, 0); fprintf (asmfile, ";"); CHARS (8); }}/* Subroutine of `dbxout_type'. Output debug info about the methods defined in TYPE. */static voiddbxout_type_methods (type) register tree type;{ /* C++: put out the method names and their parameter lists */ tree methods = TYPE_METHODS (type); tree type_encoding; register tree fndecl; register tree last; char formatted_type_identifier_length[16]; register int type_identifier_length; if (methods == NULL_TREE) return; type_encoding = DECL_NAME (TYPE_NAME (type));#if 0 /* C++: Template classes break some assumptions made by this code about the class names, constructor names, and encodings for assembler label names. For now, disable output of dbx info for them. */ { char *ptr = IDENTIFIER_POINTER (type_encoding); /* This should use index. (mrs) */ while (*ptr && *ptr != '<') ptr++; if (*ptr != 0) { static int warned; if (!warned) { warned = 1;#ifdef HAVE_TEMPLATES if (warn_template_debugging) warning ("dbx info for template class methods not yet supported");#endif } return; } }#endif type_identifier_length = IDENTIFIER_LENGTH (type_encoding); sprintf(formatted_type_identifier_length, "%d", type_identifier_length); if (TREE_CODE (methods) == FUNCTION_DECL) fndecl = methods; else if (TREE_VEC_ELT (methods, 0) != NULL_TREE) fndecl = TREE_VEC_ELT (methods, 0); else fndecl = TREE_VEC_ELT (methods, 1); while (fndecl) { tree name = DECL_NAME (fndecl); int need_prefix = 1; /* Group together all the methods for the same operation. These differ in the types of the arguments. */ for (last = NULL_TREE; fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last)); fndecl = TREE_CHAIN (fndecl)) /* Output the name of the field (after overloading), as well as the name of the field before overloading, along with its parameter list */ { /* This is the "mangled" name of the method. It encodes the argument types. */ char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); int destructor = 0; CONTIN; last = fndecl; if (DECL_IGNORED_P (fndecl)) continue; if (flag_minimal_debug) { /* Detect ordinary methods because their mangled names start with the operation name. */ if (!strncmp (IDENTIFIER_POINTER (name), debug_name, IDENTIFIER_LENGTH (name))) { debug_name += IDENTIFIER_LENGTH (name); if (debug_name[0] == '_' && debug_name[1] == '_') { char *method_name = debug_name + 2; char *length_ptr = formatted_type_identifier_length; /* Get past const and volatile qualifiers. */ while (*method_name == 'C' || *method_name == 'V') method_name++; /* Skip digits for length of type_encoding. */ while (*method_name == *length_ptr && *length_ptr) length_ptr++, method_name++; if (! strncmp (method_name, IDENTIFIER_POINTER (type_encoding), type_identifier_length)) method_name += type_identifier_length; debug_name = method_name; } } /* Detect constructors by their style of name mangling. */ else if (debug_name[0] == '_' && debug_name[1] == '_') { char *ctor_name = debug_name + 2; char *length_ptr = formatted_type_identifier_length; while (*ctor_name == 'C' || *ctor_name == 'V') ctor_name++; /* Skip digits for length of type_encoding. */ while (*ctor_name == *length_ptr && *length_ptr) length_ptr++, ctor_name++; if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name, type_identifier_length)) debug_name = ctor_name + type_identifier_length; } /* The other alternative is a destructor. */ else destructor = 1; /* Output the operation name just once, for the first method that we output. */ if (need_prefix) { fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -