From 98c6bbbe43cf8e658aa0b300f60da67789cacf56 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 28 Jan 1994 01:21:53 +0000 Subject: [PATCH] * as.h: If __GNUC__ and inline are both undefined, define inline away. * write.c (cvt_frag_to_fill): Don't assume that fr_var for rs_align or rs_org frags will be 1. (relax_segment): For rs_align, if fr_var is not 1, complain if required padding is not a multiple of the size of the pad pattern. (fixup_segment): Leave gp-relative relocations alone. For pcrel relocations referring to the same segment, clear fx_pcrel when clearing fx_addsy. * as.h: Adjust comments on rs_align. * write.c, config/obj-{aout,bout,coff*}.c, config/tc-sparc.c: Query the fx_done field instead of fx_addsy to see if the fixup still needs to be applied. Set fx_done and clear fx_addsy both, for now. If TC_HANDLES_FX_DONE isn't defined, assume md_apply_fix will only clear fx_addsy, and set fx_done accordingly after returning. * config/tc-sparc.h (TC_HANDLES_FX_DONE): Define. * config/obj-coff.c (dot_text_symbol, dot_data_symbol, dot_bss_symbol): Defined here, static. * config/obj-aout.c [BFD_ASSEMBLER]: Undef NO_RELOC before including aout/aout64.h. * write.c (write_object_file): If EMIT_SECTION_SYMBOLS is false, don't write out a section symbol even if it's used in a relocation; assume relocations will handle section numbers somehow. Rename "punt_it" label to "punt_it_if_unused" to reflect it's true use. (EMIT_SECTION_SYMBOLS): Default to 1. (adjust_reloc_syms): Don't create a new symbol for an absolute reference; just use the absolute section symbol. (write_relocs): Make printout of reloc values dependent on flag DEBUG3, not DEBUG2. * config/obj-aout.h (EMIT_SECTION_SYMBOLS): Define as 0. * config/obj-ecoff.h (EMIT_SECTION_SYMBOLS): Ditto. --- gas/as.h | 6 +- gas/config/obj-bout.c | 2 +- gas/config/obj-coff.c | 417 +++++++++++++++------------------------ gas/config/obj-coffbfd.c | 23 +-- gas/config/obj-ecoff.h | 2 + gas/write.c | 126 +++++++----- 6 files changed, 266 insertions(+), 310 deletions(-) diff --git a/gas/as.h b/gas/as.h index 0deb6004004..53355267317 100644 --- a/gas/as.h +++ b/gas/as.h @@ -79,6 +79,10 @@ #endif #endif /* ! __STDC__ */ +#if !defined (__GNUC__) && !defined (inline) +#define inline +#endif + #ifndef FOPEN_WB #include "fopen-same.h" #endif @@ -228,7 +232,7 @@ typedef enum _relax_state constant length frag. */ rs_fill = 1, - /* Align: Fr_offset: power of 2. 1 variable char: fill character. */ + /* Align: Fr_offset: power of 2. Variable chars: fill pattern. */ rs_align, /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c index c08406f473b..fef8eacc947 100644 --- a/gas/config/obj-bout.c +++ b/gas/config/obj-bout.c @@ -93,7 +93,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file) { for (; fixP; fixP = fixP->fx_next) { - if (fixP->fx_addsy != NULL + if (fixP->fx_done == 0 || fixP->fx_r_type != NO_RELOC) { tc_bout_fix_to_chars (*where, fixP, segment_address_in_file); diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index e0eca7a815c..36e5105ad59 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1,5 +1,5 @@ /* coff object file format - Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GAS. @@ -22,7 +22,6 @@ #include "obstack.h" #ifndef BFD_ASSEMBLER -lineno *lineno_rootP; const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */ @@ -31,11 +30,8 @@ const short seg_N_TYPE[] = C_DATA_SECTION, C_BSS_SECTION, C_UNDEF_SECTION, /* SEG_UNKNOWN */ - C_UNDEF_SECTION, /* SEG_ABSENT */ - C_UNDEF_SECTION, /* SEG_PASS1 */ C_UNDEF_SECTION, /* SEG_GOOF */ - C_UNDEF_SECTION, /* SEG_BIG */ - C_UNDEF_SECTION, /* SEG_DIFFERENCE */ + C_UNDEF_SECTION, /* SEG_EXPR */ C_DEBUG_SECTION, /* SEG_DEBUG */ C_NTV_SECTION, /* SEG_NTV */ C_PTV_SECTION, /* SEG_PTV */ @@ -62,7 +58,7 @@ const segT N_TYPE_seg[32] = }; #endif -char *s_get_name PARAMS ((symbolS * s)); +const char *s_get_name PARAMS ((symbolS * s)); static symbolS *tag_find_or_make PARAMS ((char *name)); static symbolS *tag_find PARAMS ((char *name)); #ifdef BFD_HEADERS @@ -71,29 +67,30 @@ static void obj_coff_section_header_append PARAMS ((char **where, struct interna static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header)); #endif static void obj_coff_def PARAMS ((int what)); -static void obj_coff_dim PARAMS ((void)); -static void obj_coff_endef PARAMS ((void)); -static void obj_coff_line PARAMS ((void)); +static void obj_coff_dim PARAMS ((int)); +static void obj_coff_endef PARAMS ((int)); +static void obj_coff_line PARAMS ((int)); static void obj_coff_ln PARAMS ((int)); -static void obj_coff_scl PARAMS ((void)); -static void obj_coff_size PARAMS ((void)); -static void obj_coff_stab PARAMS ((int what)); -static void obj_coff_tag PARAMS ((void)); -static void obj_coff_type PARAMS ((void)); -static void obj_coff_val PARAMS ((void)); +static void obj_coff_scl PARAMS ((int)); +static void obj_coff_size PARAMS ((int)); +static void obj_coff_tag PARAMS ((int)); +static void obj_coff_type PARAMS ((int)); +static void obj_coff_val PARAMS ((int)); static void tag_init PARAMS ((void)); -static void tag_insert PARAMS ((char *name, symbolS * symbolP)); +static void tag_insert PARAMS ((const char *name, symbolS * symbolP)); #ifdef BFD_ASSEMBLER static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *)); static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *)); #endif -int line_base; - static struct hash_control *tag_hash; static symbolS *def_symbol_in_progress; +static symbolS *dot_text_symbol; +static symbolS *dot_data_symbol; +static symbolS *dot_bss_symbol; + const pseudo_typeS obj_pseudo_table[] = { #ifndef IGNORE_DEBUG @@ -123,16 +120,6 @@ const pseudo_typeS obj_pseudo_table[] = {"ident", s_ignore, 0}, /* we don't yet handle this. */ - - /* stabs aka a.out aka b.out directives for debug symbols. - Currently ignored silently. Except for .line at which - we guess from context. */ - {"desc", s_ignore, 0}, /* def */ - {"stabd", obj_coff_stab, 'd'},/* stabs */ - {"stabn", obj_coff_stab, 'n'},/* stabs */ - {"stabs", obj_coff_stab, 's'},/* stabs */ - - /* stabs-in-coff (?) debug pseudos (ignored) */ {"optim", s_ignore, 0}, /* For sun386i cc (?) */ /* other stuff */ {"ABORT", s_abort, 0}, @@ -207,6 +194,38 @@ SA_SET_SYM_TAGNDX (sym, val) entry->fix_tag = 1; } +static int +S_GET_DATA_TYPE (sym) + symbolS *sym; +{ + return coffsymbol (sym->bsym)->native->u.syment.n_type; +} + +static int +S_SET_DATA_TYPE (sym, val) + symbolS *sym; + int val; +{ + coffsymbol (sym->bsym)->native->u.syment.n_type = val; + return val; +} + +int +S_GET_STORAGE_CLASS (sym) + symbolS *sym; +{ + return coffsymbol (sym->bsym)->native->u.syment.n_sclass; +} + +int +S_SET_STORAGE_CLASS (sym, val) + symbolS *sym; + int val; +{ + coffsymbol (sym->bsym)->native->u.syment.n_sclass = val; + return val; +} + #else /* ! BFD_ASSEMBLER */ /* Relocation. */ @@ -247,7 +266,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file) fixS *p; for (count = 0, p = fixP; p; p = p->fx_next) - if (p->fx_addsy) + if (!p->fx_done) count++; if (!count) return; @@ -268,7 +287,8 @@ obj_emit_relocations (where, fixP, segment_address_in_file) for (i = 0; fixP; fixP = fixP->fx_next) { - if (symbolP = fixP->fx_addsy) + symbolP = fixP->fx_addsy; + if (!fixP->fx_done) { int rtype_ok = 0; #if defined(TC_M68K) @@ -297,7 +317,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file) ri_table[i].r_type = (fixP->fx_pcrel ? R_IPRMED : R_RELLONG); - callj_table[i] = fixP->fx_callj ? 1 : 0; + callj_table[i] = fixP->fx_tcbit ? 1 : 0; rtype_ok = 1; #endif #if defined(TC_A29K) @@ -387,9 +407,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file) #ifdef TC_I960 free (callj_table); #endif - - return; -} /* obj_emit_relocations() */ +} /* Coff file generation & utilities */ @@ -470,9 +488,7 @@ obj_header_append (where, headers) obj_coff_section_header_append (where, &text_section_header); obj_coff_section_header_append (where, &data_section_header); obj_coff_section_header_append (where, &bss_section_header); - - return; -} /* obj_header_append() */ +} #endif /* ! BFD_HEADERS */ @@ -592,8 +608,7 @@ obj_symbol_to_chars (where, symbolP) }; /* for each aux in use */ #endif /* BFD_HEADERS */ - return; -} /* obj_symbol_to_chars() */ +} #ifdef BFD_HEADERS static void @@ -651,9 +666,7 @@ obj_coff_section_header_append (where, header) append (where, (char *) header, sizeof (*header)); #endif /* CROSS_COMPILE */ - - return; -} /* obj_coff_section_header_append() */ +} #endif void @@ -727,7 +740,7 @@ c_symbol_merge (debug, normal) /* Move the debug flags. */ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); -} /* c_symbol_merge() */ +} static symbolS *previous_file_symbol; void @@ -828,8 +841,9 @@ c_section_symbol (name, value, length, nreloc, nlnno) SF_SET_STATICS (symbolP); return (char *) symbolP; -} /* c_section_symbol() */ +} +#ifndef BFD_ASSEMBLER void c_section_header (header, name, @@ -882,19 +896,30 @@ c_section_header (header, ? STYP_BSS : STYP_INFO); } +#endif /* Line number handling */ +int line_base; + #ifdef BFD_ASSEMBLER /* Symbol of last function, which we should hang line#s off of. */ -symbolS *function_lineoff; +static symbolS *line_fsym; + +#define in_function() (line_fsym != 0) +#define clear_function() (line_fsym = 0) +#define set_function(F) (line_fsym = (F), add_linesym (F)) #else /* Offset in line#s where the last function started (the odd entry for line #0). */ -int function_lineoff = -1; +static int function_lineoff = -1; + +#define in_function() (function_lineoff >= 0) +#define clear_function() (function_lineoff = -1) +#define set_function(F) (function_lineoff = c_line_new ((long) (F), 0, &zero_address_frag)) int text_lineno_number; @@ -903,10 +928,9 @@ int text_lineno_number; text_lineno_number by write.c. */ int our_lineno_number; +lineno *lineno_rootP; lineno *lineno_lastP; -#endif -#ifndef BFD_ASSEMBLER int c_line_new (paddr, line_number, frag) long paddr; @@ -927,22 +951,20 @@ c_line_new (paddr, line_number, frag) lineno_lastP = new_line; return LINESZ * our_lineno_number++; } -#endif void obj_emit_lineno (where, line, file_start) char **where; -#ifndef BFD_ASSEMBLER /* sigh */ lineno *line; -#endif char *file_start; { -#ifndef BFD_ASSEMBLER #ifdef BFD_HEADERS struct bfd_internal_lineno *line_entry; #else LINENO *line_entry; #endif + char *where2 = *where; + for (; line; line = line->next) { line_entry = &line->line; @@ -961,38 +983,32 @@ obj_emit_lineno (where, line, file_start) symbolP = (symbolS *) line_entry->l_addr.l_symndx; line_entry->l_addr.l_symndx = symbolP->sy_number; - symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start; - - } /* if this is a function linno */ + symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = where2 - file_start; + } #ifdef BFD_HEADERS - *where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where); + where2 += bfd_coff_swap_lineno_out (stdoutput, line_entry, where2); #else /* No matter which member of the union we process, they are both long. */ -#ifdef CROSS_COMPILE - md_number_to_chars (*where, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr)); - *where += sizeof (line_entry->l_addr.l_paddr); + md_number_to_chars (where2, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr)); + where2 += sizeof (line_entry->l_addr.l_paddr); - md_number_to_chars (*where, line_entry->l_lnno, sizeof (line_entry->l_lnno)); - *where += sizeof (line_entry->l_lnno); + md_number_to_chars (where2, line_entry->l_lnno, sizeof (line_entry->l_lnno)); + where2 += sizeof (line_entry->l_lnno); #ifdef TC_I960 - **where = '0'; - ++*where; - **where = '0'; - ++*where; + *where2++ = '0'; + *where2++ = '0'; #endif /* TC_I960 */ -#else /* CROSS_COMPILE */ - append (where, (char *) line_entry, LINESZ); -#endif /* CROSS_COMPILE */ #endif /* BFD_HEADERS */ - } /* for each line number */ -#else /* BFD_ASSEMBLER */ - abort (); -#endif /* BFD_ASSEMBLER */ + } + *where = where2; } +#endif /* ! BFD_ASSEMBLER */ + + void obj_symbol_new_hook (symbolP) symbolS *symbolP; @@ -1035,6 +1051,7 @@ obj_symbol_new_hook (symbolP) SF_SET_LOCAL (symbolP); } + /* stack stuff */ stack * stack_init (chunk_size, element_size) @@ -1081,7 +1098,7 @@ stack_push (st, element) memcpy (st->data + st->pointer, element, st->element_size); st->pointer += st->element_size; return st->data + st->pointer; -} /* stack_push() */ +} char * stack_pop (st) @@ -1158,11 +1175,14 @@ obj_coff_ln (appline) } l = get_absolute_expression (); + if (!appline) + { #ifdef BFD_ASSEMBLER - add_lineno (frag_now, frag_now_fix (), l); + add_lineno (frag_now, frag_now_fix (), l); #else - c_line_new (frag_now_fix (), l, frag_now); + c_line_new (frag_now_fix (), l, frag_now); #endif + } #ifndef NO_LISTING { @@ -1178,7 +1198,7 @@ obj_coff_ln (appline) #endif demand_empty_rest_of_line (); -} /* obj_coff_ln() */ +} /* * def() @@ -1241,6 +1261,7 @@ obj_coff_def (what) #endif def_symbol_in_progress->sy_frag = &zero_address_frag; + S_SET_VALUE (def_symbol_in_progress, 0); if (S_IS_STRING (def_symbol_in_progress)) SF_SET_STRING (def_symbol_in_progress); @@ -1252,7 +1273,7 @@ obj_coff_def (what) unsigned int dim_index; static void -obj_coff_endef () +obj_coff_endef (ignored) { symbolS *symbolP; /* DIM BUG FIX sac@cygnus.com */ @@ -1300,20 +1321,16 @@ obj_coff_endef () #endif if (name[1] == 'b' && name[2] == 'f') { - if (function_lineoff < 0) + if (! in_function ()) as_warn ("`%s' symbol without preceding function", name); #ifdef BFD_ASSEMBLER - abort (); +/* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/ #else SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff; #endif /* Will need relocating */ SF_SET_PROCESS (def_symbol_in_progress); -#ifdef BFD_ASSEMBLER - function_lineoff = 0; -#else - function_lineoff = -1; -#endif + clear_function (); } } break; @@ -1425,13 +1442,7 @@ obj_coff_endef () if (SF_GET_FUNCTION (def_symbol_in_progress)) { know (sizeof (def_symbol_in_progress) <= sizeof (long)); -#ifdef BFD_ASSEMBLER - function_lineoff = def_symbol_in_progress; - add_linesym (def_symbol_in_progress); -#else - function_lineoff = c_line_new ((long) def_symbol_in_progress, 0, - &zero_address_frag); -#endif + set_function (def_symbol_in_progress); SF_SET_PROCESS (def_symbol_in_progress); if (symbolP == NULL) @@ -1439,18 +1450,17 @@ obj_coff_endef () /* That is, if this is the first time we've seen the function... */ symbol_table_insert (def_symbol_in_progress); - } /* definition follows debug */ - } /* Create the line number entry pointing to the function being defined */ + } /* definition follows debug */ + } /* Create the line number entry pointing to the function being defined */ def_symbol_in_progress = NULL; demand_empty_rest_of_line (); - return; } static void -obj_coff_dim () +obj_coff_dim (ignored) { - register int dim_index; + int dim_index; if (def_symbol_in_progress == NULL) { @@ -1464,11 +1474,11 @@ obj_coff_dim () for (dim_index = 0; dim_index < DIMNUM; dim_index++) { SKIP_WHITESPACES (); - SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ()); + SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, + get_absolute_expression ()); switch (*input_line_pointer) { - case ',': input_line_pointer++; break; @@ -1480,40 +1490,36 @@ obj_coff_dim () case ';': dim_index = DIMNUM; break; - } /* switch on following character */ - } /* for each dimension */ + } + } demand_empty_rest_of_line (); - return; -} /* obj_coff_dim() */ +} static void -obj_coff_line () +obj_coff_line (ignored) { int this_base; if (def_symbol_in_progress == NULL) { + /* Probably stabs-style line? */ obj_coff_ln (0); return; - } /* if it looks like a stabs style line */ + } this_base = get_absolute_expression (); if (this_base > line_base) - { - line_base = this_base; - } - + line_base = this_base; S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); SA_SET_SYM_LNNO (def_symbol_in_progress, line_base); demand_empty_rest_of_line (); - return; -} /* obj_coff_line() */ +} static void -obj_coff_size () +obj_coff_size (ignored) { if (def_symbol_in_progress == NULL) { @@ -1525,11 +1531,10 @@ obj_coff_size () S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); demand_empty_rest_of_line (); - return; -} /* obj_coff_size() */ +} static void -obj_coff_scl () +obj_coff_scl (ignored) { if (def_symbol_in_progress == NULL) { @@ -1540,11 +1545,10 @@ obj_coff_scl () S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ()); demand_empty_rest_of_line (); - return; -} /* obj_coff_scl() */ +} static void -obj_coff_tag () +obj_coff_tag (ignored) { char *symbol_name; char name_end; @@ -1554,16 +1558,16 @@ obj_coff_tag () as_warn (".tag pseudo-op used outside of .def/.endef ignored."); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); symbol_name = input_line_pointer; name_end = get_symbol_end (); - /* Assume that the symbol referred to by .tag is always defined. */ - /* This was a bad assumption. I've added find_or_make. xoxorich. */ + /* Assume that the symbol referred to by .tag is always defined. + This was a bad assumption. I've added find_or_make. xoxorich. */ SA_SET_SYM_TAGNDX (def_symbol_in_progress, - (long) tag_find_or_make (symbol_name)); + tag_find_or_make (symbol_name)); if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) { as_warn ("tag not found for .tag %s", symbol_name); @@ -1573,10 +1577,10 @@ obj_coff_tag () *input_line_pointer = name_end; demand_empty_rest_of_line (); -} /* obj_coff_tag() */ +} static void -obj_coff_type () +obj_coff_type (ignored) { if (def_symbol_in_progress == NULL) { @@ -1594,11 +1598,10 @@ obj_coff_type () } /* is a function */ demand_empty_rest_of_line (); - return; -} /* obj_coff_type() */ +} static void -obj_coff_val () +obj_coff_val (ignored) { if (def_symbol_in_progress == NULL) { @@ -1620,11 +1623,11 @@ obj_coff_val () } else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name)) { + def_symbol_in_progress->sy_value.X_op = O_symbol; def_symbol_in_progress->sy_value.X_add_symbol = symbol_find_or_make (symbol_name); - def_symbol_in_progress->sy_value.X_subtract_symbol = NULL; + def_symbol_in_progress->sy_value.X_op_symbol = NULL; def_symbol_in_progress->sy_value.X_add_number = 0; - def_symbol_in_progress->sy_value.X_seg = undefined_section; /* If the segment is undefined when the forward reference is resolved, then copy the segment id from the forward @@ -1640,8 +1643,7 @@ obj_coff_val () } /* if symbol based */ demand_empty_rest_of_line (); - return; -} /* obj_coff_val() */ +} /* * Maintain a list of the tagnames of the structres. @@ -1651,23 +1653,21 @@ static void tag_init () { tag_hash = hash_new (); - return; -} /* tag_init() */ +} static void tag_insert (name, symbolP) - CONST char *name; + const char *name; symbolS *symbolP; { - register char *error_string; + const char *error_string; - if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP))) + if ((error_string = hash_jam (tag_hash, name, (char *) symbolP))) { as_fatal ("Inserting \"%s\" into structure table failed: %s", name, error_string); } - return; -} /* tag_insert() */ +} static symbolS * tag_find_or_make (name) @@ -1684,8 +1684,8 @@ tag_find_or_make (name) symbol_table_insert (symbolP); } /* not found */ - return (symbolP); -} /* tag_find_or_make() */ + return symbolP; +} static symbolS * tag_find (name) @@ -1695,8 +1695,8 @@ tag_find (name) if (*name == '_') name++; #endif /* STRIP_UNDERSCORE */ - return ((symbolS *) hash_find (tag_hash, name)); -} /* tag_find() */ + return (symbolS *) hash_find (tag_hash, name); +} void obj_read_begin_hook () @@ -1709,6 +1709,7 @@ obj_read_begin_hook () tag_init (); } +#ifndef BFD_ASSEMBLER void obj_crawl_symbol_chain (headers) object_headers *headers; @@ -1742,17 +1743,16 @@ obj_crawl_symbol_chain (headers) { know (!previous_file_symbol); c_dot_file_symbol ("fake"); - } /* Is there a .file symbol ? If not insert one at the beginning. */ + } /* Is there a .file symbol? If not, insert one at the beginning. */ /* * Build up static symbols for .text, .data and .bss */ - dot_text_symbol = (symbolS *) - c_section_symbol (".text", - 0, - H_GET_TEXT_SIZE (headers), - 0 /*text_relocation_number */ , - 0 /*text_lineno_number */ ); + dot_text_symbol = (symbolS *) c_section_symbol (".text", + 0, + H_GET_TEXT_SIZE (headers), + 0 /*text_relocation_number*/, + 0 /*text_lineno_number */); #ifdef TE_I386AIX symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP); symbol_append (dot_text_symbol, previous_file_symbol, @@ -2055,8 +2055,6 @@ obj_crawl_symbol_chain (headers) } /* for each line number */ H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); - - return; } /* @@ -2110,12 +2108,12 @@ obj_pre_write_hook (headers) /* Count the number of relocation entries for text and data */ for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) { - if (fixP->fx_addsy) + if (!fixP->fx_done) { ++text_relocation_number; #ifdef TC_I960 /* two relocs per callj under coff. */ - if (fixP->fx_callj) + if (fixP->fx_tcbit) { ++text_relocation_number; } /* if callj and not already fixed. */ @@ -2127,7 +2125,6 @@ obj_pre_write_hook (headers) ++text_relocation_number; } #endif - } /* if not yet fixed */ } /* for each fix */ @@ -2139,7 +2136,7 @@ obj_pre_write_hook (headers) for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) { - if (fixP->fx_addsy) + if (!fixP->fx_done) { ++data_relocation_number; } /* if still relocatable */ @@ -2150,9 +2147,7 @@ obj_pre_write_hook (headers) ++data_relocation_number; } #endif - - } /* for each fix */ - + } SA_SET_SCN_NRELOC (dot_data_symbol, data_relocation_number); /* Assign the size of the section */ @@ -2193,9 +2188,8 @@ obj_pre_write_hook (headers) /* symbol table size allready set */ H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ); - /* do not added the F_RELFLG for the standard COFF. - * The AIX linker complain on file with relocation info striped flag. - */ + /* Do not added the F_RELFLG for the standard COFF. The AIX linker + complain on file with relocation info striped flag. */ #ifdef KEEP_RELOC_INFO H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0) | BYTE_ORDERING); @@ -2253,89 +2247,7 @@ obj_pre_write_hook (headers) 0, /* No line number information */ section_alignment[(int) SEG_BSS]); } - -/* This is a copy from aout. All I do is neglect to actually build the symbol. */ - -static void -obj_coff_stab (what) - int what; -{ - char *string; - expressionS e; - int goof = 0; /* TRUE if we have aborted. */ - int length; - int saved_type = 0; - long longint; - symbolS *symbolP = 0; - - if (what == 's') - { - string = demand_copy_C_string (&length); - SKIP_WHITESPACE (); - - if (*input_line_pointer == ',') - { - input_line_pointer++; - } - else - { - as_bad ("I need a comma after symbol's name"); - goof = 1; - } /* better be a comma */ - } /* skip the string */ - - /* - * Input_line_pointer->after ','. String->symbol name. - */ - if (!goof) - { - if (get_absolute_expression_and_terminator (&longint) != ',') - { - as_bad ("I want a comma after the n_type expression"); - goof = 1; - input_line_pointer--; /* Backup over a non-',' char. */ - } /* on error */ - } /* no error */ - - if (!goof) - { - if (get_absolute_expression_and_terminator (&longint) != ',') - { - as_bad ("I want a comma after the n_other expression"); - goof = 1; - input_line_pointer--; /* Backup over a non-',' char. */ - } /* on error */ - } /* no error */ - - if (!goof) - { - get_absolute_expression (); - - if (what == 's' || what == 'n') - { - if (*input_line_pointer != ',') - { - as_bad ("I want a comma after the n_desc expression"); - goof = 1; - } - else - { - input_line_pointer++; - } /* on goof */ - } /* not stabd */ - } /* no error */ - - expression (&e); - - if (goof) - { - ignore_rest_of_line (); - } - else - { - demand_empty_rest_of_line (); - } /* on error */ -} /* obj_coff_stab() */ +#endif #ifdef BFD_ASSEMBLER static @@ -2343,26 +2255,26 @@ unsigned long align (val, exp) { int n = (1 << exp) - 1; - printf ("align (%x, %x)\n", val, exp); val = (val + n) & ~n; return val; } void -coff_check_file_symbols (symp, punt) +coff_frob_symbol (symp, punt) symbolS *symp; int *punt; { static symbolS *last_functionP, *last_tagP; static stack *block_stack; + if (current_lineno_sym) + add_linesym ((symbolS *) 0); + if (!block_stack) block_stack = stack_init (512, sizeof (symbolS*)); -#if 1 if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT) S_SET_STORAGE_CLASS (symp, C_EXT); -#endif if (!SF_GET_DEBUG (symp)) { @@ -2435,7 +2347,9 @@ coff_check_file_symbols (symp, punt) S_SET_VALUE (symp, 0); } } - if (SF_GET_LOCAL (symp)) + if (S_IS_EXTERNAL (symp)) + S_SET_STORAGE_CLASS (symp, C_EXT); + else if (SF_GET_LOCAL (symp)) *punt = 1; /* more ... */ } @@ -2492,7 +2406,6 @@ DEFUN_VOID(obj_coff_section) exp = 0; } - printf ("change_to_section(`%s',%d,%x)\n", section_name, len,exp); *section_name_end = c; } @@ -2505,14 +2418,12 @@ coff_frob_file () assert (previous_file_symbol == 0); c_dot_file_symbol ("fake"); } - if (current_lineno_sym) - add_linesym ((symbolS *) 0); } #endif /* BFD_ASSEMBLER */ #ifdef DEBUG /* for debugging */ -CONST char * +const char * s_get_name (s) symbolS *s; { diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index b648bb2d02e..6e1577fe962 100644 --- a/gas/config/obj-coffbfd.c +++ b/gas/config/obj-coffbfd.c @@ -332,9 +332,7 @@ DEFUN (count_entries_in_chain, (idx), { if (TC_COUNT_RELOC (fixup_ptr)) { - #ifdef TC_A29K - if (fixup_ptr->fx_r_type == RELOC_CONSTH) nrelocs += 2; else @@ -2419,9 +2417,8 @@ DEFUN (fixup_segment, (segP, this_segment_type), #ifdef TC_I960 if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP)) { - /* Relocation should be done via the - associated 'bal' entry point - symbol. */ + /* Relocation should be done via the associated 'bal' entry + point symbol. */ if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP))) { @@ -2430,7 +2427,7 @@ DEFUN (fixup_segment, (segP, this_segment_type), continue; } fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP); - } /* callj relocation */ + } #endif sub_symbolP = fixP->fx_subsy; add_number = fixP->fx_offset; @@ -2461,9 +2458,9 @@ DEFUN (fixup_segment, (segP, this_segment_type), && (SEG_NORMAL (add_symbol_segment) || (add_symbol_segment == SEG_ABSOLUTE))) { - /* Difference of 2 symbols from same segment. */ - /* Can't make difference of 2 undefineds: 'value' means */ - /* something different for N_UNDF. */ + /* Difference of 2 symbols from same segment. Can't + make difference of 2 undefineds: 'value' means + something different for N_UNDF. */ #ifdef TC_I960 /* Makes no sense to use the difference of 2 arbitrary symbols as the target of a call instruction. */ @@ -2477,6 +2474,7 @@ DEFUN (fixup_segment, (segP, this_segment_type), add_symbolP = NULL; fixP->fx_addsy = NULL; + fixP->fx_done = 1; } else { @@ -2536,7 +2534,8 @@ DEFUN (fixup_segment, (segP, this_segment_type), add_number -= segP->scnhdr.s_vaddr; #endif pcrel = 0; /* Lie. Don't want further pcrel processing. */ - fixP->fx_addsy = NULL; /* No relocations please. */ + fixP->fx_addsy = NULL; + fixP->fx_done = 1; } else { @@ -2548,6 +2547,7 @@ DEFUN (fixup_segment, (segP, this_segment_type), #endif /* TC_I960 */ add_number += S_GET_VALUE (add_symbolP); fixP->fx_addsy = NULL; + fixP->fx_done = 1; add_symbolP = NULL; break; default: @@ -2572,7 +2572,8 @@ DEFUN (fixup_segment, (segP, this_segment_type), * relocation. */ as_bad ("can't use COBR format with external label"); - fixP->fx_addsy = NULL; /* No relocations please. */ + fixP->fx_addsy = NULL; + fixP->fx_done = 1; continue; } /* COBR */ #endif /* TC_I960 */ diff --git a/gas/config/obj-ecoff.h b/gas/config/obj-ecoff.h index e472a61fb9a..2ea5d34aef4 100644 --- a/gas/config/obj-ecoff.h +++ b/gas/config/obj-ecoff.h @@ -53,3 +53,5 @@ extern void ecoff_frob_file PARAMS ((void)); /* At the moment we don't want to do any stabs processing in read.c. */ #define OBJ_PROCESS_STAB(what, string, type, other, desc) \ ecoff_stab ((what), (string), (type), (other), (desc)) + +#define EMIT_SECTION_SYMBOLS 0 diff --git a/gas/write.c b/gas/write.c index 4ec756d64ad..6733e3e860a 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1,5 +1,5 @@ /* write.c - emit .o file - Copyright (C) 1986, 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1986, 87, 90, 91, 92, 93, 1994 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -126,6 +126,7 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel, fixP->fx_addnumber = 0; fixP->tc_fix_data = NULL; fixP->fx_tcbit = 0; + fixP->fx_done = 0; #ifdef TC_something fixP->fx_bsr = 0; @@ -354,12 +355,10 @@ cvt_frag_to_fill (headers, fragP) HANDLE_ALIGN (fragP); #endif fragP->fr_type = rs_fill; - know (fragP->fr_var == 1); know (fragP->fr_next != NULL); - fragP->fr_offset = (fragP->fr_next->fr_address - fragP->fr_address - - fragP->fr_fix); + - fragP->fr_fix) / fragP->fr_var; break; case rs_fill: @@ -506,6 +505,10 @@ dump_section_relocs (abfd, sec, stream_) #define dump_section_relocs(ABFD,SEC,STREAM) (void)(ABFD,SEC,STREAM) #endif +#ifndef EMIT_SECTION_SYMBOLS +#define EMIT_SECTION_SYMBOLS 1 +#endif + static void adjust_reloc_syms (abfd, sec, xxx) bfd *abfd; @@ -521,11 +524,12 @@ adjust_reloc_syms (abfd, sec, xxx) dump_section_relocs (abfd, sec, stderr); for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) - if (fixp->fx_addsy) + if (fixp->fx_done) + /* ignore it */; + else if (fixp->fx_addsy) { symbolS *sym = fixp->fx_addsy; asection *symsec = sym->bsym->section; - segment_info_type *symseginfo = seg_info (symsec); /* If it's one of these sections, assume the symbol is definitely going to be output. The code in @@ -542,7 +546,7 @@ adjust_reloc_syms (abfd, sec, xxx) /* Since we're reducing to section symbols, don't attempt to reduce anything that's already using one. */ - if (sym->bsym == symsec->symbol) + if (sym->bsym->flags & BSF_SECTION_SYM) { fixp->fx_addsy->sy_used_in_reloc = 1; continue; @@ -588,8 +592,7 @@ adjust_reloc_syms (abfd, sec, xxx) static symbolS *abs_sym; if (!abs_sym) { - abs_sym = symbol_new ("*absolute0zero*", &bfd_abs_section, 0, - &zero_address_frag); + abs_sym = section_symbol (absolute_section); abs_sym->sy_used_in_reloc = 1; } fixp->fx_addsy = abs_sym; @@ -610,6 +613,7 @@ write_relocs (abfd, sec, xxx) unsigned int n; arelent **relocs; fixS *fixp; + char *err; /* If seginfo is NULL, we did not create this section; don't do anything with it. */ @@ -635,10 +639,8 @@ write_relocs (abfd, sec, xxx) char *data; bfd_reloc_status_type s; - if (fixp->fx_addsy == 0) + if (fixp->fx_done) { - /* @@ Need some other flag to indicate which have already - been performed... */ n--; continue; } @@ -665,7 +667,7 @@ write_relocs (abfd, sec, xxx) we want it to operate. We can't just do it by fudging reloc->address, since that might be used in the calculations(?). */ s = bfd_perform_relocation (stdoutput, reloc, data - reloc->address, - sec, stdoutput); + sec, stdoutput, &err); switch (s) { case bfd_reloc_ok: @@ -689,10 +691,8 @@ write_relocs (abfd, sec, xxx) bfd_reloc_status_type s; int j; - if (fixp->fx_addsy == 0) + if (fixp->fx_done) { - /* @@ Need some other flag to indicate which have already - been performed... */ n--; continue; } @@ -709,15 +709,15 @@ write_relocs (abfd, sec, xxx) abort (); for (j = 0; reloc[j]; j++) { - s = bfd_perform_relocation (stdoutput, reloc[j], + s = bfd_perform_relocation (stdoutput, reloc[j], data - reloc[0]->address, - sec, stdoutput); + sec, stdoutput, &err); switch (s) { - case bfd_reloc_ok: - break; - default: - as_fatal ("bad return from bfd_perform_relocation"); + case bfd_reloc_ok: + break; + default: + as_fatal ("bad return from bfd_perform_relocation"); } } } @@ -730,7 +730,8 @@ write_relocs (abfd, sec, xxx) bfd_set_section_flags (abfd, sec, (bfd_get_section_flags (abfd, sec) & (flagword) ~SEC_RELOC)); -#ifdef DEBUG2 + +#ifdef DEBUG3 { int i; arelent *r; @@ -1345,7 +1346,7 @@ write_object_file () int punt = 0; obj_frob_symbol (symp, punt); if (punt) - goto punt_it; + goto punt_it_if_unused; } #endif #ifdef tc_frob_symbol @@ -1353,18 +1354,25 @@ write_object_file () int punt = 0; tc_frob_symbol (symp, punt); if (punt) - goto punt_it; + goto punt_it_if_unused; } #endif + if (! EMIT_SECTION_SYMBOLS + && (symp->bsym->flags & BSF_SECTION_SYM)) + goto punt_it; + /* If we don't want to keep this symbol, splice it out of the chain now. */ if (S_IS_LOCAL (symp)) { - punt_it: +#if defined (obj_frob_symbol) || defined (tc_frob_symbol) + punt_it_if_unused: +#endif if (! symp->sy_used_in_reloc) { symbolS *prev, *next; + punt_it: prev = symbol_previous (symp); next = symbol_next (symp); #ifdef DEBUG_SYMS @@ -1427,7 +1435,6 @@ write_object_file () } } - #ifdef obj_frob_file /* If obj_frob_file changes the symbol value at this point, it is responsible for moving the changed value into symp->bsym->value @@ -1521,7 +1528,16 @@ relax_segment (segment_frag_root, segment) break; case rs_align: - address += relax_align (address, (int) fragP->fr_offset); + { + int offset = relax_align (address, (int) fragP->fr_offset); + if (offset % fragP->fr_var != 0) + { + as_bad ("alignment padding (%d bytes) not a multiple of %d", + offset, fragP->fr_var); + offset -= (offset % fragP->fr_var); + } + address += offset; + } break; case rs_org: @@ -1903,7 +1919,9 @@ fixup_segment (fixP, this_segment_type) as to whether or not a relocation will be needed to handle this fixup. */ if (!TC_FORCE_RELOCATION (fixP)) - fixP->fx_addsy = NULL; + { + fixP->fx_addsy = NULL; + } } else { @@ -1931,6 +1949,13 @@ fixup_segment (fixP, this_segment_type) sub_symbolP = 0; fixP->fx_subsy = 0; } +#endif +#ifdef BFD_ASSEMBLER + else if (fixP->fx_r_type == BFD_RELOC_GPREL32 + || fixP->fx_r_type == BFD_RELOC_GPREL16) + { + /* Leave it alone. */ + } #endif else { @@ -1969,7 +1994,10 @@ fixup_segment (fixP, this_segment_type) as to whether or not a relocation will be needed to handle this fixup. */ if (!TC_FORCE_RELOCATION (fixP)) - fixP->fx_addsy = NULL; + { + fixP->fx_pcrel = 0; + fixP->fx_addsy = NULL; + } } else { @@ -2005,12 +2033,8 @@ fixup_segment (fixP, this_segment_type) * relocation. */ as_bad ("can't use COBR format with external label"); - - /* Let the target machine make the final determination - as to whether or not a relocation will be needed to - handle this fixup. */ - if (!TC_FORCE_RELOCATION (fixP)) - fixP->fx_addsy = NULL; + fixP->fx_addsy = NULL; + fixP->fx_done = 1; continue; } /* COBR */ #endif /* TC_I960 */ @@ -2038,18 +2062,19 @@ fixup_segment (fixP, this_segment_type) { fixP->fx_addsy = &abs_symbol; ++seg_reloc_count; - } /* if there's an add_symbol */ - } /* if pcrel */ + } + } if (!fixP->fx_bit_fixP && size > 0) { valueT mask = 0; /* set all bits to one */ mask--; - /* Technically speaking, combining these produces an - undefined result if size is sizeof (valueT), though I - think these two half-way operations should both be - defined. */ + /* Technically, combining these produces an undefined result + if size is sizeof (valueT), though I think these two + half-way operations should both be defined. And the + compiler should be able to combine them if it's valid on + the host architecture. */ mask <<= size * 4; mask <<= size * 4; if ((add_number & mask) != 0 @@ -2079,12 +2104,25 @@ fixup_segment (fixP, this_segment_type) #endif } /* not a bit fix */ + if (!fixP->fx_done) + { #ifdef BFD_ASSEMBLER - md_apply_fix (fixP, &add_number); + md_apply_fix (fixP, &add_number); #else - md_apply_fix (fixP, add_number); + md_apply_fix (fixP, add_number); +#endif + +#ifndef TC_HANDLES_FX_DONE + /* If the tc-* files haven't been converted, assume it's handling + it the old way, where a null fx_addsy means that the fix has + been applied completely, and no further work is needed. */ + if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0) + fixP->fx_done = 1; #endif + } +#ifdef TC_VALIDATE_FIX skip: +#endif ; } /* For each fixS in this segment. */ -- 2.30.2