📄 symout.c
字号:
buffer.class = LOC_BLOCK; buffer.value.value = DECL_BLOCK_SYMTAB_ADDRESS (decl); } else buffer.class = LOC_EXTERNAL; } fwrite (&buffer, sizeof buffer, 1, symfile); next_address += sizeof buffer; i++; }}/* Output the tags (struct, union and enum definitions) for a block, given a list of them (a chain of TREE_LIST nodes) in TAGS. Store their addresses in the file into ADDR_BUFFER. */static voidsymout_block_tags (tags, addr_buffer) tree tags; int *addr_buffer;{ register tree tag; struct symbol buffer; register int i; for (tag = tags, i = 0; tag; tag = TREE_CHAIN (tag), i++) { buffer.name = (char *) next_address; symout_strings (IDENTIFIER_POINTER (TREE_PURPOSE (tag)), IDENTIFIER_LENGTH (TREE_PURPOSE (tag)), 0, 0); addr_buffer[i] = next_address; buffer.namespace = STRUCT_NAMESPACE; buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_VALUE (tag)); buffer.class = LOC_TYPEDEF; buffer.value.value = 0; fwrite (&buffer, sizeof buffer, 1, symfile); next_address += sizeof buffer; }}/* Output all the data structure for a "block" (any binding contour). DECLS is the chain of declarations of variables in this block. TAGS is the list of struct, union and enum tag definitions of this block. SUPERBLOCK_ADDRESS is the symtab file address of the containing block's data structure. */intsymout_block (decls, tags, args, superblock_address) tree decls; tree tags; tree args; int superblock_address;{ register tree decl; register int i; register int *addr_buffer; struct block buffer; int n_decls, n_tags, n_args, total; register struct blockvec_elt *velt; int block_address; for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl)) if (! TREE_EXTERNAL (decl) || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE) i++; n_decls = i; for (decl = args, i = 0; decl; decl = TREE_CHAIN (decl), i++); n_args = i; for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++); n_tags = i; total = n_decls + n_args + n_tags; addr_buffer = (int *) alloca (total * sizeof (int)); symout_block_symbols (args, addr_buffer, 0); symout_block_symbols (decls, addr_buffer + n_args, 0); symout_block_tags (tags, addr_buffer + n_decls + n_args); velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt)); velt->next = blockvec; velt->address = next_address; blockvec = velt; buffer.startaddr = 0; buffer.endaddr = 0; buffer.superblock = (struct block *) superblock_address; buffer.function = 0; buffer.nsyms = total; block_address = next_address; fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile); next_address += sizeof buffer - sizeof buffer.sym; fwrite (addr_buffer, sizeof (int), total, symfile); next_address += total * sizeof (int); fprintf (asmfile, "\t.gdbblock %d,%d\n", total_blocks + 2, block_address); total_blocks++; return block_address;}/* Walk STMT, the body of a function, and output symtab data on all the blocks that compose it and all symbols inside them. ARGS is a chain of decls for argument variables of the function. SUPERBLOCK_ADDRESS is the address of symbol data for the innermost block containing STMT; it is used for recursive calls, and is always 0 for the outermost call (since the containing block for a function is output later than the function). */intsymout_function (stmt, args, superblock_address) register tree stmt; tree args; int superblock_address;{ int address = superblock_address; while (stmt) { switch (TREE_CODE (stmt)) { case COMPOUND_STMT: case LOOP_STMT: symout_function (STMT_BODY (stmt), 0, address); break; case IF_STMT: symout_function (STMT_THEN (stmt), 0, address); symout_function (STMT_ELSE (stmt), 0, address); break; case LET_STMT: /* Ignore LET_STMTs for blocks never really used to make RTL. */ if (! TREE_USED (stmt)) break; address = symout_block (STMT_VARS (stmt), STMT_TYPE_TAGS (stmt), args, superblock_address); symout_function (STMT_SUBBLOCKS (stmt), 0, address); } stmt = TREE_CHAIN (stmt); } return address;}symout_function_end (){ /* Output dummy entries for any undefined structure references. */ symout_types (filter_undefined_types (temporary_fwd_refs)); temporary_fwd_refs = 0;}/* Output all the data structure for a top two blocks in a compilation. The top block is for public (global) symbols; the next one is for private (this file only) symbols. DECLS is the chain of declarations of variables in this block. TAGS is the list of struct, union and enum tag definitions. */voidsymout_top_blocks (decls, tags) tree decls; tree tags;{ register tree decl; register int i; register int *addr_buffer; struct block buffer; int n_decls, n_tags; register struct blockvec_elt *velt; int top_block_addr; /* First do the public-symbols block. */ for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl)) if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl)) i++; n_decls = i; addr_buffer = (int *) alloca (n_decls * sizeof (int)); symout_block_symbols (decls, addr_buffer, 2); fprintf (asmfile, ".text 0\n\t.gdbend 0\n"); fprintf (asmfile, "\t.gdbblock 0,%d\n", next_address); total_blocks++; velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt)); velt->next = blockvec; velt->address = next_address; blockvec = velt; top_block_addr = next_address; buffer.startaddr = 0; buffer.endaddr = 0; buffer.superblock = 0; buffer.function = 0; buffer.nsyms = n_decls;; fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile); next_address += sizeof buffer - sizeof buffer.sym; fwrite (addr_buffer, sizeof (int), n_decls, symfile); next_address += n_decls * sizeof (int); /* Next do the private-symbols block. */ for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl)) if (! TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl)) i++; n_decls = i; for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++); n_tags = i; addr_buffer = (int *) alloca ((n_decls + n_tags) * sizeof (int)); symout_block_symbols (decls, addr_buffer, 1); symout_block_tags (tags, addr_buffer + n_decls); fprintf (asmfile, "\t.gdbend 1\n"); fprintf (asmfile, "\t.gdbblock 1,%d\n", next_address); total_blocks++; velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt)); velt->next = blockvec; velt->address = next_address; blockvec = velt; buffer.startaddr = 0; buffer.endaddr = 0; buffer.superblock = (struct block *) top_block_addr; buffer.function = 0; buffer.nsyms = n_decls + n_tags;; fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile); next_address += sizeof buffer - sizeof buffer.sym; fwrite (addr_buffer, sizeof (int), n_decls + n_tags, symfile); next_address += (n_decls + n_tags) * sizeof (int);}/* Output the source-line-number information. *//* Output a `struct source' for the source file described by F. Return the address-in-the-symseg of the `struct source'. */static intsymout_source_file (f) struct gdbfile *f;{ /* Make the `struct source' big enough for as many lines as this file has. */ int size = sizeof (struct source) + (f->nlines - 1) * sizeof (struct line); struct source *buffer = (struct source *) alloca (size); int addr; /* Use zero for the line data, since assembler will store the real data. */ bzero (buffer, size); /* Output the file's name as a string. The assembler doesn't know this. */ buffer->name = (char *) next_address; symout_strings (f->name, 0, 0, 0); buffer->nlines = f->nlines; /* Write the structure. */ addr = next_address; fwrite (buffer, 1, size, symfile); next_address += size; /* Tell assembler where to write the real line-number data. */ fprintf (asmfile, "\t.gdblinetab %d,%d\n", f->filenum, addr + sizeof (int)); return addr;}/* Output the `struct sourcevector' which describes all the source files and points a `struct source' for each one. */static intsymout_sources (){ register struct gdbfile *f; int nfiles = 0; struct sourcevector *s; int i; int size; int addr; /* Count number of files to determine size of the sourcevector. */ for (f = gdbfiles; f; f = f->next) ++nfiles; /* Allocate buffer for the sourcevector and record its length. */ size = sizeof (int) + nfiles * sizeof (struct source *); s = (struct sourcevector *) alloca (size); s->length = nfiles; /* Output a `struct source' for each file; put address into sourcevector. */ for (f = gdbfiles, i = 0; f; f = f->next, i++) s->source[i] = (struct source *) symout_source_file (f); /* Output the sourcevector. */ addr = next_address; fwrite (s, 1, size, symfile); next_address += size; return addr;}/* Call here at the end of compilation, after outputting all the blocks and symbols, to output the blockvector and typevector and close the symbol table file. FILETIME is source file's creation time. */voidsymout_finish (filename, filetime) char *filename; int filetime;{ int *blockvector = (int *) alloca ((total_blocks + 1) * sizeof (int)); int *typevector; int now = time (0); register int i; struct symbol_root buffer; char dir[MAXNAMLEN]; /* Output dummy entries for any undefined structure references. */ symout_types (filter_undefined_types (permanent_fwd_refs)); typevector = (int *) alloca ((total_types + 1) * sizeof (int)); buffer.language = language_c; buffer.blockvector = (struct blockvector *) next_address; /* The two blocks at the beginning of the chain are the file's private symbols block and public symbols block. They belong at the front of the blockvector, in that order. */ blockvector[2] = blockvec->address; blockvec = blockvec->next; blockvector[1] = blockvec->address; blockvec = blockvec->next; /* The rest of the blocks are in the chain in reverse order. */ for (i = total_blocks; i > 2; i--) { blockvector[i] = blockvec->address; blockvec = blockvec->next; } blockvector[0] = total_blocks; fwrite (blockvector, sizeof (int), total_blocks + 1, symfile); next_address += sizeof (int) * (total_blocks + 1); buffer.typevector = (struct typevector *) next_address; for (i = total_types; i > 0; i--) { typevector[i] = typevec->address; typevec = typevec->next; } typevector[0] = total_types; fwrite (typevector, sizeof (int), total_types + 1, symfile); next_address += sizeof (int) * (total_types + 1); buffer.sourcevector = (struct sourcevector *) symout_sources (); buffer.format = 1; buffer.textrel = 0; /* These four will be set up by linker. */ buffer.datarel = 0; /* Make them 0 now, which is right for */ buffer.bssrel = 0; /* looking at the .o file in gdb. */ buffer.ldsymoff = 0; buffer.version = (char *) next_address; symout_strings (ctime (&filetime), 0, 0, 0); buffer.compilation = (char *) next_address; symout_strings (ctime (&now), 0, 0, 0); buffer.filename = (char *) next_address; symout_strings (filename, 0, 0, 0); buffer.filedir = (char *) next_address;#ifdef USG strcpy (dir, getcwd (dir, MAXNAMLEN));#else#ifndef VMS getwd (dir);#else abort ();#endif#endif symout_strings (dir, 0, 0, 0); fflush (symfile); if (ferror (symfile) != 0) fatal_io_error (symfile_name); buffer.length = next_address; if (lseek (fileno (symfile), 0, 0) < 0) pfatal_with_name (symfile_name); if (write (fileno (symfile), &buffer, sizeof buffer) < 0) pfatal_with_name (symfile_name); close (fileno (symfile));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -