obj-coff.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,530 行 · 第 1/5 页
C
2,530 行
/* coff object file format Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GAS. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#define OBJ_HEADER "obj-coff.h"#include "as.h"#include "obstack.h"#include "subsegs.h"/* I think this is probably always correct. */#ifndef KEEP_RELOC_INFO#define KEEP_RELOC_INFO#endif/* The BFD_ASSEMBLER version of obj_coff_section will use this macro to set a new section's attributes when a directive has no valid flags or the "w" flag is used. This default should be appropriate for most. */#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)#endifstatic void obj_coff_bss PARAMS ((int));const char *s_get_name PARAMS ((symbolS * s));static void obj_coff_ln PARAMS ((int));static void obj_coff_def PARAMS ((int));static void obj_coff_endef PARAMS ((int));static void obj_coff_dim PARAMS ((int));static void obj_coff_line PARAMS ((int));static void obj_coff_size PARAMS ((int));static void obj_coff_scl PARAMS ((int));static void obj_coff_tag PARAMS ((int));static void obj_coff_val PARAMS ((int));static void obj_coff_type PARAMS ((int));static void obj_coff_ident PARAMS ((int));#ifdef BFD_ASSEMBLERstatic void obj_coff_loc PARAMS((int));#endif/* This is used to hold the symbol built by a sequence of pseudo-ops from .def and .endef. */static symbolS *def_symbol_in_progress;/* stack stuff */typedef struct { unsigned long chunk_size; unsigned long element_size; unsigned long size; char *data; unsigned long pointer; }stack;static stack *stack_init (chunk_size, element_size) unsigned long chunk_size; unsigned long element_size;{ stack *st; st = (stack *) malloc (sizeof (stack)); if (!st) return 0; st->data = malloc (chunk_size); if (!st->data) { free (st); return 0; } st->pointer = 0; st->size = chunk_size; st->chunk_size = chunk_size; st->element_size = element_size; return st;}#if 0/* Not currently used. */static voidstack_delete (st) stack *st;{ free (st->data); free (st);}#endifstatic char *stack_push (st, element) stack *st; char *element;{ if (st->pointer + st->element_size >= st->size) { st->size += st->chunk_size; if ((st->data = xrealloc (st->data, st->size)) == (char *) 0) return (char *) 0; } memcpy (st->data + st->pointer, element, st->element_size); st->pointer += st->element_size; return st->data + st->pointer;}static char *stack_pop (st) stack *st;{ if (st->pointer < st->element_size) { st->pointer = 0; return (char *) 0; } st->pointer -= st->element_size; return st->data + st->pointer;}/* * Maintain a list of the tagnames of the structres. */static struct hash_control *tag_hash;static voidtag_init (){ tag_hash = hash_new ();}static voidtag_insert (name, symbolP) const char *name; symbolS *symbolP;{ const char *error_string; if ((error_string = hash_jam (tag_hash, name, (char *) symbolP))) { as_fatal (_("Inserting \"%s\" into structure table failed: %s"), name, error_string); }}static symbolS *tag_find (name) char *name;{#ifdef STRIP_UNDERSCORE if (*name == '_') name++;#endif /* STRIP_UNDERSCORE */ return (symbolS *) hash_find (tag_hash, name);}static symbolS *tag_find_or_make (name) char *name;{ symbolS *symbolP; if ((symbolP = tag_find (name)) == NULL) { symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); tag_insert (S_GET_NAME (symbolP), symbolP);#ifdef BFD_ASSEMBLER symbol_table_insert (symbolP);#endif } /* not found */ return symbolP;}/* We accept the .bss directive to set the section for backward compatibility with earlier versions of gas. */static voidobj_coff_bss (ignore) int ignore ATTRIBUTE_UNUSED;{ if (*input_line_pointer == '\n') subseg_new (".bss", get_absolute_expression ()); else s_lcomm (0);}/* Handle .weak. This is a GNU extension. */static voidobj_coff_weak (ignore) int ignore ATTRIBUTE_UNUSED;{ char *name; int c; symbolS *symbolP; do { name = input_line_pointer; c = get_symbol_end (); symbolP = symbol_find_or_make (name); *input_line_pointer = c; SKIP_WHITESPACE ();#if defined BFD_ASSEMBLER || defined S_SET_WEAK S_SET_WEAK (symbolP);#endif#ifdef TE_PE S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);#else S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);#endif if (c == ',') { input_line_pointer++; SKIP_WHITESPACE (); if (*input_line_pointer == '\n') c = '\n'; } } while (c == ','); demand_empty_rest_of_line ();}#ifdef BFD_ASSEMBLERstatic void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));#define GET_FILENAME_STRING(X) \((char*) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])/* @@ Ick. */static segTfetch_coff_debug_section (){ static segT debug_section; if (!debug_section) { CONST asymbol *s; s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0); assert (s != 0); debug_section = s->section; } return debug_section;}voidSA_SET_SYM_ENDNDX (sym, val) symbolS *sym; symbolS *val;{ combined_entry_type *entry, *p; entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1]; p = coffsymbol (symbol_get_bfdsym (val))->native; entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p; entry->fix_end = 1;}static voidSA_SET_SYM_TAGNDX (sym, val) symbolS *sym; symbolS *val;{ combined_entry_type *entry, *p; entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1]; p = coffsymbol (symbol_get_bfdsym (val))->native; entry->u.auxent.x_sym.x_tagndx.p = p; entry->fix_tag = 1;}static intS_GET_DATA_TYPE (sym) symbolS *sym;{ return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;}intS_SET_DATA_TYPE (sym, val) symbolS *sym; int val;{ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val; return val;}intS_GET_STORAGE_CLASS (sym) symbolS *sym;{ return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;}intS_SET_STORAGE_CLASS (sym, val) symbolS *sym; int val;{ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val; return val;}/* Merge a debug symbol containing debug information into a normal symbol. */voidc_symbol_merge (debug, normal) symbolS *debug; symbolS *normal;{ S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug)); S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug)); if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal)) { /* take the most we have */ S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); } if (S_GET_NUMBER_AUXILIARY (debug) > 0) { /* Move all the auxiliary information. */ memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug), (S_GET_NUMBER_AUXILIARY (debug) * sizeof (*SYM_AUXINFO (debug)))); } /* Move the debug flags. */ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));}voidc_dot_file_symbol (filename) const char *filename;{ symbolS *symbolP; /* BFD converts filename to a .file symbol with an aux entry. It also handles chaining. */ symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag); S_SET_STORAGE_CLASS (symbolP, C_FILE); S_SET_NUMBER_AUXILIARY (symbolP, 1); symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;#ifndef NO_LISTING { extern int listing; if (listing) { listing_source_file (filename); } }#endif /* Make sure that the symbol is first on the symbol chain */ if (symbol_rootP != symbolP) { symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); } /* if not first on the list */}/* Line number handling */struct line_no { struct line_no *next; fragS *frag; alent l;};int coff_line_base;/* Symbol of last function, which we should hang line#s off of. */static symbolS *line_fsym;#define in_function() (line_fsym != 0)#define clear_function() (line_fsym = 0)#define set_function(F) (line_fsym = (F), coff_add_linesym (F))voidcoff_obj_symbol_new_hook (symbolP) symbolS *symbolP;{ long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type); char * s = (char *) xmalloc (sz); memset (s, 0, sz); coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s; S_SET_DATA_TYPE (symbolP, T_NULL); S_SET_STORAGE_CLASS (symbolP, 0); S_SET_NUMBER_AUXILIARY (symbolP, 0); if (S_IS_STRING (symbolP)) SF_SET_STRING (symbolP); if (S_IS_LOCAL (symbolP)) SF_SET_LOCAL (symbolP);}/* * Handle .ln directives. */static symbolS *current_lineno_sym;static struct line_no *line_nos;/* @@ Blindly assume all .ln directives will be in the .text section... */int coff_n_line_nos;static voidadd_lineno (frag, offset, num) fragS *frag; addressT offset; int num;{ struct line_no *new_line = (struct line_no *) xmalloc (sizeof (struct line_no)); if (!current_lineno_sym) { abort (); }#ifndef OBJ_XCOFF /* The native aix assembler accepts negative line number */ if (num <= 0) { /* Zero is used as an end marker in the file. */ as_warn (_("Line numbers must be positive integers\n")); num = 1; }#endif /* OBJ_XCOFF */ new_line->next = line_nos; new_line->frag = frag; new_line->l.line_number = num; new_line->l.u.offset = offset; line_nos = new_line; coff_n_line_nos++;}voidcoff_add_linesym (sym) symbolS *sym;{ if (line_nos) { coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno = (alent *) line_nos; coff_n_line_nos++; line_nos = 0; } current_lineno_sym = sym;}static voidobj_coff_ln (appline) int appline;{ int l; if (! appline && def_symbol_in_progress != NULL) { as_warn (_(".ln pseudo-op inside .def/.endef: ignored.")); demand_empty_rest_of_line (); return; } l = get_absolute_expression (); if (!appline) { add_lineno (frag_now, frag_now_fix (), l); } if (appline) new_logical_line ((char *) NULL, l - 1);#ifndef NO_LISTING { extern int listing;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?