📄 mips-tfile.c
字号:
static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/static thead_t *cur_tag_head = (thead_t *)0; /* current tag head */static long file_offset = 0; /* current file offset */static long max_file_offset = 0; /* maximum file offset */static FILE *object_stream = (FILE *)0; /* file desc. to output .o */static FILE *obj_in_stream = (FILE *)0; /* file desc. to input .o */static char *progname = (char *)0; /* program name for errors */static char *input_name = "stdin"; /* name of input file */static char *object_name = (char *)0; /* tmp. name of object file */static char *obj_in_name = (char *)0; /* name of input object file */static char *cur_line_start = (char *)0; /* current line read in */static char *cur_line_ptr = (char *)0; /* ptr within current line */static unsigned cur_line_nbytes = 0; /* # bytes for current line */static unsigned cur_line_alloc = 0; /* # bytes total in buffer */static long line_number = 0; /* current input line number */static int debug = 0; /* trace functions */static int version = 0; /* print version # */static int had_errors = 0; /* != 0 if errors were found */static int rename_output = 0; /* != 0 if rename output file*/static int delete_input = 0; /* != 0 if delete input after done */static int stabs_seen = 0; /* != 0 if stabs have been seen *//* Pseudo symbol to use when putting stabs into the symbol table. */#ifndef STABS_SYMBOL#define STABS_SYMBOL "@stabs"#endifstatic char stabs_symbol[] = STABS_SYMBOL;/* Forward reference for functions. See the definition for more details. */#ifndef STATIC#define STATIC static#endifSTATIC int out_of_bounds __proto((symint_t, symint_t, const char *, int));STATIC shash_t *hash_string __proto((const char *, Ptrdiff_t, shash_t **, symint_t *));STATIC symint_t add_string __proto((varray_t *, shash_t **, const char *, const char *, shash_t **));STATIC symint_t add_local_symbol __proto((const char *, const char *, st_t, sc_t, symint_t, symint_t));STATIC symint_t add_ext_symbol __proto((const char *, const char *, st_t, sc_t, long, symint_t, int));STATIC symint_t add_aux_sym_symint __proto((symint_t));STATIC symint_t add_aux_sym_rndx __proto((int, symint_t));STATIC symint_t add_aux_sym_tir __proto((type_info_t *, hash_state_t, thash_t **));STATIC tag_t * get_tag __proto((const char *, const char *, symint_t, bt_t));STATIC void add_unknown_tag __proto((tag_t *));STATIC void add_procedure __proto((const char *, const char *));STATIC void add_file __proto((const char *, const char *));STATIC void add_bytes __proto((varray_t *, char *, Size_t));STATIC void add_varray_page __proto((varray_t *));STATIC void update_headers __proto((void));STATIC void write_varray __proto((varray_t *, off_t, const char *));STATIC void write_object __proto((void));STATIC char *st_to_string __proto((st_t));STATIC char *sc_to_string __proto((sc_t));STATIC char *read_line __proto((void));STATIC void parse_input __proto((void));STATIC void mark_stabs __proto((const char *));STATIC void parse_begin __proto((const char *));STATIC void parse_bend __proto((const char *));STATIC void parse_def __proto((const char *));STATIC void parse_end __proto((const char *));STATIC void parse_ent __proto((const char *));STATIC void parse_file __proto((const char *));STATIC void parse_stabs_common __proto((const char *, const char *, const char *));STATIC void parse_stabs __proto((const char *));STATIC void parse_stabn __proto((const char *));STATIC page_t *read_seek __proto((Size_t, off_t, const char *));STATIC void copy_object __proto((void));STATIC void catch_signal __proto((int));STATIC page_t *allocate_page __proto((void));STATIC page_t *allocate_multiple_pages __proto((Size_t));STATIC void free_multiple_pages __proto((page_t *, Size_t));#ifndef MALLOC_CHECKSTATIC page_t *allocate_cluster __proto((Size_t));#endifSTATIC forward_t *allocate_forward __proto((void));STATIC scope_t *allocate_scope __proto((void));STATIC shash_t *allocate_shash __proto((void));STATIC tag_t *allocate_tag __proto((void));STATIC thash_t *allocate_thash __proto((void));STATIC thead_t *allocate_thead __proto((void));STATIC vlinks_t *allocate_vlinks __proto((void));STATIC void free_forward __proto((forward_t *));STATIC void free_scope __proto((scope_t *));STATIC void free_tag __proto((tag_t *));STATIC void free_thead __proto((thead_t *));STATIC char *local_index __proto((const char *, int));STATIC char *local_rindex __proto((const char *, int));extern char *sbrk __proto((int));extern PTR_T malloc __proto((Size_t));extern PTR_T calloc __proto((Size_t, Size_t));extern PTR_T realloc __proto((PTR_T, Size_t));extern void free __proto((PTR_T));extern char *mktemp __proto((char *));extern long strtol __proto((const char *, char **, int));extern char *optarg;extern int optind;extern int opterr;extern char *version_string;extern char *sys_siglist[NSIG + 1];#ifndef SEEK_SET /* Symbolic constants for the "fseek" function: */#define SEEK_SET 0 /* Set file pointer to offset */#define SEEK_CUR 1 /* Set file pointer to its current value plus offset */#define SEEK_END 2 /* Set file pointer to the size of the file plus offset */#endif/* List of assembler pseudo ops and beginning sequences that need special actions. Someday, this should be a hash table, and such, but for now a linear list of names and calls to memcmp will do...... */typedef struct _pseudo_ops { const char *name; /* pseudo-op in ascii */ int len; /* length of name to compare */ void (*func) __proto((const char *)); /* function to handle line */} pseudo_ops_t;static pseudo_ops_t pseudo_ops[] = { { "#.def", sizeof("#.def")-1, parse_def }, { "#.begin", sizeof("#.begin")-1, parse_begin }, { "#.bend", sizeof("#.bend")-1, parse_bend }, { ".end", sizeof(".end")-1, parse_end }, { ".ent", sizeof(".ent")-1, parse_ent }, { ".file", sizeof(".file")-1, parse_file }, { "#.stabs", sizeof("#.stabs")-1, parse_stabs }, { "#.stabn", sizeof("#.stabn")-1, parse_stabn }, { ".stabs", sizeof(".stabs")-1, parse_stabs }, { ".stabn", sizeof(".stabn")-1, parse_stabn }, { "#@stabs", sizeof("#@stabs")-1, mark_stabs },};/* Add a page to a varray object. */STATIC voidadd_varray_page (vp) varray_t *vp; /* varray to add page to */{ vlinks_t *new_links = allocate_vlinks ();#ifdef MALLOC_CHECK if (vp->object_size > 1) new_links->datum = (page_t *) xcalloc (1, vp->object_size); else#endif new_links->datum = allocate_page (); alloc_counts[ (int)alloc_type_varray ].total_alloc++; alloc_counts[ (int)alloc_type_varray ].total_pages++; new_links->start_index = vp->num_allocated; vp->objects_last_page = 0; if (vp->first == (vlinks_t *)0) /* first allocation? */ vp->first = vp->last = new_links; else { /* 2nd or greater allocation */ new_links->prev = vp->last; vp->last->next = new_links; vp->last = new_links; }}/* Compute hash code (from tree.c) */#define HASHBITS 30STATIC shash_t *hash_string (text, hash_len, hash_tbl, ret_hash_index) const char *text; /* ptr to text to hash */ Ptrdiff_t hash_len; /* length of the text */ shash_t **hash_tbl; /* hash table */ symint_t *ret_hash_index; /* ptr to store hash index */{ register unsigned long hi; register Ptrdiff_t i; register shash_t *ptr; register int first_ch = *text; hi = hash_len; for (i = 0; i < hash_len; i++) hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff); hi &= (1 << HASHBITS) - 1; hi %= SHASH_SIZE; if (ret_hash_index != (symint_t *)0) *ret_hash_index = hi; for (ptr = hash_tbl[hi]; ptr != (shash_t *)0; ptr = ptr->next) if (hash_len == ptr->len && first_ch == ptr->string[0] && memcmp ((CPTR_T) text, (CPTR_T) ptr->string, hash_len) == 0) break; return ptr;}/* Add a string (and null pad) to one of the string tables. A consequence of hashing strings, is that we don't let strings cross page boundaries. The extra nulls will be ignored. */STATIC symint_tadd_string (vp, hash_tbl, start, end_p1, ret_hash) varray_t *vp; /* string virtual array */ shash_t **hash_tbl; /* ptr to hash table */ const char *start; /* 1st byte in string */ const char *end_p1; /* 1st byte after string */ shash_t **ret_hash; /* return hash pointer */{ register Ptrdiff_t len = end_p1 - start; register shash_t *hash_ptr; symint_t hi; if (len >= PAGE_USIZE) fatal ("String too big (%ld bytes)", (long) len); hash_ptr = hash_string (start, len, hash_tbl, &hi); if (hash_ptr == (shash_t *)0) { register char *p; if (vp->objects_last_page + len >= PAGE_USIZE) { vp->num_allocated = ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE; add_varray_page (vp); } hash_ptr = allocate_shash (); hash_ptr->next = hash_tbl[hi]; hash_tbl[hi] = hash_ptr; hash_ptr->len = len; hash_ptr->indx = vp->num_allocated; hash_ptr->string = p = & vp->last->datum->byte[ vp->objects_last_page ]; vp->objects_last_page += len+1; vp->num_allocated += len+1; while (len-- > 0) *p++ = *start++; *p = '\0'; } if (ret_hash != (shash_t **)0) *ret_hash = hash_ptr; return hash_ptr->indx;}/* Add a local symbol. */STATIC symint_tadd_local_symbol (str_start, str_end_p1, type, storage, value, indx) const char *str_start; /* first byte in string */ const char *str_end_p1; /* first byte after string */ st_t type; /* symbol type */ sc_t storage; /* storage class */ symint_t value; /* value of symbol */ symint_t indx; /* index to local/aux. syms */{ register symint_t ret; register SYMR *psym; register scope_t *pscope; register thead_t *ptag_head; register tag_t *ptag; register tag_t *ptag_next; register varray_t *vp = &cur_file_ptr->symbols; register int scope_delta = 0; shash_t *hash_ptr = (shash_t *)0; if (vp->objects_last_page == vp->objects_per_page) add_varray_page (vp); psym = &vp->last->datum->sym[ vp->objects_last_page++ ]; psym->value = value; psym->st = (unsigned) type; psym->sc = (unsigned) storage; psym->index = indx; psym->iss = (str_start == (const char *)0) ? 0 : add_string (&cur_file_ptr->strings, &cur_file_ptr->shash_head[0], str_start, str_end_p1, &hash_ptr); ret = vp->num_allocated++; if (MIPS_IS_STAB(psym)) return ret; /* Save the symbol within the hash table if this is a static item, and it has a name. */ if (hash_ptr != (shash_t *)0 && (type == st_Global || type == st_Static || type == st_Label || type == st_Proc || type == st_StaticProc)) hash_ptr->sym_ptr = psym; /* push or pop a scope if appropriate. */ switch (type) { default: break; case st_File: /* beginning of file */ case st_Proc: /* procedure */ case st_StaticProc: /* static procedure */ case st_Block: /* begin scope */ pscope = allocate_scope (); pscope->prev = cur_file_ptr->cur_scope; pscope->lsym = psym; pscope->lnumber = ret; pscope->type = type; cur_file_ptr->cur_scope = pscope; if (type != st_File) scope_delta = 1; /* For every block type except file, struct, union, or enumeration blocks, push a level on the tag stack. We omit file types, so that tags can span file boundaries. */ if (type != st_File && storage != sc_Info) { ptag_head = allocate_thead (); ptag_head->fir
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -