📄 dbxread.c
字号:
int type, desc; CORE_ADDR valu; char *name; struct section_offsets *section_offsets; struct objfile *objfile;{#ifndef SUN_FIXED_LBRAC_BUG /* This records the last pc address we've seen. We depend on there being an SLINE or FUN or SO before the first LBRAC, since the variable does not get reset in between reads of different symbol files. */ static CORE_ADDR last_pc_address;#endif register struct context_stack *new; /* This remembers the address of the start of a function. It is used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are relative to the current function's start address. On systems other than Solaris 2, this just holds the SECT_OFF_TEXT value, and is used to relocate these symbol types rather than SECTION_OFFSETS. */ static CORE_ADDR function_start_offset; char *colon_pos; /* Something is wrong if we see real data before seeing a source file name. */ if (last_source_file == NULL && type != (unsigned char)N_SO) { /* Currently this ignores N_ENTRY on Gould machines, N_NSYM on machines where that code is defined. */ if (IGNORE_SYMBOL (type)) return; /* FIXME, this should not be an error, since it precludes extending the symbol table information in this way... */ error ("Invalid symbol data: does not start by identifying a source file."); } switch (type) { case N_FUN: case N_FNAME:#if 0/* It seems that the Sun ANSI C compiler (acc) replaces N_FUN with N_GSYM and N_STSYM with a type code of f or F. Can't enable this until we get some stuff straightened out with psymtabs. FIXME. */ case N_GSYM: case N_STSYM:#endif /* 0 */ /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); /* Either of these types of symbols indicates the start of a new function. We must process its "name" normally for dbx, but also record the start of a new lexical context, and possibly also the end of the lexical context for the previous function. */ /* This is not always true. This type of symbol may indicate a text segment variable. */ colon_pos = strchr (name, ':'); if (!colon_pos++ || (*colon_pos != 'f' && *colon_pos != 'F')) { define_symbol (valu, name, desc, type, objfile); break; }#ifndef SUN_FIXED_LBRAC_BUG last_pc_address = valu; /* Save for SunOS bug circumcision */#endif#ifdef BLOCK_ADDRESS_FUNCTION_RELATIVE /* On Solaris 2.0 compilers, the block addresses and N_SLINE's are relative to the start of the function. On normal systems, and when using gcc on Solaris 2.0, these addresses are just absolute, or relative to the N_SO, depending on BLOCK_ADDRESS_ABSOLUTE. */ function_start_offset = valu; #else /* Default on ordinary systems */ function_start_offset = ANOFFSET (section_offsets, SECT_OFF_TEXT);#endif within_function = 1; if (context_stack_depth > 0) { new = pop_context (); /* Make a block for the local symbols within. */ finish_block (new->name, &local_symbols, new->old_blocks, new->start_addr, valu, objfile); } /* Stack must be empty now. */ if (context_stack_depth != 0) complain (&lbrac_unmatched_complaint, (char *) symnum); new = push_context (0, valu); new->name = define_symbol (valu, name, desc, type, objfile); break; case N_LBRAC: /* This "symbol" just indicates the start of an inner lexical context within a function. */#if defined(BLOCK_ADDRESS_ABSOLUTE) || defined(BLOCK_ADDRESS_FUNCTION_RELATIVE) /* Relocate for dynamic loading and Sun ELF acc fn-relative syms. */ valu += function_start_offset;#else /* On most machines, the block addresses are relative to the N_SO, the linker did not relocate them (sigh). */ valu += last_source_start_addr;#endif#ifndef SUN_FIXED_LBRAC_BUG if (valu < last_pc_address) { /* Patch current LBRAC pc value to match last handy pc value */ complain (&lbrac_complaint, 0); valu = last_pc_address; }#endif new = push_context (desc, valu); break; case N_RBRAC: /* This "symbol" just indicates the end of an inner lexical context that was started with N_LBRAC. */#if defined(BLOCK_ADDRESS_ABSOLUTE) || defined(BLOCK_ADDRESS_FUNCTION_RELATIVE) /* Relocate for dynamic loading and Sun ELF acc fn-relative syms. */ valu += function_start_offset;#else /* On most machines, the block addresses are relative to the N_SO, the linker did not relocate them (sigh). */ valu += last_source_start_addr;#endif new = pop_context(); if (desc != new->depth) complain (&lbrac_mismatch_complaint, (char *) symnum); /* Some compilers put the variable decls inside of an LBRAC/RBRAC block. This macro should be nonzero if this is true. DESC is N_DESC from the N_RBRAC symbol. GCC_P is true if we've detected the GCC_COMPILED_SYMBOL or the GCC2_COMPILED_SYMBOL. */#if !defined (VARIABLES_INSIDE_BLOCK)#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) 0#endif /* Can only use new->locals as local symbols here if we're in gcc or on a machine that puts them before the lbrack. */ if (!VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)) local_symbols = new->locals; /* If this is not the outermost LBRAC...RBRAC pair in the function, its local symbols preceded it, and are the ones just recovered from the context stack. Defined the block for them. If this is the outermost LBRAC...RBRAC pair, there is no need to do anything; leave the symbols that preceded it to be attached to the function's own block. However, if it is so, we need to indicate that we just moved outside of the function. */ if (local_symbols && (context_stack_depth > !VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))) { /* FIXME Muzzle a compiler bug that makes end < start. */ if (new->start_addr > valu) { complain(&lbrac_rbrac_complaint, 0); new->start_addr = valu; } /* Make a block for the local symbols within. */ finish_block (0, &local_symbols, new->old_blocks, new->start_addr, valu, objfile); } else { within_function = 0; } if (VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)) /* Now pop locals of block just finished. */ local_symbols = new->locals; break; case N_FN: case N_FN_SEQ: /* This kind of symbol indicates the start of an object file. */ /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); break; case N_SO: /* This type of symbol indicates the start of data for one source file. Finish the symbol table of the previous source file (if any) and start accumulating a new symbol table. */ /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);#ifndef SUN_FIXED_LBRAC_BUG last_pc_address = valu; /* Save for SunOS bug circumcision */#endif #ifdef PCC_SOL_BROKEN /* pcc bug, occasionally puts out SO for SOL. */ if (context_stack_depth > 0) { start_subfile (name, NULL); break; }#endif if (last_source_file) { /* Check if previous symbol was also an N_SO (with some sanity checks). If so, that one was actually the directory name, and the current one is the real file name. Patch things up. */ if (previous_stab_code == N_SO) { patch_subfile_names (current_subfile, name); break; /* Ignore repeated SOs */ } end_symtab (valu, 0, 0, objfile); end_stabs (); } start_stabs (); start_symtab (name, NULL, valu); break; case N_SOL: /* This type of symbol indicates the start of data for a sub-source-file, one whose contents were copied or included in the compilation of the main source file (whose name was given in the N_SO symbol.) */ /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); start_subfile (name, current_subfile->dirname); break; case N_BINCL: push_subfile (); add_new_header_file (name, valu); start_subfile (name, current_subfile->dirname); break; case N_EINCL: start_subfile (pop_subfile (), current_subfile->dirname); break; case N_EXCL: add_old_header_file (name, valu); break; case N_SLINE: /* This type of "symbol" really just records one line-number -- core-address correspondence. Enter it in the line list for this symbol table. */ /* Relocate for dynamic loading and for ELF acc fn-relative syms. */ valu += function_start_offset;#ifndef SUN_FIXED_LBRAC_BUG last_pc_address = valu; /* Save for SunOS bug circumcision */#endif record_line (current_subfile, desc, valu); break; case N_BCOMM: if (common_block) error ("Invalid symbol data: common within common at symtab pos %d", symnum); common_block = local_symbols; common_block_i = local_symbols ? local_symbols->nsyms : 0; break; case N_ECOMM: /* Symbols declared since the BCOMM are to have the common block start address added in when we know it. common_block points to the first symbol after the BCOMM in the local_symbols list; copy the list and hang it off the symbol for the common block name for later fixup. */ { int i; struct symbol *sym = (struct symbol *) xmmalloc (objfile -> md, sizeof (struct symbol)); memset (sym, 0, sizeof *sym); SYMBOL_NAME (sym) = savestring (name, strlen (name)); SYMBOL_CLASS (sym) = LOC_BLOCK; SYMBOL_NAMESPACE (sym) = (enum namespace)((long) copy_pending (local_symbols, common_block_i, common_block)); i = hashname (SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; global_sym_chain[i] = sym; common_block = 0; break; } /* The following symbol types need to have the appropriate offset added to their value; then we process symbol definitions in the name. */ case N_STSYM: /* Static symbol in data seg */ case N_LCSYM: /* Static symbol in BSS seg */ case N_ROSYM: /* Static symbol in Read-only data seg */ /* HORRID HACK DEPT. However, it's Sun's furgin' fault. FIXME. Solaris2's stabs-in-coff makes *most* symbols relative but leaves a few absolute. N_STSYM and friends sit on the fence. .stab "foo:S...",N_STSYM is absolute (ld relocates it) .stab "foo:V...",N_STSYM is relative (section base subtracted). This leaves us no choice but to search for the 'S' or 'V'... (or pass the whole section_offsets stuff down ONE MORE function call level, which we really don't want to do). */ { char *p; p = strchr (name, ':'); if (p != 0 && p[1] == 'S') { /* FIXME! We relocate it by the TEXT offset, in case the whole module moved in memory. But this is wrong, since the sections can side around independently. */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); goto define_a_symbol; } /* Since it's not the kludge case, re-dispatch to the right handler. */ switch (type) { case N_STSYM: goto case_N_STSYM; case N_LCSYM: goto case_N_LCSYM; case N_ROSYM: goto case_N_ROSYM; default: abort(); } } case_N_STSYM: /* Static symbol in data seg */ case N_DSLINE: /* Source line number, data seg */ valu += ANOFFSET (section_offsets, SECT_OFF_DATA); goto define_a_symbol; case_N_LCSYM: /* Static symbol in BSS seg */ case N_BSLINE: /* Source line number, bss seg */ /* N_BROWS: overlaps with N_BSLINE */ valu += ANOFFSET (section_offsets, SECT_OFF_BSS); goto define_a_symbol; case_N_ROSYM: /* Static symbol in Read-only data seg */ valu += ANOFFSET (section_offsets, SECT_OFF_RODATA); goto define_a_symbol; case N_ENTRY: /* Alternate entry point */ /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); goto define_a_symbol; /* The following symbol types don't need the address field relocated, since it is either unused, or is absolute. */ define_a_symbol: case N_GSYM: /* Global variable */ case N_NSYMS: /* Number of symbols (ultrix) */ case N_NOMAP: /* No map? (ultrix) */ case N_DEFD: /* Modula-2 GNU module dependency */ case N_SSYM: /* Struct or union element */ case N_LSYM: /* Local symbol in stack */ case N_PSYM: /* Parameter variable */ case N_LENG: /* Length of preceding symbol type */ if (name) define_symbol (valu, name, desc, type, objfile); break; case N_RSYM: /* Register variable */ /* XXX - bugs in gcc 2.1: the bogus name 'in$chrg' is output * for no clear reason with totally bogus values. We ignore * it. Also, when inline functions are invoked, an entry for * their "this" pointer is output. Unfortunately, it is usually * output as type 'P' instead of 'r' so gdb thinks there are * multiple 'this' arguments to the same function. We change * the type of all but the first 'P' to 'r' (reg var). (Note * that we (ab)use the fact that 'this' is the first parameter * and, thus, the first local symbol.) * CHECK THIS WHEN WE SWITCH TO GCC 2.2.x! */ if (name) { if (strncmp(name, "__in$chrg:", 10) == 0) break; if (local_symbols && strncmp(name, "$t:P", 4) == 0) name[3] = 'r'; define_symbol (valu, name, desc, type, objfile); } break; /* We use N_OPT to carry the gcc2_compiled flag. Sun uses it for a bunch of other flags, too. Someday we may parse their flags; for now we ignore theirs and hope they'll ignore ours. */ case N_OPT: /* Solaris 2: Compiler options */ if (name) { if (strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) ==
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -