diff options
Diffstat (limited to 'gas/config')
54 files changed, 3110 insertions, 1853 deletions
diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c index d586e3a..fbf0ffb 100644 --- a/gas/config/atof-ieee.c +++ b/gas/config/atof-ieee.c @@ -460,7 +460,7 @@ gen_to_words (words, precision, exponent_bits) /* Bigger than one littlenum */ num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; *lp++ = word1; - if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS) + if (num_bits + exponent_bits + 1 > precision * LITTLENUM_NUMBER_OF_BITS) { /* Exponent overflow */ make_invalid_floating_point_number (words); @@ -501,7 +501,7 @@ gen_to_words (words, precision, exponent_bits) if (next_bits (1)) { --lp; - if (prec_bits > LITTLENUM_NUMBER_OF_BITS) + if (prec_bits >= LITTLENUM_NUMBER_OF_BITS) { int n = 0; int tmp_bits; @@ -515,7 +515,19 @@ gen_to_words (words, precision, exponent_bits) --n; tmp_bits -= LITTLENUM_NUMBER_OF_BITS; } - if (tmp_bits > LITTLENUM_NUMBER_OF_BITS || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]) + if (tmp_bits > LITTLENUM_NUMBER_OF_BITS + || (lp[n] & mask[tmp_bits]) != mask[tmp_bits] + || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS + - exponent_bits - 1) +#ifdef TC_I386 + /* An extended precision float with only the integer + bit set would be invalid. That must be converted + to the smallest normalized number. */ + && !(precision == X_PRECISION + && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS + - exponent_bits - 2)) +#endif + )) { unsigned long carry; @@ -539,11 +551,18 @@ gen_to_words (words, precision, exponent_bits) << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits)); *lp++ = word1; +#ifdef TC_I386 + /* Set the integer bit in the extended precision format. + This cannot happen on the m68k where the mantissa + just overflows into the integer bit above. */ + if (precision == X_PRECISION) + *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1); +#endif while (lp < words_end) *lp++ = 0; } } - else if ((*lp & mask[prec_bits]) != mask[prec_bits]) + else *lp += 1; } diff --git a/gas/config/m68k-parse.h b/gas/config/m68k-parse.h index e131342..cdb5f60 100644 --- a/gas/config/m68k-parse.h +++ b/gas/config/m68k-parse.h @@ -1,5 +1,6 @@ /* m68k-parse.h -- header file for m68k assembler - Copyright (C) 1987, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1987, 91, 92, 93, 94, 95, 96, 1999 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -83,6 +84,9 @@ enum m68k_register ZPC, /* Hack for Program space, but 0 addressing */ SR, /* Status Reg */ CCR, /* Condition code Reg */ + ACC, /* Accumulator Reg */ + MACSR, /* MAC Status Reg */ + MASK, /* Modulus Reg */ /* These have to be grouped together for the movec instruction to work. */ USP, /* User Stack Pointer */ @@ -165,6 +169,44 @@ enum m68k_register ZADDR5, ZADDR6, ZADDR7, + + /* Upper and lower half of data and address registers. Order *must* + be DATAxL, ADDRxL, DATAxU, ADDRxU. */ + DATA0L, /* lower half of data registers */ + DATA1L, + DATA2L, + DATA3L, + DATA4L, + DATA5L, + DATA6L, + DATA7L, + + ADDR0L, /* lower half of address registers */ + ADDR1L, + ADDR2L, + ADDR3L, + ADDR4L, + ADDR5L, + ADDR6L, + ADDR7L, + + DATA0U, /* upper half of data registers */ + DATA1U, + DATA2U, + DATA3U, + DATA4U, + DATA5U, + DATA6U, + DATA7U, + + ADDR0U, /* upper half of address registers */ + ADDR1U, + ADDR2U, + ADDR3U, + ADDR4U, + ADDR5U, + ADDR6U, + ADDR7U, }; /* Size information. */ diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c index b519347..4b4f4d8 100644 --- a/gas/config/obj-aout.c +++ b/gas/config/obj-aout.c @@ -1,5 +1,5 @@ /* a.out object file format - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -14,9 +14,10 @@ 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. */ +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. */ #include "as.h" #ifdef BFD_ASSEMBLER @@ -108,18 +109,21 @@ obj_aout_frob_symbol (sym, punt) asection *sec; int desc, type, other; - flags = sym->bsym->flags; + flags = symbol_get_bfdsym (sym)->flags; desc = S_GET_DESC (sym); type = S_GET_TYPE (sym); other = S_GET_OTHER (sym); - sec = sym->bsym->section; + sec = S_GET_SEGMENT (sym); /* Only frob simple symbols this way right now. */ if (! (type & ~ (N_TYPE | N_EXT))) { if (type == (N_UNDF | N_EXT) && sec == &bfd_abs_section) - sym->bsym->section = sec = bfd_und_section_ptr; + { + sec = bfd_und_section_ptr; + S_SET_SEGMENT (sym, sec); + } if ((type & N_TYPE) != N_INDR && (type & N_TYPE) != N_SETA @@ -141,7 +145,7 @@ obj_aout_frob_symbol (sym, punt) case N_SETB: /* Set the debugging flag for constructor symbols so that BFD leaves them alone. */ - sym->bsym->flags |= BSF_DEBUGGING; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; /* You can't put a common symbol in a set. The way a set element works is that the symbol has a definition and a @@ -164,29 +168,29 @@ obj_aout_frob_symbol (sym, punt) break; case N_INDR: /* Put indirect symbols in the indirect section. */ - sym->bsym->section = bfd_ind_section_ptr; - sym->bsym->flags |= BSF_INDIRECT; + S_SET_SEGMENT (sym, bfd_ind_section_ptr); + symbol_get_bfdsym (sym)->flags |= BSF_INDIRECT; if (type & N_EXT) { - sym->bsym->flags |= BSF_EXPORT; - sym->bsym->flags &=~ BSF_LOCAL; + symbol_get_bfdsym (sym)->flags |= BSF_EXPORT; + symbol_get_bfdsym (sym)->flags &=~ BSF_LOCAL; } break; case N_WARNING: /* Mark warning symbols. */ - sym->bsym->flags |= BSF_WARNING; + symbol_get_bfdsym (sym)->flags |= BSF_WARNING; break; } } else { - sym->bsym->flags |= BSF_DEBUGGING; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; } S_SET_TYPE (sym, type); /* Double check weak symbols. */ - if (sym->bsym->flags & BSF_WEAK) + if (S_IS_WEAK (sym)) { if (S_IS_COMMON (sym)) as_bad (_("Symbol `%s' can not be both weak and common"), @@ -215,7 +219,7 @@ obj_aout_frob_file () assert (x == true); } -#else +#else /* ! BFD_ASSEMBLER */ /* Relocation. */ @@ -291,7 +295,7 @@ obj_header_append (where, headers) #endif /* CROSS_COMPILE */ } -#endif +#endif /* ! defined (obj_header_append) */ void obj_symbol_to_chars (where, symbolP) @@ -508,7 +512,7 @@ obj_crawl_symbol_chain (headers) } else /* .Stabd case. */ symbolP->sy_name_offset = 0; - symbolPP = &(symbol_next (symbolP)); + symbolPP = &symbolP->sy_next; } else { diff --git a/gas/config/obj-aout.h b/gas/config/obj-aout.h index 339070e..2cf33fd 100644 --- a/gas/config/obj-aout.h +++ b/gas/config/obj-aout.h @@ -1,5 +1,5 @@ /* obj-aout.h, a.out object file format for gas, the assembler. - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1998 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -60,18 +60,24 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #ifdef BFD_ASSEMBLER -#define S_SET_OTHER(S,V) (aout_symbol((S)->bsym)->other = (V)) -#define S_SET_TYPE(S,T) (aout_symbol((S)->bsym)->type = (T)) -#define S_SET_DESC(S,D) (aout_symbol((S)->bsym)->desc = (D)) -#define S_GET_OTHER(S) (aout_symbol((S)->bsym)->other) -#define S_GET_TYPE(S) (aout_symbol((S)->bsym)->type) -#define S_GET_DESC(S) (aout_symbol((S)->bsym)->desc) +#define S_SET_OTHER(S,V) \ + (aout_symbol (symbol_get_bfdsym (S))->other = (V)) +#define S_SET_TYPE(S,T) \ + (aout_symbol (symbol_get_bfdsym (S))->type = (T)) +#define S_SET_DESC(S,D) \ + (aout_symbol (symbol_get_bfdsym (S))->desc = (D)) +#define S_GET_OTHER(S) \ + (aout_symbol (symbol_get_bfdsym (S))->other) +#define S_GET_TYPE(S) \ + (aout_symbol (symbol_get_bfdsym (S))->type) +#define S_GET_DESC(S) \ + (aout_symbol (symbol_get_bfdsym (S))->desc) asection *text_section, *data_section, *bss_section; #define obj_frob_symbol(S,PUNT) obj_aout_frob_symbol (S, &PUNT) #define obj_frob_file() obj_aout_frob_file () -extern void obj_aout_frob_symbol PARAMS ((struct symbol *, int *)); +extern void obj_aout_frob_symbol PARAMS ((symbolS *, int *)); extern void obj_aout_frob_file PARAMS ((void)); #define obj_sec_sym_ok_for_reloc(SEC) (1) diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c index c9b80f5..dc79718 100644 --- a/gas/config/obj-bout.c +++ b/gas/config/obj-bout.c @@ -14,9 +14,10 @@ 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. */ + 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. */ #include "as.h" #include "obstack.h" diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 5639fbe..781d23d 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1,5 +1,5 @@ /* coff object file format - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS. @@ -249,8 +249,8 @@ SA_SET_SYM_ENDNDX (sym, val) { combined_entry_type *entry, *p; - entry = &coffsymbol (sym->bsym)->native[1]; - p = coffsymbol (val->bsym)->native; + 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; } @@ -262,8 +262,8 @@ SA_SET_SYM_TAGNDX (sym, val) { combined_entry_type *entry, *p; - entry = &coffsymbol (sym->bsym)->native[1]; - p = coffsymbol (val->bsym)->native; + 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; } @@ -272,7 +272,7 @@ static int S_GET_DATA_TYPE (sym) symbolS *sym; { - return coffsymbol (sym->bsym)->native->u.syment.n_type; + return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type; } int @@ -280,7 +280,7 @@ S_SET_DATA_TYPE (sym, val) symbolS *sym; int val; { - coffsymbol (sym->bsym)->native->u.syment.n_type = val; + coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val; return val; } @@ -288,7 +288,7 @@ int S_GET_STORAGE_CLASS (sym) symbolS *sym; { - return coffsymbol (sym->bsym)->native->u.syment.n_sclass; + return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass; } int @@ -296,7 +296,7 @@ S_SET_STORAGE_CLASS (sym, val) symbolS *sym; int val; { - coffsymbol (sym->bsym)->native->u.syment.n_sclass = val; + coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val; return val; } @@ -339,7 +339,7 @@ c_dot_file_symbol (filename) S_SET_STORAGE_CLASS (symbolP, C_FILE); S_SET_NUMBER_AUXILIARY (symbolP, 1); - symbolP->bsym->flags = BSF_DEBUGGING; + symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING; #ifndef NO_LISTING { @@ -385,7 +385,7 @@ coff_obj_symbol_new_hook (symbolP) char * s = (char *) xmalloc (sz); memset (s, 0, sz); - coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s; + coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s; S_SET_DATA_TYPE (symbolP, T_NULL); S_SET_STORAGE_CLASS (symbolP, 0); @@ -434,7 +434,8 @@ coff_add_linesym (sym) { if (line_nos) { - coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos; + coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno = + (alent *) line_nos; coff_n_line_nos++; line_nos = 0; } @@ -532,7 +533,7 @@ obj_coff_def (what) /* Initialize the new symbol */ def_symbol_in_progress = symbol_make (symbol_name_copy); - def_symbol_in_progress->sy_frag = &zero_address_frag; + symbol_set_frag (def_symbol_in_progress, &zero_address_frag); S_SET_VALUE (def_symbol_in_progress, 0); if (S_IS_STRING (def_symbol_in_progress)) @@ -585,7 +586,7 @@ obj_coff_endef (ignore) CONST char *name; S_SET_SEGMENT (def_symbol_in_progress, text_section); - name = bfd_asymbol_name (def_symbol_in_progress->bsym); + name = S_GET_NAME (def_symbol_in_progress); if (name[1] == 'b' && name[2] == 'f') { if (! in_function ()) @@ -909,17 +910,19 @@ obj_coff_val (ignore) #endif if (!strcmp (symbol_name, ".")) { - def_symbol_in_progress->sy_frag = frag_now; + symbol_set_frag (def_symbol_in_progress, frag_now); S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ()); /* If the .val is != from the .def (e.g. statics) */ } 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_op_symbol = NULL; - def_symbol_in_progress->sy_value.X_add_number = 0; + expressionS exp; + + exp.X_op = O_symbol; + exp.X_add_symbol = symbol_find_or_make (symbol_name); + exp.X_op_symbol = NULL; + exp.X_add_number = 0; + symbol_set_value_expression (def_symbol_in_progress, &exp); /* If the segment is undefined when the forward reference is resolved, then copy the segment id from the forward @@ -1034,7 +1037,8 @@ coff_frob_symbol (symp, punt) coff_last_function = symp; if (S_GET_NUMBER_AUXILIARY (symp) < 1) S_SET_NUMBER_AUXILIARY (symp, 1); - auxp = &coffsymbol (symp->bsym)->native[1].u.auxent; + auxp = + &coffsymbol (symbol_get_bfdsym (symp))->native[1].u.auxent; memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0, sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen)); } @@ -1055,7 +1059,7 @@ coff_frob_symbol (symp, punt) *punt = 1; if (SF_GET_FUNCTION (symp)) - symp->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION; /* more ... */ } @@ -1068,17 +1072,17 @@ coff_frob_symbol (symp, punt) #ifdef OBJ_XCOFF /* This is pretty horrible, but we have to set *punt correctly in order to call SA_SET_SYM_ENDNDX correctly. */ - if (! symp->sy_used_in_reloc - && ((symp->bsym->flags & BSF_SECTION_SYM) != 0 + if (! symbol_used_in_reloc_p (symp) + && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0 || (! S_IS_EXTERNAL (symp) - && ! symp->sy_tc.output + && ! symbol_get_tc (symp)->output && S_GET_STORAGE_CLASS (symp) != C_FILE))) *punt = 1; #endif if (set_end != (symbolS *) NULL && ! *punt - && ((symp->bsym->flags & BSF_NOT_AT_END) != 0 + && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0 || (S_IS_DEFINED (symp) && ! S_IS_COMMON (symp) && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp))))) @@ -1100,22 +1104,22 @@ coff_frob_symbol (symp, punt) coff_last_bf = symp; } - if (coffsymbol (symp->bsym)->lineno) + if (coffsymbol (symbol_get_bfdsym (symp))->lineno) { int i; struct line_no *lptr; alent *l; - lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; + lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno; for (i = 0; lptr; lptr = lptr->next) i++; - lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; + lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno; /* We need i entries for line numbers, plus 1 for the first entry which BFD will override, plus 1 for the last zero entry (a marker for BFD). */ l = (alent *) xmalloc ((i + 2) * sizeof (alent)); - coffsymbol (symp->bsym)->lineno = l; + coffsymbol (symbol_get_bfdsym (symp))->lineno = l; l[i + 1].line_number = 0; l[i + 1].u.sym = NULL; for (; i > 0; i--) @@ -1243,7 +1247,7 @@ obj_coff_section (ignore) case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break; case 'n': flags &=~ SEC_LOAD; break; case 'd': - case 'w': flags &=~ SEC_READONLY; break; + case 'w': flags |= SEC_DATA; flags &=~ SEC_READONLY; break; case 'x': flags |= SEC_CODE; break; case 'r': flags |= SEC_READONLY; break; @@ -3231,6 +3235,7 @@ write_object_file () at the next frag. */ subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg); + #ifndef SUB_SEGMENT_ALIGN #define SUB_SEGMENT_ALIGN(SEG) 1 #endif @@ -3238,7 +3243,9 @@ write_object_file () md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0, alignment_done); #endif - frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0); + frag_align (SUB_SEGMENT_ALIGN (now_seg), + subseg_text_p (now_seg) ? NOP_OPCODE : 0, + 0); #ifdef md_do_align alignment_done: #endif @@ -4258,6 +4265,12 @@ fixup_segment (segP, this_segment_type) #endif } /* if pcrel */ +#ifdef MD_APPLY_FIX3 + md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type); +#else + md_apply_fix (fixP, add_number); +#endif + if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow) { #ifndef TC_M88K @@ -4294,13 +4307,6 @@ fixup_segment (segP, this_segment_type) (unsigned long) (fragP->fr_address + where)); #endif } /* not a bit fix */ - /* Once this fix has been applied, we don't have to output - anything nothing more need be done. */ -#ifdef MD_APPLY_FIX3 - md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type); -#else - md_apply_fix (fixP, add_number); -#endif } /* For each fixS in this segment. */ } /* fixup_segment() */ diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index 4650477..a8799a3 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -154,7 +154,7 @@ #define OBJ_COFF_MAX_AUXENTRIES 1 #endif /* OBJ_COFF_MAX_AUXENTRIES */ -extern void coff_obj_symbol_new_hook PARAMS ((struct symbol *)); +extern void coff_obj_symbol_new_hook PARAMS ((symbolS *)); #define obj_symbol_new_hook coff_obj_symbol_new_hook extern void coff_obj_read_begin_hook PARAMS ((void)); @@ -211,32 +211,35 @@ extern void coff_obj_read_begin_hook PARAMS ((void)); /* Alter the field names, for now, until we've fixed up the other references to use the new name. */ #ifdef TC_I960 -#define TC_SYMFIELD_TYPE struct symbol * +#define TC_SYMFIELD_TYPE symbolS * #define sy_tc bal #endif #define OBJ_SYMFIELD_TYPE unsigned long #define sy_obj sy_flags -#define SYM_AUXENT(S) (&coffsymbol ((S)->bsym)->native[1].u.auxent) -#define SYM_AUXINFO(S) (&coffsymbol ((S)->bsym)->native[1]) +#define SYM_AUXENT(S) \ + (&coffsymbol (symbol_get_bfdsym (S))->native[1].u.auxent) +#define SYM_AUXINFO(S) \ + (&coffsymbol (symbol_get_bfdsym (S))->native[1]) #define DO_NOT_STRIP 0 extern void obj_coff_section PARAMS ((int)); /* The number of auxiliary entries */ -#define S_GET_NUMBER_AUXILIARY(s) (coffsymbol((s)->bsym)->native->u.syment.n_numaux) +#define S_GET_NUMBER_AUXILIARY(s) \ + (coffsymbol (symbol_get_bfdsym (s))->native->u.syment.n_numaux) /* The number of auxiliary entries */ #define S_SET_NUMBER_AUXILIARY(s,v) (S_GET_NUMBER_AUXILIARY (s) = (v)) /* True if a symbol name is in the string table, i.e. its length is > 8. */ #define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0) -extern int S_SET_DATA_TYPE PARAMS ((struct symbol *, int)); -extern int S_SET_STORAGE_CLASS PARAMS ((struct symbol *, int)); -extern int S_GET_STORAGE_CLASS PARAMS ((struct symbol *)); -extern void SA_SET_SYM_ENDNDX PARAMS ((struct symbol *, struct symbol *)); +extern int S_SET_DATA_TYPE PARAMS ((symbolS *, int)); +extern int S_SET_STORAGE_CLASS PARAMS ((symbolS *, int)); +extern int S_GET_STORAGE_CLASS PARAMS ((symbolS *)); +extern void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *)); /* Auxiliary entry macros. SA_ stands for symbol auxiliary */ /* Omit the tv related fields */ @@ -298,9 +301,9 @@ extern void SA_SET_SYM_ENDNDX PARAMS ((struct symbol *, struct symbol *)); /* All other bits are unused. */ /* Accessors */ -#define SF_GET(s) ((s)->sy_flags) -#define SF_GET_DEBUG(s) ((s)->bsym->flags & BSF_DEBUGGING) -#define SF_SET_DEBUG(s) ((s)->bsym->flags |= BSF_DEBUGGING) +#define SF_GET(s) (*symbol_get_obj (s)) +#define SF_GET_DEBUG(s) (symbol_get_bfdsym (s)->flags & BSF_DEBUGGING) +#define SF_SET_DEBUG(s) (symbol_get_bfdsym (s)->flags |= BSF_DEBUGGING) #define SF_GET_NORMAL_FIELD(s) (SF_GET (s) & SF_NORMAL_MASK) #define SF_GET_DEBUG_FIELD(s) (SF_GET (s) & SF_DEBUG_MASK) #define SF_GET_FILE(s) (SF_GET (s) & SF_FILE) @@ -346,13 +349,13 @@ extern int coff_line_base; extern int coff_n_line_nos; #define obj_emit_lineno(WHERE,LINE,FILE_START) abort () -extern void coff_add_linesym PARAMS ((struct symbol *)); +extern void coff_add_linesym PARAMS ((symbolS *)); void c_dot_file_symbol PARAMS ((char *filename)); #define obj_app_file c_dot_file_symbol -extern void coff_frob_symbol PARAMS ((struct symbol *, int *)); +extern void coff_frob_symbol PARAMS ((symbolS *, int *)); extern void coff_adjust_symtab PARAMS ((void)); extern void coff_frob_section PARAMS ((segT)); extern void coff_adjust_section_syms PARAMS ((bfd *, asection *, PTR)); @@ -364,7 +367,7 @@ extern void coff_frob_file_after_relocs PARAMS ((void)); #define obj_frob_section(S) coff_frob_section (S) #define obj_frob_file_after_relocs() coff_frob_file_after_relocs () -extern struct symbol *coff_last_function; +extern symbolS *coff_last_function; /* Forward the segment of a forwarded symbol, handle assignments that just copy symbol values, etc. */ @@ -778,7 +781,7 @@ extern void c_dot_file_symbol PARAMS ((char *filename)); #define obj_app_file c_dot_file_symbol extern void obj_extra_stuff PARAMS ((object_headers * headers)); -extern segT s_get_segment PARAMS ((struct symbol * ptr)); +extern segT s_get_segment PARAMS ((symbolS *ptr)); extern void c_section_header PARAMS ((struct internal_scnhdr * header, char *name, @@ -792,7 +795,7 @@ extern void c_section_header PARAMS ((struct internal_scnhdr * header, long alignment)); #ifndef tc_coff_symbol_emit_hook -void tc_coff_symbol_emit_hook PARAMS ((struct symbol *)); +void tc_coff_symbol_emit_hook PARAMS ((symbolS *)); #endif /* sanity check */ diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c index ec3ce88..6489243 100644 --- a/gas/config/obj-ecoff.c +++ b/gas/config/obj-ecoff.c @@ -1,5 +1,5 @@ /* ECOFF object file format. - Copyright (C) 1993, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Contributed by Cygnus Support. This file was put together by Ian Lance Taylor <ian@cygnus.com>. @@ -260,8 +260,9 @@ obj_ecoff_set_ext (sym, ext) = &ecoff_backend (stdoutput)->debug_swap; ecoff_symbol_type *esym; - know (bfd_asymbol_flavour (sym->bsym) == bfd_target_ecoff_flavour); - esym = ecoffsymbol (sym->bsym); + know (bfd_asymbol_flavour (symbol_get_bfdsym (sym)) + == bfd_target_ecoff_flavour); + esym = ecoffsymbol (symbol_get_bfdsym (sym)); esym->local = false; esym->native = xmalloc (debug_swap->external_ext_size); (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native); diff --git a/gas/config/obj-ecoff.h b/gas/config/obj-ecoff.h index 427e619..8bca254 100644 --- a/gas/config/obj-ecoff.h +++ b/gas/config/obj-ecoff.h @@ -36,10 +36,14 @@ symbols is undefined (this last is needed to distinguish a .extern symbols from a .comm symbol). */ -#define TARGET_SYMBOL_FIELDS \ - struct efdr *ecoff_file; \ - struct localsym *ecoff_symbol; \ +struct ecoff_sy_obj +{ + struct efdr *ecoff_file; + struct localsym *ecoff_symbol; valueT ecoff_extern_size; +}; + +#define OBJ_SYMFIELD_TYPE struct ecoff_sy_obj /* Modify the ECOFF symbol. */ #define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp) @@ -64,4 +68,4 @@ extern void ecoff_frob_file PARAMS ((void)); #define obj_sec_sym_ok_for_reloc(SEC) 1 #define obj_ecoff_set_ext ecoff_set_ext -extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *)); +extern void obj_ecoff_set_ext PARAMS ((symbolS *, EXTR *)); diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index f50c4b7..6feb5c5 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -1,5 +1,5 @@ /* ELF object file format - Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -65,17 +65,16 @@ static void obj_elf_type PARAMS ((int)); static void obj_elf_ident PARAMS ((int)); static void obj_elf_weak PARAMS ((int)); static void obj_elf_local PARAMS ((int)); -static void obj_elf_common PARAMS ((int)); static void obj_elf_symver PARAMS ((int)); static void obj_elf_vtable_inherit PARAMS ((int)); static void obj_elf_vtable_entry PARAMS ((int)); -static void obj_elf_data PARAMS ((int)); -static void obj_elf_text PARAMS ((int)); static void obj_elf_subsection PARAMS ((int)); +static void obj_elf_popsection PARAMS ((int)); static const pseudo_typeS elf_pseudo_table[] = { {"comm", obj_elf_common, 0}, + {"common", obj_elf_common, 1}, {"ident", obj_elf_ident, 0}, {"local", obj_elf_local, 0}, {"previous", obj_elf_previous, 0}, @@ -83,6 +82,8 @@ static const pseudo_typeS elf_pseudo_table[] = {"section.s", obj_elf_section, 0}, {"sect", obj_elf_section, 0}, {"sect.s", obj_elf_section, 0}, + {"pushsection", obj_elf_section, 1}, + {"popsection", obj_elf_popsection, 0}, {"size", obj_elf_size, 0}, {"type", obj_elf_type, 0}, {"version", obj_elf_version, 0}, @@ -111,7 +112,7 @@ static const pseudo_typeS elf_pseudo_table[] = {"text", obj_elf_text, 0}, /* End sentinel. */ - {NULL}, + {NULL, NULL, 0}, }; static const pseudo_typeS ecoff_debug_pseudo_table[] = @@ -156,7 +157,7 @@ static const pseudo_typeS ecoff_debug_pseudo_table[] = { "vreg", s_ignore, 0 }, #endif - {NULL} /* end sentinel */ + {NULL, NULL, 0} /* end sentinel */ }; #undef NO_RELOC @@ -235,8 +236,8 @@ elf_file_symbol (s) symbolS *sym; sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0); - sym->sy_frag = &zero_address_frag; - sym->bsym->flags |= BSF_FILE; + symbol_set_frag (sym, &zero_address_frag); + symbol_get_bfdsym (sym)->flags |= BSF_FILE; if (symbol_rootP != sym) { @@ -252,9 +253,9 @@ elf_file_symbol (s) #endif } -static void -obj_elf_common (ignore) - int ignore; +void +obj_elf_common (is_common) + int is_common; { char *name; char c; @@ -263,6 +264,12 @@ obj_elf_common (ignore) symbolS *symbolP; int have_align; + if (flag_mri && is_common) + { + s_mri_common (0); + return; + } + name = input_line_pointer; c = get_symbol_end (); /* just after name is now '\0' */ @@ -294,7 +301,7 @@ obj_elf_common (ignore) } if (S_GET_VALUE (symbolP) != 0) { - if (S_GET_VALUE (symbolP) != size) + if (S_GET_VALUE (symbolP) != (valueT) size) { as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."), S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size); @@ -322,7 +329,7 @@ obj_elf_common (ignore) as_warn (_("Common alignment negative; 0 assumed")); } } - if (symbolP->local) + if (symbol_get_obj (symbolP)->local) { segT old_sec; int old_subsec; @@ -350,8 +357,8 @@ obj_elf_common (ignore) if (align) frag_align (align, 0, 0); if (S_GET_SEGMENT (symbolP) == bss_section) - symbolP->sy_frag->fr_symbol = 0; - symbolP->sy_frag = frag_now; + symbol_get_frag (symbolP)->fr_symbol = 0; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) size, (char *) 0); *pfrag = 0; @@ -389,7 +396,7 @@ obj_elf_common (ignore) goto allocate_common; } - symbolP->bsym->flags |= BSF_OBJECT; + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; demand_empty_rest_of_line (); return; @@ -411,7 +418,7 @@ obj_elf_common (ignore) static void obj_elf_local (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name; int c; @@ -425,7 +432,7 @@ obj_elf_local (ignore) *input_line_pointer = c; SKIP_WHITESPACE (); S_CLEAR_EXTERNAL (symbolP); - symbolP->local = 1; + symbol_get_obj (symbolP)->local = 1; if (c == ',') { input_line_pointer++; @@ -440,7 +447,7 @@ obj_elf_local (ignore) static void obj_elf_weak (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name; int c; @@ -454,7 +461,7 @@ obj_elf_weak (ignore) *input_line_pointer = c; SKIP_WHITESPACE (); S_SET_WEAK (symbolP); - symbolP->local = 1; + symbol_get_obj (symbolP)->local = 1; if (c == ',') { input_line_pointer++; @@ -470,6 +477,16 @@ obj_elf_weak (ignore) static segT previous_section; static int previous_subsection; +struct section_stack +{ + struct section_stack *next; + segT seg, prev_seg; + int subseg, prev_subseg; +}; + +static struct section_stack *section_stack; + + /* Handle the .section pseudo-op. This code supports two different syntaxes. @@ -497,7 +514,7 @@ struct special_section int attributes; }; -static struct special_section special_sections[] = +static struct special_section const special_sections[] = { { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, { ".comment", SHT_PROGBITS, 0 }, @@ -536,25 +553,197 @@ static struct special_section special_sections[] = }; void -obj_elf_section (xxx) - int xxx; +obj_elf_change_section (name, type, attr, push) + char *name; + int type, attr, push; { - char *string; int new_sec; segT sec; - int type, attr; - int i; - flagword flags; - symbolS *secsym; #ifdef md_flush_pending_output md_flush_pending_output (); #endif + /* Switch to the section, creating it if necessary. */ + if (push) + { + struct section_stack *elt; + elt = xmalloc (sizeof (struct section_stack)); + elt->next = section_stack; + elt->seg = now_seg; + elt->prev_seg = previous_section; + elt->subseg = now_subseg; + elt->prev_subseg = previous_subsection; + section_stack = elt; + } + previous_section = now_seg; + previous_subsection = now_subseg; + + new_sec = bfd_get_section_by_name (stdoutput, name) == NULL; + sec = subseg_new (name, 0); + + if (new_sec) + { + flagword flags; + symbolS *secsym; + int i; + + /* See if this is one of the special sections. */ + for (i = 0; special_sections[i].name != NULL; i++) + if (strcmp (name, special_sections[i].name) == 0) + { + if (type == SHT_NULL) + type = special_sections[i].type; + else if (type != special_sections[i].type) + as_warn (_("Setting incorrect section type for %s"), name); + + if ((attr &~ special_sections[i].attributes) != 0) + { + /* As a GNU extension, we permit a .note section to be + allocatable. If the linker sees an allocateable .note + section, it will create a PT_NOTE segment in the output + file. */ + if (strcmp (name, ".note") != 0 + || attr != SHF_ALLOC) + as_warn (_("Setting incorrect section attributes for %s"), + name); + } + attr |= special_sections[i].attributes; + break; + } + + /* Convert ELF type and flags to BFD flags. */ + flags = (SEC_RELOC + | ((attr & SHF_WRITE) ? 0 : SEC_READONLY) + | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0) + | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0) + | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)); +#ifdef md_elf_section_flags + flags = md_elf_section_flags (flags, attr, type); +#endif + + /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ + if (type == SHT_NOBITS) + seg_info (sec)->bss = 1; + + bfd_set_section_flags (stdoutput, sec, flags); + + /* Add a symbol for this section to the symbol table. */ + secsym = symbol_find (name); + if (secsym != NULL) + symbol_set_bfdsym (secsym, sec->symbol); + else + symbol_table_insert (section_symbol (sec)); + } + +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif +} + +int +obj_elf_parse_section_letters (str, len) + char *str; + size_t len; +{ + int attr = 0; + + while (len > 0) + { + switch (*str) + { + case 'a': + attr |= SHF_ALLOC; + break; + case 'w': + attr |= SHF_WRITE; + break; + case 'x': + attr |= SHF_EXECINSTR; + break; + default: + { + char *bad_msg = _("Unrecognized .section attribute: want a,w,x"); +#ifdef md_elf_section_letter + int md_attr = md_elf_section_letter (*str, &bad_msg); + if (md_attr >= 0) + attr |= md_attr; + else +#endif + { + as_warn (bad_msg); + attr = -1; + } + } + break; + } + str++, len--; + } + + return attr; +} + +int +obj_elf_section_word (str, len) + char *str; + size_t len; +{ + if (len == 5 && strncmp (str, "write", 5) == 0) + return SHF_WRITE; + if (len == 5 && strncmp (str, "alloc", 5) == 0) + return SHF_ALLOC; + if (len == 9 && strncmp (str, "execinstr", 9) == 0) + return SHF_EXECINSTR; + +#ifdef md_elf_section_word + { + int md_attr = md_elf_section_word (str, len); + if (md_attr >= 0) + return md_attr; + } +#endif + + as_warn (_("Unrecognized section attribute")); + return 0; +} + +int +obj_elf_section_type (str, len) + char *str; + size_t len; +{ + if (len == 8 && strncmp (str, "progbits", 8) == 0) + return SHT_PROGBITS; + if (len == 6 && strncmp (str, "nobits", 6) == 0) + return SHT_NOBITS; + +#ifdef md_elf_section_type + { + int md_type = md_elf_section_type (str, len); + if (md_type >= 0) + return md_type; + } +#endif + + as_warn (_("Unrecognized section type")); + return 0; +} + +void +obj_elf_section (push) + int push; +{ + char *name, *beg, *end; + int type, attr, dummy; + if (flag_mri) { char mri_type; +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + previous_section = now_seg; previous_subsection = now_subseg; @@ -571,8 +760,8 @@ obj_elf_section (xxx) SKIP_WHITESPACE (); if (*input_line_pointer == '"') { - string = demand_copy_C_string (&xxx); - if (string == NULL) + name = demand_copy_C_string (&dummy); + if (name == NULL) { ignore_rest_of_line (); return; @@ -580,46 +769,21 @@ obj_elf_section (xxx) } else { - char *p = input_line_pointer; - char c; - while (0 == strchr ("\n\t,; ", *p)) - p++; - if (p == input_line_pointer) + end = input_line_pointer; + while (0 == strchr ("\n\t,; ", *end)) + end++; + if (end == input_line_pointer) { as_warn (_("Missing section name")); ignore_rest_of_line (); return; } - c = *p; - *p = 0; - string = xmalloc ((unsigned long) (p - input_line_pointer + 1)); - strcpy (string, input_line_pointer); - *p = c; - input_line_pointer = p; - } - - /* Switch to the section, creating it if necessary. */ - previous_section = now_seg; - previous_subsection = now_subseg; - - new_sec = bfd_get_section_by_name (stdoutput, string) == NULL; - sec = subseg_new (string, 0); - - /* If this section already existed, we don't bother to change the - flag values. */ - if (! new_sec) - { - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - ++input_line_pointer; - ++input_line_pointer; - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif - - return; + + name = xmalloc (end - input_line_pointer + 1); + memcpy (name, input_line_pointer, end - input_line_pointer); + name[end - input_line_pointer] = '\0'; + input_line_pointer = end; } - SKIP_WHITESPACE (); type = SHT_NULL; @@ -629,81 +793,41 @@ obj_elf_section (xxx) { /* Skip the comma. */ ++input_line_pointer; - SKIP_WHITESPACE (); if (*input_line_pointer == '"') { - /* Pick up a string with a combination of a, w, x. */ - ++input_line_pointer; - while (*input_line_pointer != '"') + beg = demand_copy_C_string (&dummy); + if (beg == NULL) { - switch (*input_line_pointer) - { - case 'a': - attr |= SHF_ALLOC; - break; - case 'w': - attr |= SHF_WRITE; - break; - case 'x': - attr |= SHF_EXECINSTR; - break; - default: - { - char *bad_msg = _("Bad .section directive: want a,w,x in string"); -#ifdef md_elf_section_letter - int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg); - if (md_attr) - attr |= md_attr; - else -#endif - { - as_warn (bad_msg); - ignore_rest_of_line (); - return; - } - } - } - ++input_line_pointer; + ignore_rest_of_line (); + return; } - - /* Skip the closing quote. */ - ++input_line_pointer; + attr |= obj_elf_parse_section_letters (beg, strlen (beg)); SKIP_WHITESPACE (); if (*input_line_pointer == ',') { + char c; ++input_line_pointer; SKIP_WHITESPACE (); - if (*input_line_pointer == '@' || *input_line_pointer == '%') + c = *input_line_pointer; + if (c == '"') { - ++input_line_pointer; - if (strncmp (input_line_pointer, "progbits", - sizeof "progbits" - 1) == 0) - { - type = SHT_PROGBITS; - input_line_pointer += sizeof "progbits" - 1; - } - else if (strncmp (input_line_pointer, "nobits", - sizeof "nobits" - 1) == 0) + beg = demand_copy_C_string (&dummy); + if (beg == NULL) { - type = SHT_NOBITS; - input_line_pointer += sizeof "nobits" - 1; - } - else - { -#ifdef md_elf_section_type - int md_type = md_elf_section_type (&input_line_pointer); - if (md_type) - type = md_type; - else -#endif - { - as_warn (_("Unrecognized section type")); - ignore_rest_of_line (); - } + ignore_rest_of_line (); + return; } + type = obj_elf_section_type (beg, strlen (beg)); + } + else if (c == '@' || c == '%') + { + beg = ++input_line_pointer; + c = get_symbol_end (); + *input_line_pointer = c; + type = obj_elf_section_type (beg, input_line_pointer - beg); } } } @@ -711,6 +835,8 @@ obj_elf_section (xxx) { do { + char c; + SKIP_WHITESPACE (); if (*input_line_pointer != '#') { @@ -718,39 +844,12 @@ obj_elf_section (xxx) ignore_rest_of_line (); return; } - ++input_line_pointer; - if (strncmp (input_line_pointer, "write", - sizeof "write" - 1) == 0) - { - attr |= SHF_WRITE; - input_line_pointer += sizeof "write" - 1; - } - else if (strncmp (input_line_pointer, "alloc", - sizeof "alloc" - 1) == 0) - { - attr |= SHF_ALLOC; - input_line_pointer += sizeof "alloc" - 1; - } - else if (strncmp (input_line_pointer, "execinstr", - sizeof "execinstr" - 1) == 0) - { - attr |= SHF_EXECINSTR; - input_line_pointer += sizeof "execinstr" - 1; - } - else - { -#ifdef md_elf_section_word - int md_attr = md_elf_section_word (&input_line_pointer); - if (md_attr) - attr |= md_attr; - else -#endif - { - as_warn (_("Unrecognized section attribute")); - ignore_rest_of_line (); - return; - } - } + beg = ++input_line_pointer; + c = get_symbol_end (); + *input_line_pointer = c; + + attr |= obj_elf_section_word (beg, input_line_pointer - beg); + SKIP_WHITESPACE (); } while (*input_line_pointer++ == ','); @@ -758,77 +857,14 @@ obj_elf_section (xxx) } } - /* See if this is one of the special sections. */ - for (i = 0; special_sections[i].name != NULL; i++) - { - if (string[1] == special_sections[i].name[1] - && strcmp (string, special_sections[i].name) == 0) - { - if (type == SHT_NULL) - type = special_sections[i].type; - else if (type != special_sections[i].type) - as_warn (_("Setting incorrect section type for %s"), string); - - if ((attr &~ special_sections[i].attributes) != 0) - { - /* As a GNU extension, we permit a .note section to be - allocatable. If the linker sees an allocateable - .note section, it will create a PT_NOTE segment in - the output file. */ - if (strcmp (string, ".note") != 0 - || attr != SHF_ALLOC) - as_warn (_("Setting incorrect section attributes for %s"), - string); - } - attr |= special_sections[i].attributes; - - break; - } - } - - flags = (SEC_RELOC - | ((attr & SHF_WRITE) ? 0 : SEC_READONLY) - | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0) - | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0) - | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)); - if (special_sections[i].name == NULL) - { - if (type == SHT_PROGBITS) - flags |= SEC_ALLOC | SEC_LOAD; - else if (type == SHT_NOBITS) - { - flags |= SEC_ALLOC; - flags &=~ SEC_LOAD; - } - -#ifdef md_elf_section_flags - flags = md_elf_section_flags (flags, attr, type); -#endif - } - - /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ - if (type == SHT_NOBITS) - seg_info (sec)->bss = 1; - - bfd_set_section_flags (stdoutput, sec, flags); - - /* Add a symbol for this section to the symbol table. */ - secsym = symbol_find (string); - if (secsym != NULL) - secsym->bsym = sec->symbol; - else - symbol_table_insert (section_symbol (sec)); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif - demand_empty_rest_of_line (); + + obj_elf_change_section (name, type, attr, push); } /* Change to the .data section. */ -static void +void obj_elf_data (i) int i; { @@ -847,7 +883,7 @@ obj_elf_data (i) /* Change to the .text section. */ -static void +void obj_elf_text (i) int i; { @@ -866,7 +902,7 @@ obj_elf_text (i) static void obj_elf_subsection (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register int temp; @@ -898,8 +934,11 @@ obj_elf_section_change_hook () void obj_elf_previous (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { + segT new_section; + int new_subsection; + if (previous_section == 0) { as_bad (_(".previous without corresponding .section; ignored")); @@ -910,8 +949,38 @@ obj_elf_previous (ignore) md_flush_pending_output (); #endif - subseg_set (previous_section, previous_subsection); - previous_section = 0; + new_section = previous_section; + new_subsection = previous_subsection; + previous_section = now_seg; + previous_subsection = now_subseg; + subseg_set (new_section, new_subsection); + +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif +} + +static void +obj_elf_popsection (xxx) + int xxx ATTRIBUTE_UNUSED; +{ + struct section_stack *top = section_stack; + + if (top == NULL) + { + as_bad (_(".popsection without corresponding .pushsection; ignored")); + return; + } + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + section_stack = top->next; + previous_section = top->prev_seg; + previous_subsection = top->prev_subseg; + subseg_set (top->seg, top->subseg); + free (top); #ifdef md_elf_section_change_hook md_elf_section_change_hook (); @@ -920,7 +989,7 @@ obj_elf_previous (ignore) static void obj_elf_line (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { /* Assume delimiter is part of expression. BSD4.2 as fails with delightful bug, so we are not being incompatible here. */ @@ -936,7 +1005,7 @@ obj_elf_line (ignore) static void obj_elf_symver (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name; char c; @@ -949,7 +1018,7 @@ obj_elf_symver (ignore) *input_line_pointer = c; - if (sym->sy_obj.versioned_name != NULL) + if (symbol_get_obj (sym)->versioned_name != NULL) { as_bad (_("multiple .symver directives for symbol `%s'"), S_GET_NAME (sym)); @@ -975,14 +1044,14 @@ obj_elf_symver (ignore) *input_line_pointer++ = c; } - sym->sy_obj.versioned_name = xstrdup (name); + symbol_get_obj (sym)->versioned_name = xstrdup (name); *input_line_pointer = c; - if (strchr (sym->sy_obj.versioned_name, ELF_VER_CHR) == NULL) + if (strchr (symbol_get_obj (sym)->versioned_name, ELF_VER_CHR) == NULL) { as_bad (_("missing version name in `%s' for symbol `%s'"), - sym->sy_obj.versioned_name, S_GET_NAME (sym)); + symbol_get_obj (sym)->versioned_name, S_GET_NAME (sym)); ignore_rest_of_line (); return; } @@ -996,6 +1065,7 @@ obj_elf_symver (ignore) static void obj_elf_vtable_inherit (ignore) + int ignore ATTRIBUTE_UNUSED; { char *cname, *pname; symbolS *csym, *psym; @@ -1012,7 +1082,7 @@ obj_elf_vtable_inherit (ignore) the same child symbol. Also, we can currently only do this if the child symbol is already exists and is placed in a fragment. */ - if (csym == NULL || csym->sy_frag == NULL) + if (csym == NULL || symbol_get_frag (csym) == NULL) { as_bad ("expected `%s' to have already been set for .vtable_inherit", cname); @@ -1037,7 +1107,7 @@ obj_elf_vtable_inherit (ignore) if (input_line_pointer[0] == '0' && (input_line_pointer[1] == '\0' - || isspace(input_line_pointer[1]))) + || isspace ((unsigned char) input_line_pointer[1]))) { psym = section_symbol (absolute_section); ++input_line_pointer; @@ -1055,8 +1125,9 @@ obj_elf_vtable_inherit (ignore) if (bad) return; - assert (csym->sy_value.X_op == O_constant); - fix_new (csym->sy_frag, csym->sy_value.X_add_number, 0, psym, 0, 0, + assert (symbol_get_value_expression (csym)->X_op == O_constant); + fix_new (symbol_get_frag (csym), + symbol_get_value_expression (csym)->X_add_number, 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT); } @@ -1066,6 +1137,7 @@ obj_elf_vtable_inherit (ignore) static void obj_elf_vtable_entry (ignore) + int ignore ATTRIBUTE_UNUSED; { char *name; symbolS *sym; @@ -1113,8 +1185,11 @@ void obj_symbol_new_hook (symbolP) symbolS *symbolP; { - symbolP->sy_obj.size = NULL; - symbolP->sy_obj.versioned_name = NULL; + struct elf_obj_sy *sy_obj; + + sy_obj = symbol_get_obj (symbolP); + sy_obj->size = NULL; + sy_obj->versioned_name = NULL; #ifdef NEED_ECOFF_DEBUG if (ECOFF_DEBUGGING) @@ -1124,7 +1199,7 @@ obj_symbol_new_hook (symbolP) void obj_elf_version (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name; unsigned int c; @@ -1191,7 +1266,7 @@ obj_elf_version (ignore) static void obj_elf_size (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name = input_line_pointer; char c = get_symbol_end (); @@ -1225,8 +1300,9 @@ obj_elf_size (ignore) S_SET_SIZE (sym, exp.X_add_number); else { - sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS)); - *sym->sy_obj.size = exp; + symbol_get_obj (sym)->size = + (expressionS *) xmalloc (sizeof (expressionS)); + *symbol_get_obj (sym)->size = exp; } demand_empty_rest_of_line (); } @@ -1246,7 +1322,7 @@ obj_elf_size (ignore) static void obj_elf_type (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name; char c; @@ -1284,14 +1360,14 @@ obj_elf_type (ignore) *input_line_pointer = c; - sym->bsym->flags |= type; + symbol_get_bfdsym (sym)->flags |= type; demand_empty_rest_of_line (); } static void obj_elf_ident (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { static segT comment_section; segT old_section = now_seg; @@ -1351,7 +1427,7 @@ static void adjust_stab_sections (abfd, sec, xxx) bfd *abfd; asection *sec; - PTR xxx; + PTR xxx ATTRIBUTE_UNUSED; { char *name; asection *strsec; @@ -1393,7 +1469,7 @@ elf_ecoff_set_ext (sym, ext) symbolS *sym; struct ecoff_extr *ext; { - sym->bsym->udata.p = (PTR) ext; + symbol_get_bfdsym (sym)->udata.p = (PTR) ext; } /* This function is called by bfd_ecoff_debug_externals. It is @@ -1429,35 +1505,39 @@ elf_frob_symbol (symp, puntp) symbolS *symp; int *puntp; { + struct elf_obj_sy *sy_obj; + #ifdef NEED_ECOFF_DEBUG if (ECOFF_DEBUGGING) ecoff_frob_symbol (symp); #endif - if (symp->sy_obj.size != NULL) + sy_obj = symbol_get_obj (symp); + + if (sy_obj->size != NULL) { - switch (symp->sy_obj.size->X_op) + switch (sy_obj->size->X_op) { case O_subtract: S_SET_SIZE (symp, - (S_GET_VALUE (symp->sy_obj.size->X_add_symbol) - + symp->sy_obj.size->X_add_number - - S_GET_VALUE (symp->sy_obj.size->X_op_symbol))); + (S_GET_VALUE (sy_obj->size->X_add_symbol) + + sy_obj->size->X_add_number + - S_GET_VALUE (sy_obj->size->X_op_symbol))); break; case O_constant: S_SET_SIZE (symp, - (S_GET_VALUE (symp->sy_obj.size->X_add_symbol) - + symp->sy_obj.size->X_add_number)); + (S_GET_VALUE (sy_obj->size->X_add_symbol) + + sy_obj->size->X_add_number)); break; default: as_bad (_(".size expression too complicated to fix up")); break; } - free (symp->sy_obj.size); - symp->sy_obj.size = NULL; + free (sy_obj->size); + sy_obj->size = NULL; } - if (symp->sy_obj.versioned_name != NULL) + if (sy_obj->versioned_name != NULL) { /* This symbol was given a new name with the .symver directive. @@ -1477,15 +1557,15 @@ elf_frob_symbol (symp, puntp) /* Verify that the name isn't using the @@ syntax--this is reserved for definitions of the default version to link against. */ - p = strchr (symp->sy_obj.versioned_name, ELF_VER_CHR); + p = strchr (sy_obj->versioned_name, ELF_VER_CHR); know (p != NULL); if (p[1] == ELF_VER_CHR) { as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"), - symp->sy_obj.versioned_name); + sy_obj->versioned_name); *puntp = true; } - S_SET_NAME (symp, symp->sy_obj.versioned_name); + S_SET_NAME (symp, sy_obj->versioned_name); } else { @@ -1497,7 +1577,7 @@ elf_frob_symbol (symp, puntp) where the loop will still see it. It would probably be better to do this in obj_frob_file_before_adjust. */ - symp2 = symbol_find_or_make (symp->sy_obj.versioned_name); + symp2 = symbol_find_or_make (sy_obj->versioned_name); /* Now we act as though we saw symp2 = sym. */ @@ -1505,9 +1585,11 @@ elf_frob_symbol (symp, puntp) /* Subtracting out the frag address here is a hack because we are in the middle of the final loop. */ - S_SET_VALUE (symp2, S_GET_VALUE (symp) - symp->sy_frag->fr_address); + S_SET_VALUE (symp2, + (S_GET_VALUE (symp) + - symbol_get_frag (symp)->fr_address)); - symp2->sy_frag = symp->sy_frag; + symbol_set_frag (symp2, symbol_get_frag (symp)); /* This will copy over the size information. */ copy_symbol_attributes (symp2, symp); @@ -1521,7 +1603,7 @@ elf_frob_symbol (symp, puntp) } /* Double check weak symbols. */ - if (symp->bsym->flags & BSF_WEAK) + if (S_IS_WEAK (symp)) { if (S_IS_COMMON (symp)) as_bad (_("Symbol `%s' can not be both weak and common"), @@ -1537,19 +1619,21 @@ elf_frob_symbol (symp, puntp) .global directives to mark functions. */ if (S_IS_COMMON (symp)) - symp->bsym->flags |= BSF_OBJECT; + symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; if (strstr (TARGET_OS, "irix") != NULL - && (! S_IS_DEFINED (symp) && ((symp->bsym->flags & BSF_FUNCTION) == 0))) - symp->bsym->flags |= BSF_OBJECT; + && ! S_IS_DEFINED (symp) + && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0) + symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; #endif #ifdef TC_PPC /* Frob the PowerPC, so that the symbol always has object type if it is not some other type. VxWorks needs this. */ - if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0 + if ((symbol_get_bfdsym (symp)->flags + & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0 && S_IS_DEFINED (symp)) - symp->bsym->flags |= BSF_OBJECT; + symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; #endif } diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index 2f4bc5f..d39998e 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -1,5 +1,6 @@ /* ELF object file format. - Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. + Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -34,6 +35,22 @@ #define BYTES_IN_WORD 4 /* for now */ #include "bfd/elf-bfd.h" +#include "targ-cpu.h" + +#ifdef TC_ALPHA +#define ECOFF_DEBUGGING alpha_flag_mdebug +extern int alpha_flag_mdebug; +#endif + +/* For now, always set ECOFF_DEBUGGING for a MIPS target. */ +#ifdef TC_MIPS +#ifdef MIPS_STABS_ELF +#define ECOFF_DEBUGGING 0 +#else +#define ECOFF_DEBUGGING 1 +#endif /* MIPS_STABS_ELF */ +#endif /* TC_MIPS */ + /* Additional information we keep for each symbol. */ /* FIXME: For some reason, this structure is needed both here and in @@ -41,25 +58,28 @@ #ifndef OBJ_SYMFIELD_TYPE struct elf_obj_sy { + /* Whether the symbol has been marked as local. */ + int local; + /* Use this to keep track of .size expressions that involve differences that we can't compute yet. */ expressionS *size; /* The name specified by the .symver directive. */ char *versioned_name; + +#ifdef ECOFF_DEBUGGING + /* If we are generating ECOFF debugging information, we need some + additional fields for each symbol. */ + struct efdr *ecoff_file; + struct localsym *ecoff_symbol; + valueT ecoff_extern_size; +#endif }; #endif #define OBJ_SYMFIELD_TYPE struct elf_obj_sy -/* Symbol fields used by the ELF back end. */ -#define ELF_TARGET_SYMBOL_FIELDS int local:1; - -/* Don't change this; change ELF_TARGET_SYMBOL_FIELDS instead. */ -#define TARGET_SYMBOL_FIELDS ELF_TARGET_SYMBOL_FIELDS - -#include "targ-cpu.h" - #ifndef FALSE #define FALSE 0 #define TRUE !FALSE @@ -71,17 +91,20 @@ extern void elf_begin PARAMS ((void)); /* should be conditional on address size! */ #define elf_symbol(asymbol) ((elf_symbol_type *)(&(asymbol)->the_bfd)) -#define S_GET_SIZE(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_size) +#define S_GET_SIZE(S) \ + (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size) #define S_SET_SIZE(S,V) \ - (elf_symbol((S)->bsym)->internal_elf_sym.st_size = (V)) + (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size = (V)) -#define S_GET_ALIGN(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_value) +#define S_GET_ALIGN(S) \ + (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value) #define S_SET_ALIGN(S,V) \ - (elf_symbol ((S)->bsym)->internal_elf_sym.st_value = (V)) + (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value = (V)) -#define S_GET_OTHER(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_other) +#define S_GET_OTHER(S) \ + (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_other) #define S_SET_OTHER(S,V) \ - (elf_symbol ((S)->bsym)->internal_elf_sym.st_other = (V)) + (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_other = (V)) extern asection *gdb_section; @@ -99,6 +122,9 @@ extern void obj_elf_section_change_hook PARAMS ((void)); extern void obj_elf_section PARAMS ((int)); extern void obj_elf_previous PARAMS ((int)); extern void obj_elf_version PARAMS ((int)); +extern void obj_elf_common PARAMS ((int)); +extern void obj_elf_data PARAMS ((int)); +extern void obj_elf_text PARAMS ((int)); /* BFD wants to write the udata field, which is a no-no for the globally defined sections. */ @@ -110,18 +136,20 @@ extern void obj_elf_version PARAMS ((int)); #define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST,SRC) \ do \ { \ - if ((SRC)->sy_obj.size) \ + struct elf_obj_sy *srcelf = symbol_get_obj (SRC); \ + struct elf_obj_sy *destelf = symbol_get_obj (DEST); \ + if (srcelf->size) \ { \ - if ((DEST)->sy_obj.size == NULL) \ - (DEST)->sy_obj.size = \ + if (destelf->size == NULL) \ + destelf->size = \ (expressionS *) xmalloc (sizeof (expressionS)); \ - *(DEST)->sy_obj.size = *(SRC)->sy_obj.size; \ + *destelf->size = *srcelf->size; \ } \ else \ { \ - if ((DEST)->sy_obj.size != NULL) \ - free ((DEST)->sy_obj.size); \ - (DEST)->sy_obj.size = NULL; \ + if (destelf->size != NULL) \ + free (destelf->size); \ + destelf->size = NULL; \ } \ S_SET_SIZE ((DEST), S_GET_SIZE (SRC)); \ S_SET_OTHER ((DEST), S_GET_OTHER (SRC)); \ @@ -136,30 +164,7 @@ while (0) extern void obj_elf_init_stab_section PARAMS ((segT)); #define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg) -#ifdef TC_ALPHA -#define ECOFF_DEBUGGING alpha_flag_mdebug -extern int alpha_flag_mdebug; -#endif - -/* For now, always set ECOFF_DEBUGGING for a MIPS target. */ -#ifdef TC_MIPS -#ifdef MIPS_STABS_ELF -#define ECOFF_DEBUGGING 0 -#else -#define ECOFF_DEBUGGING 1 -#endif /* MIPS_STABS_ELF */ -#endif /* TC_MIPS */ - #ifdef ECOFF_DEBUGGING -/* If we are generating ECOFF debugging information, we need some - additional fields for each symbol. */ -#undef TARGET_SYMBOL_FIELDS -#define TARGET_SYMBOL_FIELDS \ - ELF_TARGET_SYMBOL_FIELDS \ - struct efdr *ecoff_file; \ - struct localsym *ecoff_symbol; \ - valueT ecoff_extern_size; - /* We smuggle stabs in ECOFF rather than using a separate section. The Irix linker can not handle a separate stabs section. */ @@ -175,7 +180,7 @@ extern int alpha_flag_mdebug; ecoff_stab ((seg), (what), (string), (type), (other), (desc)) #endif /* ECOFF_DEBUGGING */ -extern void elf_frob_symbol PARAMS ((struct symbol *, int *)); +extern void elf_frob_symbol PARAMS ((symbolS *, int *)); #ifndef obj_frob_symbol #define obj_frob_symbol(symp, punt) elf_frob_symbol (symp, &punt) #endif @@ -188,7 +193,7 @@ extern void elf_pop_insert PARAMS ((void)); #ifdef ANSI_PROTOTYPES struct ecoff_extr; #endif -extern void elf_ecoff_set_ext PARAMS ((struct symbol *, struct ecoff_extr *)); +extern void elf_ecoff_set_ext PARAMS ((symbolS *, struct ecoff_extr *)); #endif #endif /* _OBJ_ELF_H */ diff --git a/gas/config/obj-multi.h b/gas/config/obj-multi.h index fe8d98d..d54c61f 100644 --- a/gas/config/obj-multi.h +++ b/gas/config/obj-multi.h @@ -25,26 +25,20 @@ /* FIXME: What's the story here? Why do we have to define OBJ_SYMFIELD_TYPE both here and in obj-elf.h? */ + #ifdef OBJ_MAYBE_ELF struct elf_obj_sy { + int local; expressionS *size; char *versioned_name; +#ifdef ECOFF_DEBUGGING + /* If we are generating ECOFF debugging information, we need some + additional fields for each symbol. */ + struct efdr *ecoff_file; + struct localsym *ecoff_symbol; + valueT ecoff_extern_size; +#endif }; #define OBJ_SYMFIELD_TYPE struct elf_obj_sy -#define ELF_TARGET_SYMBOL_FIELDS int local:1; -#else -#define ELF_TARGET_SYMBOL_FIELDS #endif - -#ifdef ECOFF_DEBUGGING -struct efdr; -struct localsym; -#define ECOFF_DEBUG_TARGET_SYMBOL_FIELDS struct efdr *ecoff_file; struct localsym *ecoff_symbol; valueT ecoff_extern_size; -#else -#define ECOFF_DEBUG_TARGET_SYMBOL_FIELDS -#endif - -#define TARGET_SYMBOL_FIELDS \ - ELF_TARGET_SYMBOL_FIELDS \ - ECOFF_DEBUG_TARGET_SYMBOL_FIELDS diff --git a/gas/config/obj-vms.h b/gas/config/obj-vms.h index ac0c1fb..ad8fdce 100644 --- a/gas/config/obj-vms.h +++ b/gas/config/obj-vms.h @@ -1,5 +1,5 @@ /* VMS object file format - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -214,18 +214,17 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ /* Force structure tags into scope so that their use in prototypes will never be their first occurance. */ struct fix; -struct symbol; struct frag; /* obj-vms routines visible to the rest of gas. */ extern void tc_aout_fix_to_chars PARAMS ((char *,struct fix *,relax_addressT)); -extern int vms_resolve_symbol_redef PARAMS ((struct symbol *)); +extern int vms_resolve_symbol_redef PARAMS ((symbolS *)); #define RESOLVE_SYMBOL_REDEFINITION(X) vms_resolve_symbol_redef(X) /* Compiler-generated label "__vax_g_doubles" is used to augment .stabs. */ -extern void vms_check_for_special_label PARAMS ((struct symbol *)); +extern void vms_check_for_special_label PARAMS ((symbolS *)); #define obj_frob_label(X) vms_check_for_special_label(X) extern void vms_check_for_main PARAMS ((void)); diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c index 568617f..69432dc 100644 --- a/gas/config/tc-alpha.c +++ b/gas/config/tc-alpha.c @@ -4,7 +4,7 @@ Written by Alessandro Forin, based on earlier gas-1.38 target CPU files. Modified by Ken Raeburn for gas-2.x and ECOFF support. Modified by Richard Henderson for ELF support. - Modified by Klaus K"ampf for EVAX (openVMS/Alpha) support. + Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support. This file is part of GAS, the GNU Assembler. @@ -96,8 +96,9 @@ struct alpha_macro /* Two extra symbols we want to see in our input. This is a blatent misuse of the expressionS.X_op field. */ -#define O_pregister (O_max+1) /* O_register, but in parentheses */ -#define O_cpregister (O_pregister+1) /* + a leading comma */ +#define O_pregister ((operatorT) (O_max+1)) /* O_register, in parentheses */ +#define O_cpregister ((operatorT) (O_pregister+1)) /* + a leading comma */ +#define O_alpha_max ((operatorT) (O_cpregister+1)) /* Macros for extracting the type and number of encoded register tokens */ @@ -709,6 +710,13 @@ md_begin () { unsigned int i; + /* Verify that X_op field is wide enough. */ + { + expressionS e; + e.X_op = O_alpha_max; + assert (e.X_op == O_alpha_max); + } + /* Create the opcode hash table */ alpha_opcode_hash = hash_new (); @@ -1081,7 +1089,7 @@ md_apply_fix (fixP, valueP) #endif do_reloc_gp: - fixP->fx_addsy = section_symbol (absolute_section); + fixP->fx_addsy = section_symbol (now_seg); md_number_to_chars (fixpos, value, 2); break; @@ -1173,7 +1181,7 @@ md_apply_fix (fixP, valueP) Therefore they must be completely resolved as constants. */ if (fixP->fx_addsy != 0 - && fixP->fx_addsy->bsym->section != absolute_section) + && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) as_bad_where (fixP->fx_file, fixP->fx_line, _("non-absolute expression in constant field")); @@ -1393,7 +1401,8 @@ tc_gen_reloc (sec, fixp) arelent *reloc; reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; /* Make sure none of our internal relocations make it this far. @@ -1435,7 +1444,7 @@ tc_gen_reloc (sec, fixp) */ if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)) && !S_IS_COMMON(fixp->fx_addsy)) - reloc->addend -= fixp->fx_addsy->bsym->value; + reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value; #endif } @@ -2109,9 +2118,6 @@ FIXME expressionS newtok[3]; expressionS addend; - /* We're going to need this symbol in md_apply_fix(). */ - (void) section_symbol (absolute_section); - #ifdef OBJ_ECOFF if (regno (tok[2].X_add_number) == AXP_REG_PV) ecoff_set_gp_prolog_size (0); @@ -2175,7 +2181,7 @@ add_to_link_pool (basesym, sym, addend) segment_info_type *seginfo = seg_info (alpha_link_section); fixS *fixp; - offset = -basesym->sy_obj; + offset = - *symbol_get_obj (basesym); /* @@ This assumes all entries in a given section will be of the same size... Probably correct, but unwise to rely on. */ @@ -2498,7 +2504,8 @@ load_expression (targreg, exp, pbasereg, poffset) } insn.nfixups++; insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; - insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_op = O_symbol; + insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg); insn.fixups[0].exp.X_add_number = 1; emit_lituse = 0; @@ -2649,7 +2656,8 @@ emit_ir_load (tok, ntok, opname) } insn.nfixups++; insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; - insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_op = O_symbol; + insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg); insn.fixups[0].exp.X_add_number = 1; } @@ -2702,7 +2710,8 @@ emit_loadstore (tok, ntok, opname) } insn.nfixups++; insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; - insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_op = O_symbol; + insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg); insn.fixups[0].exp.X_add_number = 1; } @@ -3287,7 +3296,8 @@ emit_jsrjmp (tok, ntok, vopname) } insn.nfixups++; insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; - insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_op = O_symbol; + insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg); insn.fixups[0].exp.X_add_number = 3; } @@ -3457,7 +3467,7 @@ s_alpha_comm (ignore) p = frag_more (temp); new_seg->flags |= SEC_IS_COMMON; if (! S_IS_DEFINED (symbolP)) - symbolP->bsym->section = new_seg; + S_SET_SEGMENT (symbolP, new_seg); #else S_SET_VALUE (symbolP, (valueT) temp); #endif @@ -3468,7 +3478,7 @@ s_alpha_comm (ignore) subseg_set (current_section, current_subsec); #endif - know (symbolP->sy_frag == &zero_address_frag); + know (symbol_get_frag (symbolP) == &zero_address_frag); demand_empty_rest_of_line (); } @@ -3557,7 +3567,7 @@ s_alpha_ent (dummy) as_warn (_("nested .ent directives")); sym = symbol_find_or_make (name); - sym->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; alpha_cur_ent_sym = sym; /* The .ent directive is sometimes followed by a number. Not sure @@ -3604,12 +3614,13 @@ s_alpha_end (dummy) /* Create an expression to calculate the size of the function. */ if (sym) { - sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS)); - sym->sy_obj.size->X_op = O_subtract; - sym->sy_obj.size->X_add_symbol + symbol_get_obj (sym)->size = + (expressionS *) xmalloc (sizeof (expressionS)); + symbol_get_obj (sym)->size->X_op = O_subtract; + symbol_get_obj (sym)->size->X_add_symbol = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now); - sym->sy_obj.size->X_op_symbol = sym; - sym->sy_obj.size->X_add_number = 0; + symbol_get_obj (sym)->size->X_op_symbol = sym; + symbol_get_obj (sym)->size->X_add_number = 0; } alpha_cur_ent_sym = NULL; @@ -3765,7 +3776,7 @@ s_alpha_ent (ignore) } symbol = make_expr_symbol (&symexpr); - symbol->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION; alpha_evax_proc.symbol = symbol; demand_empty_rest_of_line (); @@ -3837,7 +3848,8 @@ s_alpha_pdesc (ignore) return; } - alpha_evax_proc.symbol->sy_obj = (valueT)seginfo->literal_pool_size; + *symbol_get_obj (alpha_evax_proc.symbol) = + (valueT) seginfo->literal_pool_size; expression (&exp); if (exp.X_op != O_symbol) @@ -3849,7 +3861,8 @@ s_alpha_pdesc (ignore) entry_sym = make_expr_symbol (&exp); /* Save bfd symbol of proc desc in function symbol. */ - alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym; + symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p + = symbol_get_bfdsym (entry_sym); SKIP_WHITESPACE (); if (*input_line_pointer++ != ',') @@ -4140,14 +4153,14 @@ s_alpha_file (ignore) extern char *demand_copy_string PARAMS ((int *lenP)); sprintf (case_hack, "<CASE:%01d%01d>", - alpha_flag_hash_long_names, alpha_flag_show_after_trunc); + alpha_flag_hash_long_names, alpha_flag_show_after_trunc); s = symbol_find_or_make (case_hack); - s->bsym->flags |= BSF_FILE; + symbol_get_bfdsym (s)->flags |= BSF_FILE; get_absolute_expression (); s = symbol_find_or_make (demand_copy_string (&length)); - s->bsym->flags |= BSF_FILE; + symbol_get_bfdsym (s)->flags |= BSF_FILE; demand_empty_rest_of_line (); return; @@ -4282,7 +4295,7 @@ s_alpha_proc (is_static) input_line_pointer++; temp = get_absolute_expression (); } - /* symbolP->sy_other = (signed char) temp; */ + /* *symbol_get_obj (symbolP) = (signed char) temp; */ as_warn (_("unhandled: .proc %s,%d"), name, temp); demand_empty_rest_of_line (); } @@ -4745,7 +4758,7 @@ alpha_align (n, pfill, label, force) if (label != NULL) { assert (S_GET_SEGMENT (label) == now_seg); - label->sy_frag = frag_now; + symbol_set_frag (label, frag_now); S_SET_VALUE (label, (valueT) frag_now_fix ()); } diff --git a/gas/config/tc-alpha.h b/gas/config/tc-alpha.h index ca6903a..a350513 100644 --- a/gas/config/tc-alpha.h +++ b/gas/config/tc-alpha.h @@ -85,7 +85,7 @@ extern int tc_get_register PARAMS ((int frame)); extern void alpha_frob_ecoff_data PARAMS ((void)); #define tc_frob_label(sym) alpha_define_label (sym) -extern void alpha_define_label PARAMS ((struct symbol *)); +extern void alpha_define_label PARAMS ((symbolS *)); #define md_cons_align(nbytes) alpha_cons_align (nbytes) extern void alpha_cons_align PARAMS ((int)); diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index c07c2d7..3aafea3 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -1,5 +1,5 @@ /* tc-arc.c -- Assembler for the ARC - Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. Contributed by Doug Evans (dje@cygnus.com). This file is part of GAS, the GNU Assembler. @@ -15,8 +15,9 @@ 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. */ + 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. */ #include <stdio.h> #include <ctype.h> @@ -797,7 +798,7 @@ arc_common (ignore) S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size); } } - assert (symbolP->sy_frag == &zero_address_frag); + assert (symbol_get_frag (symbolP) == &zero_address_frag); if (*input_line_pointer != ',') { as_bad (_("expected comma after common length")); @@ -830,8 +831,8 @@ arc_common (ignore) if (align) frag_align (align, 0, 0); if (S_GET_SEGMENT (symbolP) == bss_section) - symbolP->sy_frag->fr_symbol = 0; - symbolP->sy_frag = frag_now; + symbol_get_frag (symbolP)->fr_symbol = 0; + symbol_set_frag (symbolP, frag_now); p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) size, (char *) 0); *p = 0; @@ -966,7 +967,7 @@ arc_rename (ignore) new = (char *) xmalloc (strlen (name) + 1); strcpy (new, name); *input_line_pointer = c; - sym->sy_tc.real_name = new; + symbol_get_tc (sym)->real_name = new; demand_empty_rest_of_line (); } @@ -1241,13 +1242,13 @@ get_arc_exp_reloc_type (data_p, default_type, exp, expnew) if (exp->X_op == O_right_shift && exp->X_op_symbol != NULL - && exp->X_op_symbol->sy_value.X_op == O_constant - && exp->X_op_symbol->sy_value.X_add_number == 2 + && symbol_constant_p (exp->X_op_symbol) + && S_GET_VALUE (exp->X_op_symbol) == 2 && exp->X_add_number == 0) { if (exp->X_add_symbol != NULL - && (exp->X_add_symbol->sy_value.X_op == O_constant - || exp->X_add_symbol->sy_value.X_op == O_symbol)) + && (symbol_constant_p (exp->X_add_symbol) + || symbol_equated_p (exp->X_add_symbol))) { *expnew = *exp; expnew->X_op = O_symbol; @@ -1255,9 +1256,10 @@ get_arc_exp_reloc_type (data_p, default_type, exp, expnew) return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J']; } else if (exp->X_add_symbol != NULL - && exp->X_add_symbol->sy_value.X_op == O_subtract) + && (symbol_get_value_expression (exp->X_add_symbol)->X_op + == O_subtract)) { - *expnew = exp->X_add_symbol->sy_value; + *expnew = *symbol_get_value_expression (exp->X_add_symbol); return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J']; } } @@ -1445,7 +1447,8 @@ tc_gen_reloc (section, fixP) reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) @@ -1473,8 +1476,8 @@ int arc_frob_symbol (sym) symbolS *sym; { - if (sym->sy_tc.real_name != (char *) NULL) - S_SET_NAME (sym, sym->sy_tc.real_name); + if (symbol_get_tc (sym)->real_name != (char *) NULL) + S_SET_NAME (sym, symbol_get_tc (sym)->real_name); return 0; } diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h index 6a95ff4..5066201 100644 --- a/gas/config/tc-arc.h +++ b/gas/config/tc-arc.h @@ -1,5 +1,5 @@ /* tc-arc.h - Macros and type defines for the ARC. - Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1997, 1999 Free Software Foundation, Inc. Contributed by Doug Evans (dje@cygnus.com). This file is part of GAS, the GNU Assembler. @@ -66,6 +66,6 @@ struct arc_tc_sy #define TC_SYMFIELD_TYPE struct arc_tc_sy /* Finish up the symbol. */ -extern int arc_frob_symbol PARAMS ((struct symbol *)); +extern int arc_frob_symbol PARAMS ((symbolS *)); #define tc_frob_symbol(sym, punt) punt = arc_frob_symbol (sym) #endif diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index d898bf0..7a90601 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -51,12 +51,17 @@ #define ARM_LONGMUL 0x00000010 /* allow long multiplies */ #define ARM_HALFWORD 0x00000020 /* allow half word loads */ #define ARM_THUMB 0x00000040 /* allow BX instruction */ +#define ARM_EXT_V5 0x00000080 /* allow CLZ etc */ -#define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD) +/* Architectures are the sum of the base and extensions */ +#define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD) +#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB) +#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5) +#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB) /* Some useful combinations: */ #define ARM_ANY 0x00ffffff -#define ARM_2UP 0x00fffffe +#define ARM_2UP (ARM_ANY - ARM_1) #define ARM_ALL ARM_2UP /* Not arm1 only */ #define ARM_3UP 0x00fffffc #define ARM_6UP 0x00fffff8 /* Includes ARM7 */ @@ -73,7 +78,7 @@ #ifndef CPU_DEFAULT #if defined __thumb__ -#define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB) +#define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB) #else #define CPU_DEFAULT ARM_ALL #endif @@ -419,6 +424,7 @@ static void do_branch PARAMS ((char *operands, unsigned long flags)); static void do_swi PARAMS ((char *operands, unsigned long flags)); /* Pseudo Op codes */ static void do_adr PARAMS ((char *operands, unsigned long flags)); +static void do_adrl PARAMS ((char * operands, unsigned long flags)); static void do_nop PARAMS ((char *operands, unsigned long flags)); /* ARM 2 */ static void do_mul PARAMS ((char *operands, unsigned long flags)); @@ -455,6 +461,7 @@ static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *)); static int add_to_lit_pool PARAMS ((void)); static unsigned validate_immediate PARAMS ((unsigned)); +static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *)); static int validate_offset_imm PARAMS ((int, int)); static void opcode_select PARAMS ((int)); static void end_of_line PARAMS ((char *)); @@ -484,9 +491,9 @@ static void thumb_mov_compare PARAMS ((char *, int)); static void set_constant_flonums PARAMS ((void)); static valueT md_chars_to_number PARAMS ((char *, int)); static void insert_reg_alias PARAMS ((char *, int)); -static void output_inst PARAMS ((char *)); +static void output_inst PARAMS ((void)); #ifdef OBJ_ELF -static bfd_reloc_code_real_type arm_parse_reloc(void); +static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void)); #endif /* ARM instructions take 4bytes in the object file, Thumb instructions @@ -540,6 +547,7 @@ static CONST struct asm_opcode insns[] = /* Pseudo ops */ {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr}, + {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl}, {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop}, /* ARM 2 multiplies */ @@ -870,8 +878,8 @@ static CONST struct reg_entry reg_table[] = {NULL, 0} }; -#define bad_args _("Bad arguments to instruction"); -#define bad_pc _("r15 not allowed here"); +#define bad_args _("Bad arguments to instruction"); +#define bad_pc _("r15 not allowed here"); static struct hash_control * arm_ops_hsh = NULL; static struct hash_control * arm_tops_hsh = NULL; @@ -897,7 +905,11 @@ static void s_thumb PARAMS ((int)); static void s_code PARAMS ((int)); static void s_force_thumb PARAMS ((int)); static void s_thumb_func PARAMS ((int)); +static void s_thumb_set PARAMS ((int)); +static void arm_s_text PARAMS ((int)); +static void arm_s_data PARAMS ((int)); #ifdef OBJ_ELF +static void arm_s_section PARAMS ((int)); static void s_arm_elf_cons PARAMS ((int)); #endif @@ -905,27 +917,35 @@ static int my_get_expression PARAMS ((expressionS *, char **)); CONST pseudo_typeS md_pseudo_table[] = { - {"req", s_req, 0}, /* Never called becasue '.req' does not start line */ - {"bss", s_bss, 0}, - {"align", s_align, 0}, - {"arm", s_arm, 0}, - {"thumb", s_thumb, 0}, - {"code", s_code, 0}, - {"force_thumb", s_force_thumb, 0}, - {"thumb_func", s_thumb_func, 0}, - {"even", s_even, 0}, - {"ltorg", s_ltorg, 0}, - {"pool", s_ltorg, 0}, + { "req", s_req, 0 }, /* Never called becasue '.req' does not start line */ + { "bss", s_bss, 0 }, + { "align", s_align, 0 }, + { "arm", s_arm, 0 }, + { "thumb", s_thumb, 0 }, + { "code", s_code, 0 }, + { "force_thumb", s_force_thumb, 0 }, + { "thumb_func", s_thumb_func, 0 }, + { "thumb_set", s_thumb_set, 0 }, + { "even", s_even, 0 }, + { "ltorg", s_ltorg, 0 }, + { "pool", s_ltorg, 0 }, + /* Allow for the effect of section changes. */ + { "text", arm_s_text, 0 }, + { "data", arm_s_data, 0 }, #ifdef OBJ_ELF - {"word", s_arm_elf_cons, 4}, - {"long", s_arm_elf_cons, 4}, + { "section", arm_s_section, 0 }, + { "section.s", arm_s_section, 0 }, + { "sect", arm_s_section, 0 }, + { "sect.s", arm_s_section, 0 }, + { "word", s_arm_elf_cons, 4 }, + { "long", s_arm_elf_cons, 4 }, #else - {"word", cons, 4}, + { "word", cons, 4}, #endif - {"extend", float_cons, 'x'}, - {"ldouble", float_cons, 'x'}, - {"packed", float_cons, 'p'}, - {0, 0, 0} + { "extend", float_cons, 'x' }, + { "ldouble", float_cons, 'x' }, + { "packed", float_cons, 'p' }, + { 0, 0, 0 } }; /* Stuff needed to resolve the label ambiguity @@ -955,7 +975,6 @@ literalT literals[MAX_LITERAL_POOL_SIZE]; int next_literal_pool_place = 0; /* Next free entry in the pool */ int lit_pool_num = 1; /* Next literal pool number */ symbolS * current_poolP = NULL; -symbolS * symbol_make_empty PARAMS ((void)); static int add_to_lit_pool () @@ -963,7 +982,8 @@ add_to_lit_pool () int lit_count = 0; if (current_poolP == NULL) - current_poolP = symbol_make_empty (); + current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section, + (valueT) 0, &zero_address_frag); /* Check if this literal value is already in the pool: */ while (lit_count < next_literal_pool_place) @@ -1027,7 +1047,7 @@ symbol_locate (symbolP, name, segment, valu, frag) S_SET_VALUE (symbolP, valu); symbol_clear_list_pointers(symbolP); - symbolP->sy_frag = frag; + symbol_set_frag (symbolP, frag); /* Link to end of symbol chain. */ { @@ -1049,23 +1069,6 @@ symbol_locate (symbolP, name, segment, valu, frag) #endif /* DEBUG_SYMS */ } -symbolS * -symbol_make_empty () -{ - symbolS * symbolP; - - symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS)); - - /* symbol must be born in some fixed state. This seems as good as any. */ - memset (symbolP, 0, sizeof (symbolS)); - - symbolP->bsym = bfd_make_empty_symbol (stdoutput); - assert (symbolP->bsym != 0); - symbolP->bsym->udata.p = (PTR) symbolP; - - return symbolP; -} - /* Check that an immediate is valid, and if so, convert it to the right format. */ static unsigned int @@ -1084,6 +1087,47 @@ validate_immediate (val) return FAIL; } +/* Check to see if an immediate can be computed as two seperate immediate + values, added together. We already know that this value cannot be + computed by just one ARM instruction. */ + +static unsigned int +validate_immediate_twopart (val, highpart) + unsigned int val; + unsigned int * highpart; +{ + unsigned int a; + unsigned int i; + + for (i = 0; i < 32; i += 2) + if (((a = rotate_left (val, i)) & 0xff) != 0) + { + if (a & 0xff00) + { + if (a & ~ 0xffff) + continue; + * highpart = (a >> 8) | ((i + 24) << 7); + } + else if (a & 0xff0000) + { + if (a & 0xff000000) + continue; + + * highpart = (a >> 16) | ((i + 16) << 7); + } + else + { + assert (a & 0xff000000); + + * highpart = (a >> 24) | ((i + 8) << 7); + } + + return (a & 0xff) | (i << 7); + } + + return FAIL; +} + static int validate_offset_imm (val, hwse) int val; @@ -1126,19 +1170,14 @@ s_even (ignore) } static void -s_ltorg (internal) - int internal; +s_ltorg (ignored) + int ignored; { int lit_count = 0; char sym_name[20]; if (current_poolP == NULL) - { - /* Nothing to do */ - if (!internal) - as_tsktsk (_("Nothing to put in the pool\n")); - return; - } + return; /* Align pool as you have word accesses */ /* Only make a frag if we have to ... */ @@ -1147,9 +1186,6 @@ s_ltorg (internal) record_alignment (now_seg, 2); - if (internal) - as_tsktsk (_("Inserting implicit pool at change of section")); - sprintf (sym_name, "$$lit_\002%x", lit_pool_num++); symbol_locate (current_poolP, sym_name, now_seg, @@ -1238,6 +1274,135 @@ s_thumb_func (ignore) demand_empty_rest_of_line (); } +/* Perform a .set directive, but also mark the alias as + being a thumb function. */ + +static void +s_thumb_set (equiv) + int equiv; +{ + /* XXX the following is a duplicate of the code for s_set() in read.c + We cannot just call that code as we need to get at the symbol that + is created. */ + register char * name; + register char delim; + register char * end_name; + register symbolS * symbolP; + + /* + * Especial apologies for the random logic: + * this just grew, and could be parsed much more simply! + * Dean in haste. + */ + name = input_line_pointer; + delim = get_symbol_end (); + end_name = input_line_pointer; + *end_name = delim; + + SKIP_WHITESPACE (); + + if (*input_line_pointer != ',') + { + *end_name = 0; + as_bad (_("Expected comma after name \"%s\""), name); + *end_name = delim; + ignore_rest_of_line (); + return; + } + + input_line_pointer++; + *end_name = 0; + + if (name[0] == '.' && name[1] == '\0') + { + /* XXX - this should not happen to .thumb_set */ + abort (); + } + + if ((symbolP = symbol_find (name)) == NULL + && (symbolP = md_undefined_symbol (name)) == NULL) + { +#ifndef NO_LISTING + /* When doing symbol listings, play games with dummy fragments living + outside the normal fragment chain to record the file and line info + for this symbol. */ + if (listing & LISTING_SYMBOLS) + { + extern struct list_info_struct * listing_tail; + fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS)); + memset (dummy_frag, 0, sizeof(fragS)); + dummy_frag->fr_type = rs_fill; + dummy_frag->line = listing_tail; + symbolP = symbol_new (name, undefined_section, 0, dummy_frag); + dummy_frag->fr_symbol = symbolP; + } + else +#endif + symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); + +#ifdef OBJ_COFF + /* "set" symbols are local unless otherwise specified. */ + SF_SET_LOCAL (symbolP); +#endif /* OBJ_COFF */ + } /* make a new symbol */ + + symbol_table_insert (symbolP); + + * end_name = delim; + + if (equiv + && S_IS_DEFINED (symbolP) + && S_GET_SEGMENT (symbolP) != reg_section) + as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); + + pseudo_set (symbolP); + + demand_empty_rest_of_line (); + + /* XXX now we come to the Thumb specific bit of code. */ + + THUMB_SET_FUNC (symbolP, 1); + ARM_SET_THUMB (symbolP, 1); + ARM_SET_INTERWORK (symbolP, support_interwork); +} + +/* If we change section we must dump the literal pool first. */ +static void +arm_s_text (ignore) + int ignore; +{ + if (now_seg != text_section) + s_ltorg (0); + + s_text (ignore); +} + +static void +arm_s_data (ignore) + int ignore; +{ + if (flag_readonly_data_in_text) + { + if (now_seg != text_section) + s_ltorg (0); + } + else if (now_seg != data_section) + s_ltorg (0); + + s_data (ignore); +} + +#ifdef OBJ_ELF +static void +arm_s_section (ignore) + int ignore; +{ + s_ltorg (0); + + obj_elf_section (ignore); +} +#endif + static void opcode_select (width) int width; @@ -2039,14 +2204,14 @@ static int walk_no_bignums (sp) symbolS * sp; { - if (sp->sy_value.X_op == O_big) + if (symbol_get_value_expression (sp)->X_op == O_big) return 1; - if (sp->sy_value.X_add_symbol) + if (symbol_get_value_expression (sp)->X_add_symbol) { - return (walk_no_bignums (sp->sy_value.X_add_symbol) - || (sp->sy_value.X_op_symbol - && walk_no_bignums (sp->sy_value.X_op_symbol))); + return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol) + || (symbol_get_value_expression (sp)->X_op_symbol + && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol))); } return 0; @@ -2491,6 +2656,41 @@ do_adr (str, flags) } static void +do_adrl (str, flags) + char * str; + unsigned long flags; +{ + /* This is a pseudo-op of the form "adrl rd, label" to be converted + into a relative address of the form: + add rd, pc, #low(label-.-8)" + add rd, rd, #high(label-.-8)" */ + + while (* str == ' ') + str ++; + + if (reg_required_here (& str, 12) == FAIL + || skip_past_comma (& str) == FAIL + || my_get_expression (& inst.reloc.exp, & str)) + { + if (!inst.error) + inst.error = bad_args; + return; + } + + end_of_line (str); + + /* Frag hacking will turn this into a sub instruction if the offset turns + out to be negative. */ + inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE; + inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */ + inst.reloc.pc_rel = 1; + inst.instruction |= flags; + inst.size = INSN_SIZE * 2; + + return; +} + +static void do_cmp (str, flags) char * str; unsigned long flags; @@ -2584,7 +2784,7 @@ ldst_extend (str, hwse) /* Halfword and signextension instructions have the immediate value split across bits 11..8 and bits 3..0 */ if (hwse) - inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF; + inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF); else inst.instruction |= add | value; } @@ -2635,7 +2835,8 @@ do_ldst (str, flags) /* This is not ideal, but it is the simplest way of dealing with the ARM7T halfword instructions (since they use a different encoding, but the same mnemonic): */ - if (halfword = ((flags & 0x80000000) != 0)) + halfword = (flags & 0x80000000) != 0; + if (halfword) { /* This is actually a load/store of a halfword, or a signed-extension load */ @@ -4835,6 +5036,7 @@ md_begin () if (support_interwork) flags |= F_INTERWORK; if (uses_apcs_float) flags |= F_APCS_FLOAT; if (pic_code) flags |= F_PIC; + if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT; bfd_set_private_flags (stdoutput, flags); } @@ -4867,9 +5069,13 @@ md_begin () /* Catch special cases */ if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT)) { - if (cpu_variant & ARM_THUMB) + if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB)) + mach = bfd_mach_arm_5T; + else if (cpu_variant & ARM_EXT_V5) + mach = bfd_mach_arm_5; + else if (cpu_variant & ARM_THUMB) mach = bfd_mach_arm_4T; - else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4) + else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4) mach = bfd_mach_arm_4; else if (cpu_variant & ARM_LONGMUL) mach = bfd_mach_arm_3M; @@ -5010,8 +5216,7 @@ md_atof (type, litP, sizeP) return 0; } -/* The knowledge of the PC's pipeline offset is built into the relocs - for the ELF port and into the insns themselves for the COFF port. */ +/* The knowledge of the PC's pipeline offset is built into the insns themselves. */ long md_pcrel_from (fixP) fixS * fixP; @@ -5028,7 +5233,7 @@ md_pcrel_from (fixP) for the calculation */ return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3; } - + return fixP->fx_where + fixP->fx_frag->fr_address; } @@ -5163,7 +5368,7 @@ md_apply_fix3 (fixP, val, seg) /* Note whether this will delete the relocation. */ #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */ - if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant) + if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy)) && !fixP->fx_pcrel) #else if (fixP->fx_addsy == 0 && !fixP->fx_pcrel) @@ -5179,7 +5384,8 @@ md_apply_fix3 (fixP, val, seg) && S_IS_DEFINED (fixP->fx_addsy) && S_GET_SEGMENT (fixP->fx_addsy) != seg) { - if (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH) + if (target_oabi + && fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH) value = 0; else value += md_pcrel_from (fixP); @@ -5200,7 +5406,8 @@ md_apply_fix3 (fixP, val, seg) && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL) { as_bad_where (fixP->fx_file, fixP->fx_line, - _("invalid constant (%x) after fixup\n"), value); + _("invalid constant (%lx) after fixup\n"), + (unsigned long) value); break; } @@ -5208,11 +5415,55 @@ md_apply_fix3 (fixP, val, seg) md_number_to_chars (buf, (valueT) newimm, INSN_SIZE); break; - case BFD_RELOC_ARM_OFFSET_IMM: + case BFD_RELOC_ARM_ADRL_IMMEDIATE: + { + unsigned int highpart = 0; + unsigned int newinsn = 0xe1a00000; /* nop */ + newimm = validate_immediate (value); + temp = md_chars_to_number (buf, INSN_SIZE); + + /* If the instruction will fail, see if we can fix things up by + changing the opcode. */ + if (newimm == (unsigned int) FAIL + && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL) + { + /* No ? OK - try using two ADD instructions to generate the value. */ + newimm = validate_immediate_twopart (value, & highpart); + + /* Yes - then make sure that the second instruction is also an add. */ + if (newimm != (unsigned int) FAIL) + newinsn = temp; + /* Still No ? Try using a negated value. */ + else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL) + temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT; + /* Otherwise - give up. */ + else + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Unable to compute ADRL instructions for PC offset of 0x%x\n"), value); + break; + } + + /* Replace the first operand in the 2nd instruction (which is the PC) + with the destination register. We have already added in the PC in the + first instruction and we do not want to do it again. */ + newinsn &= ~ 0xf0000; + newinsn |= ((newinsn & 0x0f000) << 4); + } + + newimm |= (temp & 0xfffff000); + md_number_to_chars (buf, (valueT) newimm, INSN_SIZE); + + highpart |= (newinsn & 0xfffff000); + md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE); + } + break; + + case BFD_RELOC_ARM_OFFSET_IMM: sign = value >= 0; if ((value = validate_offset_imm (value, 0)) == FAIL) { - as_bad (_("bad immediate value for offset (%d)"), val); + as_bad (_("bad immediate value for offset (%ld)"), (long) value); break; } if (value < 0) @@ -5233,7 +5484,7 @@ md_apply_fix3 (fixP, val, seg) as_bad_where (fixP->fx_file, fixP->fx_line, _("invalid literal constant: pool needs to be closer\n")); else - as_bad (_("bad immediate value for offset (%d)"), value); + as_bad (_("bad immediate value for offset (%ld)"), (long) value); break; } @@ -5242,7 +5493,7 @@ md_apply_fix3 (fixP, val, seg) newval = md_chars_to_number (buf, INSN_SIZE); newval &= 0xff7ff0f0; - newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0); + newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0); md_number_to_chars (buf, newval, INSN_SIZE); break; @@ -5315,14 +5566,12 @@ md_apply_fix3 (fixP, val, seg) case BFD_RELOC_ARM_PCREL_BRANCH: newval = md_chars_to_number (buf, INSN_SIZE); + #ifdef OBJ_ELF - newval &= 0xff000000; if (! target_oabi) value = fixP->fx_offset; - else -#else - value = (value >> 2) & 0x00ffffff; #endif + value = (value >> 2) & 0x00ffffff; value = (value + (newval & 0x00ffffff)) & 0x00ffffff; newval = value | (newval & 0xff000000); md_number_to_chars (buf, newval, INSN_SIZE); @@ -5504,7 +5753,8 @@ md_apply_fix3 (fixP, val, seg) default: as_bad_where (fixP->fx_file, fixP->fx_line, - "Unable to process relocation for thumb opcode: %x", newval); + "Unable to process relocation for thumb opcode: %lx", + (unsigned long) newval); break; } md_number_to_chars (buf, newval, THUMB_SIZE); @@ -5543,7 +5793,8 @@ md_apply_fix3 (fixP, val, seg) if (subtract || value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid immediate for address calculation (value = 0x%08X)"), value); + _("Invalid immediate for address calculation (value = 0x%08lX)"), + (unsigned long) value); newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP); newval |= rd << 8; newval |= value >> 2; @@ -5576,7 +5827,8 @@ md_apply_fix3 (fixP, val, seg) case 0x05: /* 8bit immediate CMP */ if (value < 0 || value > 255) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid immediate: %d is too large"), value); + _("Invalid immediate: %ld is too large"), + (long) value); newval |= value; break; @@ -5590,7 +5842,7 @@ md_apply_fix3 (fixP, val, seg) /* 5bit shift value (0..31) */ if (value < 0 || value > 31) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Illegal Thumb shift value: %d"), value); + _("Illegal Thumb shift value: %ld"), (long) value); newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f; newval |= value << 6; md_number_to_chars (buf, newval , THUMB_SIZE); @@ -5622,7 +5874,8 @@ tc_gen_reloc (section, fixp) reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; /* @@ Why fx_addnumber sometimes and fx_offset other times? */ @@ -5671,17 +5924,11 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_ARM_LITERAL: case BFD_RELOC_ARM_HWLITERAL: /* If this is called then the a literal has been referenced across - a section boundry - possibly due to an implicit dump */ + a section boundary - possibly due to an implicit dump */ as_bad_where (fixp->fx_file, fixp->fx_line, - _("Literal referenced across section boundry (Implicit dump?)")); + _("Literal referenced across section boundary (Implicit dump?)")); return NULL; - case BFD_RELOC_ARM_GOTPC: - assert (fixp->fx_pcrel != 0); - code = fixp->fx_r_type; - code = BFD_RELOC_32_PCREL; - break; - #ifdef OBJ_ELF case BFD_RELOC_ARM_GOT32: case BFD_RELOC_ARM_GOTOFF: @@ -5696,6 +5943,12 @@ tc_gen_reloc (section, fixp) fixp->fx_r_type); return NULL; + case BFD_RELOC_ARM_ADRL_IMMEDIATE: + as_bad_where (fixp->fx_file, fixp->fx_line, + _("ADRL used for a symbol not defined in the same file"), + fixp->fx_r_type); + return NULL; + case BFD_RELOC_ARM_OFFSET_IMM: as_bad_where (fixp->fx_file, fixp->fx_line, _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"), @@ -5731,7 +5984,10 @@ tc_gen_reloc (section, fixp) if (code == BFD_RELOC_32_PCREL && GOT_symbol && fixp->fx_addsy == GOT_symbol) - code = BFD_RELOC_ARM_GOTPC; + { + code = BFD_RELOC_ARM_GOTPC; + reloc->addend = fixp->fx_offset = reloc->address; + } #endif reloc->howto = bfd_reloc_type_lookup (stdoutput, code); @@ -5757,8 +6013,7 @@ md_estimate_size_before_relax (fragP, segtype) } static void -output_inst (str) - char * str; +output_inst PARAMS ((void)) { char * to = NULL; @@ -5773,7 +6028,13 @@ output_inst (str) { assert (inst.size == (2 * THUMB_SIZE)); md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE); - md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE); + md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE); + } + else if (inst.size > INSN_SIZE) + { + assert (inst.size == (2 * INSN_SIZE)); + md_number_to_chars (to, inst.instruction, INSN_SIZE); + md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE); } else md_number_to_chars (to, inst.instruction, inst.size); @@ -5803,7 +6064,7 @@ md_assemble (str) /* Align the previous label if needed. */ if (last_label_seen != NULL) { - last_label_seen->sy_frag = frag_now; + symbol_set_frag (last_label_seen, frag_now); S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ()); S_SET_SEGMENT (last_label_seen, now_seg); } @@ -5813,7 +6074,7 @@ md_assemble (str) if (*str == ' ') str++; /* Skip leading white space */ - + /* Scan up to the end of the op-code, which must end in white space or end of string. */ for (start = p = str; *p != '\0'; p++) @@ -5828,24 +6089,25 @@ md_assemble (str) if (thumb_mode) { - CONST struct thumb_opcode *opcode; + CONST struct thumb_opcode * opcode; c = *p; *p = '\0'; opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str); *p = c; + if (opcode) { inst.instruction = opcode->value; inst.size = opcode->size; (*opcode->parms)(p); - output_inst (start); + output_inst (); return; } } else { - CONST struct asm_opcode *opcode; + CONST struct asm_opcode * opcode; inst.size = INSN_SIZE; /* p now points to the end of the opcode, probably white space, but we @@ -5859,10 +6121,11 @@ md_assemble (str) *q = '\0'; opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str); *q = c; + if (opcode && opcode->template) { unsigned long flag_bits = 0; - char *r; + char * r; /* Check that this instruction is supported for this CPU */ if ((opcode->variants & cpu_variant) == 0) @@ -5879,7 +6142,7 @@ md_assemble (str) inst.instruction |= COND_ALWAYS; (*opcode->parms)(q, 0); } - output_inst (start); + output_inst (); return; } @@ -5964,7 +6227,7 @@ _("Warning: Use of the 'nv' conditional is deprecated\n")); } (*opcode->parms) (p, flag_bits); - output_inst (start); + output_inst (); return; } @@ -6051,7 +6314,10 @@ _("Warning: Use of the 'nv' conditional is deprecated\n")); * -m[arm]3 Arm 3 processor * -m[arm]6[xx], Arm 6 processors * -m[arm]7[xx][t][[d]m] Arm 7 processors - * -mstrongarm[110] Arm 8 processors + * -m[arm]8[10] Arm 8 processors + * -m[arm]9[20][tdmi] Arm 9 processors + * -mstrongarm[110[0]] StrongARM processors + * -m[arm]v[2345] Arm architecures * -mall All (except the ARM1) * FP variants: * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions @@ -6140,7 +6406,7 @@ md_parse_option (c, arg) } else if (streq (str, "thumb-interwork")) { - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4; #if defined OBJ_COFF || defined OBJ_ELF support_interwork = true; #endif @@ -6274,7 +6540,7 @@ md_parse_option (c, arg) switch (* str) { case 't': - cpu_variant |= (ARM_THUMB | ARM_ARCHv4); + cpu_variant |= (ARM_THUMB | ARM_ARCH_V4); break; case 'm': @@ -6301,16 +6567,20 @@ md_parse_option (c, arg) case '8': if (streq (str, "8") || streq (str, "810")) - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL; else goto bad; break; case '9': if (streq (str, "9")) - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB; + else if (streq (str, "920")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL; + else if (streq (str, "920t")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB; else if (streq (str, "9tdmi")) - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB; else goto bad; break; @@ -6319,7 +6589,7 @@ md_parse_option (c, arg) if (streq (str, "strongarm") || streq (str, "strongarm110") || streq (str, "strongarm1100")) - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL; else goto bad; break; @@ -6349,7 +6619,18 @@ md_parse_option (c, arg) break; case '4': - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4; + + switch (*++str) + { + case 't': cpu_variant |= ARM_THUMB; break; + case 0: break; + default: as_bad (_("Invalid architecture variant -m%s"), arg); break; + } + break; + + case '5': + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5; switch (*++str) { @@ -6392,7 +6673,7 @@ md_show_usage (fp) _("\ ARM Specific Assembler Options:\n\ -m[arm][<processor name>] select processor variant\n\ - -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\ + -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\ -mthumb only allow Thumb instructions\n\ -mthumb-interwork mark the assembled code as supporting interworking\n\ -mall allow any instruction\n\ @@ -6469,24 +6750,7 @@ fix_new_arm (frag, where, size, exp, pc_rel, reloc) } -/* - * This fix_new is called by cons via TC_CONS_FIX_NEW - * - * We check the expression to see if it is of the form - * __GLOBAL_OFFSET_TABLE + ??? - * If it is then this is a PC relative reference to the GOT. - * i.e. - * ldr sl, L1 - * add sl, pc, sl - * L2: - * ... - * L1: - * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4)) - * - * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the - * normal BFD_RELOC_{16,32,64} - */ - +/* This fix_new is called by cons via TC_CONS_FIX_NEW. */ void cons_fix_new_arm (frag, where, size, exp) fragS * frag; @@ -6515,13 +6779,6 @@ cons_fix_new_arm (frag, where, size, exp) break; } - /* Look for possible GOTPC reloc */ - - /* - * Look for pic assembler and 'undef symbol + expr symbol' expression - * and a 32 bit size. - */ - fix_new_exp (frag, where, (int) size, exp, pcrel, type); } @@ -6613,7 +6870,7 @@ arm_adjust_symtab () } if (ARM_IS_INTERWORK (sym)) - coffsymbol(sym->bsym)->native->u.syment.n_flags = 0xFF; + coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF; } #endif #ifdef OBJ_ELF @@ -6627,7 +6884,7 @@ arm_adjust_symtab () { if (THUMB_IS_FUNC (sym)) { - elf_sym = elf_symbol (sym->bsym); + elf_sym = elf_symbol (symbol_get_bfdsym (sym)); bind = ELF_ST_BIND (elf_sym); elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC); } @@ -6854,4 +7111,3 @@ s_arm_elf_cons (nbytes) } #endif /* OBJ_ELF */ - diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index bf99e24..d27d61d 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -1,5 +1,6 @@ /* This file is tc-arm.h - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 + Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modified by David Taylor (dtaylor@armltd.co.uk) @@ -103,7 +104,7 @@ extern void arm_start_line_hook PARAMS ((void)); #define tc_frob_label(S) arm_frob_label (S) - extern void arm_frob_label PARAMS ((struct symbol *)); + extern void arm_frob_label PARAMS ((symbolS *)); /* We also need to mark assembler created symbols: */ #define tc_frob_fake_label(S) arm_frob_label (S) @@ -121,9 +122,9 @@ /* We need to keep some local information on symbols. */ #define TC_SYMFIELD_TYPE unsigned int -#define ARM_GET_FLAG(s) ((s)->sy_tc) -#define ARM_SET_FLAG(s,v) ((s)->sy_tc |= (v)) -#define ARM_RESET_FLAG(s,v) ((s)->sy_tc &= ~(v)) +#define ARM_GET_FLAG(s) (*symbol_get_tc (s)) +#define ARM_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v)) +#define ARM_RESET_FLAG(s,v) (*symbol_get_tc (s) &= ~(v)) #define ARM_FLAG_THUMB (1 << 0) /* The symbol is a Thumb symbol rather than an Arm symbol. */ #define ARM_FLAG_INTERWORK (1 << 1) /* The symbol is attached to code that suppports interworking. */ @@ -170,6 +171,9 @@ char * arm_canonicalize_symbol_name PARAMS ((char *)); #define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L')) #define LOCAL_LABELS_FB 1 +#ifdef OBJ_ELF +#define LOCAL_LABEL_PREFIX '.' +#endif /* This expression evaluates to false if the relocation is for a local object for which we still want to do the relocation at runtime. True if we diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c index cf38f3e..33926fb 100644 --- a/gas/config/tc-d10v.c +++ b/gas/config/tc-d10v.c @@ -1,6 +1,5 @@ /* tc-d10v.c -- Assembler code for the Mitsubishi D10V - - Copyright (C) 1996, 1997, 1998 Free Software Foundation. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -37,8 +36,8 @@ int Optimizing = 0; #define AT_WORD_P(X) ((X)->X_op == O_right_shift \ && (X)->X_op_symbol != NULL \ - && (X)->X_op_symbol->sy_value.X_op == O_constant \ - && (X)->X_op_symbol->sy_value.X_add_number == AT_WORD_RIGHT_SHIFT) + && symbol_constant_p ((X)->X_op_symbol) \ + && S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT) #define AT_WORD_RIGHT_SHIFT 2 @@ -63,6 +62,8 @@ typedef struct _fixups static Fixups FixUps[2]; static Fixups *fixups; +static int do_not_ignore_hash = 0; + /* True if instruction swapping warnings should be inhibited. */ static unsigned char flag_warn_suppress_instructionswap; /* --nowarnswap */ @@ -159,7 +160,7 @@ register_name (expressionP) { expressionP->X_op = O_register; /* temporarily store a pointer to the string here */ - expressionP->X_op_symbol = (struct symbol *)input_line_pointer; + expressionP->X_op_symbol = (symbolS *)input_line_pointer; expressionP->X_add_number = reg_number; input_line_pointer = p; return 1; @@ -393,7 +394,8 @@ get_operands (exp) char *p = input_line_pointer; int numops = 0; int post = 0; - + int uses_at = 0; + while (*p) { while (*p == ' ' || *p == '\t' || *p == ',') @@ -403,6 +405,8 @@ get_operands (exp) if (*p == '@') { + uses_at = 1; + p++; exp[numops].X_op = O_absent; if (*p == '(') @@ -437,7 +441,20 @@ get_operands (exp) if (!register_name (&exp[numops])) { /* parse as an expression */ - expression (&exp[numops]); + if (uses_at) + { + /* Any expression that involves the indirect addressing + cannot also involve immediate addressing. Therefore + the use of the hash character is illegal. */ + int save = do_not_ignore_hash; + do_not_ignore_hash = 1; + + expression (&exp[numops]); + + do_not_ignore_hash = save; + } + else + expression (&exp[numops]); } if (strncasecmp (input_line_pointer, "@word", 5) == 0) @@ -1376,7 +1393,8 @@ tc_gen_reloc (seg, fixp) { arelent *reloc; reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) @@ -1595,7 +1613,7 @@ void md_operand (expressionP) expressionS *expressionP; { - if (*input_line_pointer == '#') + if (*input_line_pointer == '#' && ! do_not_ignore_hash) { input_line_pointer++; expression (expressionP); diff --git a/gas/config/tc-d30v.c b/gas/config/tc-d30v.c index c5033ba..0682a57 100644 --- a/gas/config/tc-d30v.c +++ b/gas/config/tc-d30v.c @@ -1,6 +1,5 @@ /* tc-d30v.c -- Assembler code for the Mitsubishi D30V - - Copyright (C) 1997, 1998 Free Software Foundation. + Copyright (C) 1997, 1998, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -216,7 +215,7 @@ register_name (expressionP) { expressionP->X_op = O_register; /* temporarily store a pointer to the string here */ - expressionP->X_op_symbol = (struct symbol *)input_line_pointer; + expressionP->X_op_symbol = (symbolS *)input_line_pointer; expressionP->X_add_number = reg_number; input_line_pointer = p; return 1; @@ -1745,7 +1744,8 @@ tc_gen_reloc (seg, fixp) { arelent *reloc; reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) @@ -2028,7 +2028,7 @@ d30v_frob_label (lab) d30v_cleanup (false); /* Update the label's address with the current output pointer. */ - lab->sy_frag = frag_now; + symbol_set_frag (lab, frag_now); S_SET_VALUE (lab, (valueT) frag_now_fix ()); /* Record this label for future adjustment after we find out what @@ -2110,7 +2110,7 @@ d30v_align (n, pfill, label) assert (S_GET_SEGMENT (label) == now_seg); - old_frag = label->sy_frag; + old_frag = symbol_get_frag (label); old_value = S_GET_VALUE (label); new_value = (valueT) frag_now_fix (); @@ -2125,15 +2125,16 @@ d30v_align (n, pfill, label) in the target fragment. Note, this search is guaranteed to find at least one match when sym == label, so no special case code is necessary. */ - for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous) + for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym)) { - if (sym->sy_frag == old_frag && S_GET_VALUE (sym) == old_value) + if (symbol_get_frag (sym) == old_frag + && S_GET_VALUE (sym) == old_value) { label_seen = true; - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, new_value); } - else if (label_seen && sym->sy_frag != old_frag) + else if (label_seen && symbol_get_frag (sym) != old_frag) break; } } diff --git a/gas/config/tc-d30v.h b/gas/config/tc-d30v.h index acce285..dfebbb9 100644 --- a/gas/config/tc-d30v.h +++ b/gas/config/tc-d30v.h @@ -1,5 +1,5 @@ /* tc-310v.h -- Header file for tc-d30v.c. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. Written by Martin Hunt, Cygnus Support. This file is part of GAS, the GNU Assembler. @@ -15,8 +15,9 @@ 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. */ + 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 TC_D30V @@ -52,7 +53,7 @@ int d30v_cleanup PARAMS ((int)); #define TC_START_LABEL(ch, ptr) (ch == ':' && d30v_cleanup (false)) #define md_start_line_hook() d30v_start_line (false) -void d30v_frob_label PARAMS ((struct symbol *)); +void d30v_frob_label PARAMS ((symbolS *)); #define tc_frob_label(sym) d30v_frob_label(sym) void d30v_cons_align PARAMS ((int)); diff --git a/gas/config/tc-fr30.c b/gas/config/tc-fr30.c index aa075b7..aca5880 100644 --- a/gas/config/tc-fr30.c +++ b/gas/config/tc-fr30.c @@ -384,7 +384,7 @@ md_convert_frag (abfd, sec, fragP) { /* Address we want to reach in file space. */ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; - target_address += fragP->fr_symbol->sy_frag->fr_address; + target_address += symbol_get_frag (fragP->fr_symbol)->fr_address; addend = (target_address - (opcode_address & -4)) >> 2; } diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 8785de8..82e07d3 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,5 +1,6 @@ /* tc-hppa.c -- Assemble for the PA - Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -34,32 +35,30 @@ /* Be careful, this file includes data *declarations*. */ #include "opcode/hppa.h" +#if defined (OBJ_ELF) && defined (OBJ_SOM) +error only one of OBJ_ELF and OBJ_SOM can be defined +#endif + /* A "convient" place to put object file dependencies which do not need to be seen outside of tc-hppa.c. */ #ifdef OBJ_ELF -/* Names of various debugging spaces/subspaces. */ -#define GDB_DEBUG_SPACE_NAME ".stab" -#define GDB_STRINGS_SUBSPACE_NAME ".stabstr" -#define GDB_SYMBOLS_SUBSPACE_NAME ".stab" -#define UNWIND_SECTION_NAME ".PARISC.unwind" -/* Nonzero if CODE is a fixup code needing further processing. */ - /* Object file formats specify relocation types. */ -typedef elf32_hppa_reloc_type reloc_type; +typedef elf_hppa_reloc_type reloc_type; /* Object file formats specify BFD symbol types. */ typedef elf_symbol_type obj_symbol_type; +#ifdef BFD64 /* How to generate a relocation. */ -#define hppa_gen_reloc_type hppa_elf_gen_reloc_type +#define hppa_gen_reloc_type _bfd_elf64_hppa_gen_reloc_type +#else +#define hppa_gen_reloc_type _bfd_elf32_hppa_gen_reloc_type +#endif /* ELF objects can have versions, but apparently do not have anywhere to store a copyright string. */ #define obj_version obj_elf_version #define obj_copyright obj_elf_version - -/* Use space aliases. */ -#define USE_ALIASES 1 #endif #ifdef OBJ_SOM @@ -76,9 +75,6 @@ typedef int reloc_type; #define obj_version obj_som_version #define obj_copyright obj_som_copyright -/* Do not use space aliases. */ -#define USE_ALIASES 0 - /* How to generate a relocation. */ #define hppa_gen_reloc_type hppa_som_gen_reloc_type @@ -267,6 +263,7 @@ struct call_desc unsigned int arg_count; }; +#ifdef OBJ_SOM /* This structure defines an entry in the subspace dictionary chain. */ @@ -321,17 +318,6 @@ struct space_dictionary_chain typedef struct space_dictionary_chain sd_chain_struct; -/* Structure for previous label tracking. Needed so that alignments, - callinfo declarations, etc can be easily attached to a particular - label. */ -typedef struct label_symbol_struct - { - struct symbol *lss_label; - sd_chain_struct *lss_space; - struct label_symbol_struct *lss_next; - } -label_symbol_struct; - /* This structure defines attributes of the default subspace dictionary entries. */ @@ -378,9 +364,6 @@ struct default_subspace_dict /* An index into the default spaces array. */ int def_space_index; - /* An alias for this section (or NULL if no alias exists). */ - char *alias; - /* Subsegment associated with this subspace. */ subsegT subsegment; }; @@ -411,10 +394,24 @@ struct default_space_dict /* Segment associated with this space. */ asection *segment; - - /* An alias for this section (or NULL if no alias exists). */ - char *alias; }; +#endif + +/* Structure for previous label tracking. Needed so that alignments, + callinfo declarations, etc can be easily attached to a particular + label. */ +typedef struct label_symbol_struct + { + struct symbol *lss_label; +#ifdef OBJ_SOM + sd_chain_struct *lss_space; +#endif +#ifdef OBJ_ELF + segT lss_segment; +#endif + struct label_symbol_struct *lss_next; + } +label_symbol_struct; /* Extra information needed to perform fixups (relocations) on the PA. */ struct hppa_fix_struct @@ -461,7 +458,10 @@ struct selector_entry /* Prototypes for functions local to tc-hppa.c. */ +#ifdef OBJ_SOM static void pa_check_current_space_and_subspace PARAMS ((void)); +#endif + static fp_operand_format pa_parse_fp_format PARAMS ((char **s)); static void pa_cons PARAMS ((int)); static void pa_data PARAMS ((int)); @@ -483,7 +483,6 @@ static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int)); static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int)); static int pa_parse_neg_add_cmpltr PARAMS ((char **, int)); static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int)); -static void pa_align PARAMS ((int)); static void pa_block PARAMS ((int)); static void pa_brtab PARAMS ((int)); static void pa_try PARAMS ((int)); @@ -492,9 +491,6 @@ static void pa_call_args PARAMS ((struct call_desc *)); static void pa_callinfo PARAMS ((int)); static void pa_code PARAMS ((int)); static void pa_comm PARAMS ((int)); -#ifdef OBJ_SOM -static void pa_compiler PARAMS ((int)); -#endif static void pa_copyright PARAMS ((int)); static void pa_end PARAMS ((int)); static void pa_enter PARAMS ((int)); @@ -510,15 +506,18 @@ static void pa_level PARAMS ((int)); static void pa_origin PARAMS ((int)); static void pa_proc PARAMS ((int)); static void pa_procend PARAMS ((int)); -static void pa_space PARAMS ((int)); -static void pa_spnum PARAMS ((int)); -static void pa_subspace PARAMS ((int)); static void pa_param PARAMS ((int)); static void pa_undefine_label PARAMS ((void)); static int need_pa11_opcode PARAMS ((struct pa_it *, struct pa_11_fp_reg_struct *)); static int pa_parse_number PARAMS ((char **, struct pa_11_fp_reg_struct *)); static label_symbol_struct *pa_get_label PARAMS ((void)); +#ifdef OBJ_SOM +static void pa_compiler PARAMS ((int)); +static void pa_align PARAMS ((int)); +static void pa_space PARAMS ((int)); +static void pa_spnum PARAMS ((int)); +static void pa_subspace PARAMS ((int)); static sd_chain_struct *create_new_space PARAMS ((char *, int, int, int, int, int, asection *, int)); @@ -539,6 +538,10 @@ static ssd_chain_struct *pa_subsegment_to_subspace PARAMS ((asection *, subsegT)); static sd_chain_struct *pa_find_space_by_number PARAMS ((int)); static unsigned int pa_subspace_start PARAMS ((sd_chain_struct *, int)); +static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int)); +static int pa_next_subseg PARAMS ((sd_chain_struct *)); +static void pa_spaces_begin PARAMS ((void)); +#endif static void pa_ip PARAMS ((char *)); static void fix_new_hppa PARAMS ((fragS *, int, int, symbolS *, long, expressionS *, int, @@ -550,11 +553,8 @@ static int reg_name_search PARAMS ((char *)); static int pa_chk_field_selector PARAMS ((char **)); static int is_same_frag PARAMS ((fragS *, fragS *)); static void process_exit PARAMS ((void)); -static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int)); static int log2 PARAMS ((int)); -static int pa_next_subseg PARAMS ((sd_chain_struct *)); static unsigned int pa_stringer_aux PARAMS ((char *)); -static void pa_spaces_begin PARAMS ((void)); #ifdef OBJ_ELF static void hppa_elf_mark_end_of_function PARAMS ((void)); @@ -563,6 +563,7 @@ static void pa_build_unwind_subspace PARAMS ((struct call_info *)); /* File and gloally scoped variable declarations. */ +#ifdef OBJ_SOM /* Root and final entry in the space chain. */ static sd_chain_struct *space_dict_root; static sd_chain_struct *space_dict_last; @@ -570,6 +571,7 @@ static sd_chain_struct *space_dict_last; /* The current space and subspace. */ static sd_chain_struct *current_space; static ssd_chain_struct *current_subspace; +#endif /* Root of the call_info chain. */ static struct call_info *call_info_root; @@ -596,7 +598,12 @@ const pseudo_typeS md_pseudo_table[] = { /* align pseudo-ops on the PA specify the actual alignment requested, not the log2 of the requested alignment. */ +#ifdef OBJ_SOM {"align", pa_align, 8}, +#endif +#ifdef OBJ_ELF + {"align", s_align_bytes, 8}, +#endif {"begin_brtab", pa_brtab, 1}, {"begin_try", pa_try, 1}, {"block", pa_block, 1}, @@ -612,6 +619,7 @@ const pseudo_typeS md_pseudo_table[] = {"copyright", pa_copyright, 0}, {"data", pa_data, 0}, {"double", pa_float_cons, 'd'}, + {"dword", pa_cons, 8}, {"end", pa_end, 0}, {"end_brtab", pa_brtab, 0}, {"end_try", pa_try, 0}, @@ -631,7 +639,9 @@ const pseudo_typeS md_pseudo_table[] = {"level", pa_level, 0}, {"long", pa_cons, 4}, {"lsym", pa_lsym, 0}, +#ifdef OBJ_SOM {"nsubspa", pa_subspace, 1}, +#endif {"octa", pa_cons, 16}, {"org", pa_origin, 0}, {"origin", pa_origin, 0}, @@ -642,11 +652,15 @@ const pseudo_typeS md_pseudo_table[] = {"reg", pa_equ, 1}, {"short", pa_cons, 2}, {"single", pa_float_cons, 'f'}, +#ifdef OBJ_SOM {"space", pa_space, 0}, {"spnum", pa_spnum, 0}, +#endif {"string", pa_stringer, 0}, {"stringz", pa_stringer, 1}, +#ifdef OBJ_SOM {"subspa", pa_subspace, 0}, +#endif {"text", pa_text, 0}, {"version", pa_version, 0}, {"word", pa_cons, 4}, @@ -701,9 +715,10 @@ static label_symbol_struct *label_symbols_rootp = NULL; /* Holds the last field selector. */ static int hppa_field_selector; - +#ifdef OBJ_SOM /* A dummy bfd symbol so that all relocations have symbols of some kind. */ static symbolS *dummy_symbol; +#endif /* Nonzero if errors are to be printed. */ static int print_errors = 1; @@ -995,6 +1010,7 @@ static const struct selector_entry selector_table[] = {"t", e_tsel}, }; +#ifdef OBJ_SOM /* default space and subspace dictionaries */ #define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME @@ -1012,31 +1028,23 @@ static const struct selector_entry selector_table[] = static struct default_subspace_dict pa_def_subspaces[] = { - {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE}, - {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, ".data", SUBSEG_DATA}, - {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT}, - {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_MILLI}, - {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, ".bss", SUBSEG_BSS}, -#ifdef OBJ_ELF - {"$UNWIND$", 1, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".PARISC.unwind", SUBSEG_UNWIND}, -#endif + {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE}, + {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA}, + {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT}, + {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI}, + {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS}, {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0} }; static struct default_space_dict pa_def_spaces[] = { - {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL, ".text"}, - {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL, ".data"}, - {NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL} + {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL}, + {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL}, + {NULL, 0, 0, 0, 0, 0, ASEC_NULL} }; /* Misc local definitions used by the assembler. */ -/* Return nonzero if the string pointed to by S potentially represents - a right or left half of a FP register */ -#define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r') -#define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l') - /* These macros are used to maintain spaces/subspaces. */ #define SPACE_DEFINED(space_chain) (space_chain)->sd_defined #define SPACE_USER_DEFINED(space_chain) (space_chain)->sd_user_defined @@ -1045,6 +1053,12 @@ static struct default_space_dict pa_def_spaces[] = #define SUBSPACE_DEFINED(ss_chain) (ss_chain)->ssd_defined #define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name +#endif + +/* Return nonzero if the string pointed to by S potentially represents + a right or left half of a FP register */ +#define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r') +#define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l') /* Insert FIELD into OPCODE starting at bit START. Continue pa_ip main loop after insertion. */ @@ -1071,11 +1085,11 @@ static struct default_space_dict pa_def_spaces[] = #define is_DP_relative(exp) \ ((exp).X_op == O_subtract \ - && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0) + && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0) #define is_PC_relative(exp) \ ((exp).X_op == O_subtract \ - && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0) + && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0) /* We need some complex handling for stabs (sym1 - sym2). Luckily, we'll always be able to reduce the expression to a constant, so we don't @@ -1098,18 +1112,6 @@ pa_check_eof () as_fatal (_("Missing .procend\n")); } -/* Check to make sure we have a valid space and subspace. */ - -static void -pa_check_current_space_and_subspace () -{ - if (current_space == NULL) - as_fatal (_("Not in a space.\n")); - - if (current_subspace == NULL) - as_fatal (_("Not in a subspace.\n")); -} - /* Returns a pointer to the label_symbol_struct for the current space. or NULL if no label_symbol_struct exists for the current space. */ @@ -1117,13 +1119,20 @@ static label_symbol_struct * pa_get_label () { label_symbol_struct *label_chain; - sd_chain_struct *space_chain = current_space; for (label_chain = label_symbols_rootp; label_chain; label_chain = label_chain->lss_next) - if (space_chain == label_chain->lss_space && label_chain->lss_label) + { +#ifdef OBJ_SOM + if (current_space == label_chain->lss_space && label_chain->lss_label) + return label_chain; +#endif +#ifdef OBJ_ELF + if (now_seg == label_chain->lss_segment && label_chain->lss_label) return label_chain; +#endif + } return NULL; } @@ -1136,7 +1145,6 @@ pa_define_label (symbol) symbolS *symbol; { label_symbol_struct *label_chain = pa_get_label (); - sd_chain_struct *space_chain = current_space; if (label_chain) label_chain->lss_label = symbol; @@ -1146,7 +1154,12 @@ pa_define_label (symbol) label_chain = (label_symbol_struct *) xmalloc (sizeof (label_symbol_struct)); label_chain->lss_label = symbol; - label_chain->lss_space = space_chain; +#ifdef OBJ_SOM + label_chain->lss_space = current_space; +#endif +#ifdef OBJ_ELF + label_chain->lss_segment = now_seg; +#endif label_chain->lss_next = NULL; if (label_symbols_rootp) @@ -1164,13 +1177,19 @@ pa_undefine_label () { label_symbol_struct *label_chain; label_symbol_struct *prev_label_chain = NULL; - sd_chain_struct *space_chain = current_space; for (label_chain = label_symbols_rootp; label_chain; label_chain = label_chain->lss_next) { - if (space_chain == label_chain->lss_space && label_chain->lss_label) + if (1 +#ifdef OBJ_SOM + && current_space == label_chain->lss_space && label_chain->lss_label +#endif +#ifdef OBJ_ELF + && now_seg == label_chain->lss_segment && label_chain->lss_label +#endif + ) { /* Remove the label from the chain and free its memory. */ if (prev_label_chain) @@ -1273,7 +1292,7 @@ cons_fix_new_hppa (frag, where, size, exp) fix_new_hppa (frag, where, size, (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type, - hppa_field_selector, 32, 0, NULL); + hppa_field_selector, size * 8, 0, NULL); /* Reset field selector to its default state. */ hppa_field_selector = 0; @@ -1304,7 +1323,9 @@ md_begin () flag_readonly_data_in_text = 0; } +#ifdef OBJ_SOM pa_spaces_begin (); +#endif op_hash = hash_new (); @@ -1334,12 +1355,18 @@ md_begin () if (lose) as_fatal (_("Broken assembler. No assembly attempted.")); +#ifdef OBJ_SOM /* SOM will change text_section. To make sure we never put anything into the old one switch to the new one now. */ subseg_set (text_section, 0); +#endif +#ifdef OBJ_SOM dummy_symbol = symbol_find_or_make ("L$dummy"); S_SET_SEGMENT (dummy_symbol, text_section); + /* Force the symbol to be converted to a real symbol. */ + (void) symbol_get_bfdsym (dummy_symbol); +#endif } /* Assemble a single instruction storing it into a frag. */ @@ -1368,7 +1395,8 @@ md_assemble (str) if (label_symbol->lss_label) { last_call_info->start_symbol = label_symbol->lss_label; - label_symbol->lss_label->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (label_symbol->lss_label)->flags + |= BSF_FUNCTION; #ifdef OBJ_SOM /* Also handle allocation of a fixup to hold the unwind information when the label appears after the proc/procend. */ @@ -1423,8 +1451,16 @@ pa_ip (str) unsigned long opcode; struct pa_opcode *insn; +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif + + /* Convert everything up to the first whitespace character into lower + case. */ + for (s = str; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; s++) + if (isupper (*s)) + *s = tolower (*s); /* Skip to something interesting. */ for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s) @@ -1451,14 +1487,6 @@ pa_ip (str) save_s = str; - /* Convert everything into lower case. */ - while (*save_s) - { - if (isupper (*save_s)) - *save_s = tolower (*save_s); - save_s++; - } - /* Look up the opcode in the has table. */ if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL) { @@ -2730,13 +2758,14 @@ tc_gen_reloc (section, fixp) reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); codes = (bfd_reloc_code_real_type **) hppa_gen_reloc_type (stdoutput, fixp->fx_r_type, hppa_fixp->fx_r_format, hppa_fixp->fx_r_field, fixp->fx_subsy != NULL, - fixp->fx_addsy->bsym); + symbol_get_bfdsym (fixp->fx_addsy)); if (codes == NULL) abort (); @@ -2759,7 +2788,8 @@ tc_gen_reloc (section, fixp) code = *codes[0]; - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->howto = bfd_reloc_type_lookup (stdoutput, code); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->addend = 0; /* default */ @@ -2809,7 +2839,8 @@ tc_gen_reloc (section, fixp) { code = *codes[i]; - relocs[i]->sym_ptr_ptr = &fixp->fx_addsy->bsym; + relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); relocs[i]->howto = bfd_reloc_type_lookup (stdoutput, code); relocs[i]->address = fixp->fx_frag->fr_address + fixp->fx_where; @@ -2820,23 +2851,25 @@ tc_gen_reloc (section, fixp) of two symbols. With that in mind we fill in all four relocs now and break out of the loop. */ assert (i == 1); - relocs[0]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol; + relocs[0]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol); relocs[0]->howto = bfd_reloc_type_lookup (stdoutput, *codes[0]); relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[0]->addend = 0; - relocs[1]->sym_ptr_ptr = &fixp->fx_addsy->bsym; + relocs[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); relocs[1]->howto = bfd_reloc_type_lookup (stdoutput, *codes[1]); relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[1]->addend = 0; - relocs[2]->sym_ptr_ptr = &fixp->fx_subsy->bsym; + relocs[2]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[2]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); relocs[2]->howto = bfd_reloc_type_lookup (stdoutput, *codes[2]); relocs[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[2]->addend = 0; - relocs[3]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol; + relocs[3]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol); relocs[3]->howto = bfd_reloc_type_lookup (stdoutput, *codes[3]); relocs[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[3]->addend = 0; - relocs[4]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol; + relocs[4]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol); relocs[4]->howto = bfd_reloc_type_lookup (stdoutput, *codes[4]); relocs[4]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[4]->addend = 0; @@ -2874,7 +2907,8 @@ tc_gen_reloc (section, fixp) case R_N0SEL: case R_N1SEL: /* There is no symbol or addend associated with these fixups. */ - relocs[i]->sym_ptr_ptr = &dummy_symbol->bsym; + relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); relocs[i]->addend = 0; break; @@ -2882,7 +2916,8 @@ tc_gen_reloc (section, fixp) case R_ENTRY: case R_EXIT: /* There is no symbol associated with these fixups. */ - relocs[i]->sym_ptr_ptr = &dummy_symbol->bsym; + relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); relocs[i]->addend = fixp->fx_offset; break; @@ -3039,7 +3074,7 @@ md_apply_fix (fixP, valp) && fmt != 32 #endif ) - new_val = ((fmt == 12 || fmt == 17) ? 8 : 0); + new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0); #ifdef OBJ_SOM /* These field selectors imply that we do not want an addend. */ else if (hppa_fixP->fx_r_field == e_psel @@ -3048,7 +3083,7 @@ md_apply_fix (fixP, valp) || hppa_fixP->fx_r_field == e_tsel || hppa_fixP->fx_r_field == e_rtsel || hppa_fixP->fx_r_field == e_ltsel) - new_val = ((fmt == 12 || fmt == 17) ? 8 : 0); + new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0); /* This is truely disgusting. The machine independent code blindly adds in the value of the symbol being relocated against. Damn! */ else if (fmt == 32 @@ -3063,13 +3098,15 @@ md_apply_fix (fixP, valp) /* Handle pc-relative exceptions from above. */ #define arg_reloc_stub_needed(CALLER, CALLEE) \ ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) - if ((fmt == 12 || fmt == 17) + if ((fmt == 12 || fmt == 17 || fmt == 22) && fixP->fx_addsy && fixP->fx_pcrel +#ifdef OBJ_SOM && !arg_reloc_stub_needed ((long) ((obj_symbol_type *) - fixP->fx_addsy->bsym)->tc_data.ap.hppa_arg_reloc, - hppa_fixP->fx_arg_reloc) - && ((int)(*valp) > -262144 && (int)(*valp) < 262143) + symbol_get_bfdsym (fixP->fx_addsy))->tc_data.ap.hppa_arg_reloc, + hppa_fixP->fx_arg_reloc) +#endif + && (((int)(*valp) > -262144 && (int)(*valp) < 262143) && fmt != 22) && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment && !(fixP->fx_subsy && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment)) @@ -4144,6 +4181,7 @@ pa_parse_neg_add_cmpltr (s, isbranch) return cmpltr; } +#ifdef OBJ_SOM /* Handle an alignment directive. Special so that we can update the alignment of the subspace if necessary. */ static void @@ -4160,6 +4198,7 @@ pa_align (bytes) if (log2 (bytes) != -1) record_alignment (current_subspace->ssd_seg, log2 (bytes)); } +#endif /* Handle a .BLOCK type pseudo-op. */ @@ -4172,8 +4211,10 @@ pa_block (z) unsigned int temp_size; unsigned int i; +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif temp_size = get_absolute_expression (); @@ -4251,8 +4292,10 @@ static void pa_call (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif pa_call_args (&last_call_desc); demand_empty_rest_of_line (); @@ -4336,6 +4379,7 @@ static void pa_build_unwind_subspace (call_info) struct call_info *call_info; { +#if 0 char *unwind; asection *seg, *save_seg; subsegT subseg, save_subseg; @@ -4397,6 +4441,7 @@ pa_build_unwind_subspace (call_info) /* Return back to the original segment/subsegment. */ subseg_set (save_seg, save_subseg); +#endif } #endif @@ -4411,8 +4456,10 @@ pa_callinfo (unused) char *name, c, *p; int temp; +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif /* .CALLINFO must appear within a procedure definition. */ if (!within_procedure) @@ -4549,9 +4596,11 @@ static void pa_code (unused) int unused; { +#ifdef OBJ_SOM current_space = is_defined_space ("$TEXT$"); current_subspace = pa_subsegment_to_subspace (current_space->sd_seg, 0); +#endif s_text (0); pa_undefine_label (); } @@ -4601,7 +4650,7 @@ pa_comm (unused) /* colon() has already set the frag to the current location in the current subspace; we need to reset the fragment to the zero address fragment. We also need to reset the segment pointer. */ - symbol->sy_frag = &zero_address_frag; + symbol_set_frag (symbol, &zero_address_frag); } demand_empty_rest_of_line (); } @@ -4620,8 +4669,10 @@ static void pa_enter (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif as_bad (_("The .ENTER pseudo-op is not supported")); demand_empty_rest_of_line (); @@ -4633,8 +4684,10 @@ static void pa_entry (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif if (!within_procedure) as_bad (_("Misplaced .entry. Ignored.")); @@ -4738,8 +4791,10 @@ static void pa_exit (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif if (!within_procedure) as_bad (_(".EXIT must appear within a procedure")); @@ -4808,13 +4863,13 @@ pa_type_args (symbolP, is_export) char *name, c, *p; unsigned int temp, arg_reloc; pa_symbol_type type = SYMBOL_TYPE_UNKNOWN; - obj_symbol_type *symbol = (obj_symbol_type *) symbolP->bsym; + obj_symbol_type *symbol = (obj_symbol_type *) symbol_get_bfdsym (symbolP); if (strncasecmp (input_line_pointer, "absolute", 8) == 0) { input_line_pointer += 8; - symbolP->bsym->flags &= ~BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags &= ~BSF_FUNCTION; S_SET_SEGMENT (symbolP, bfd_abs_section_ptr); type = SYMBOL_TYPE_ABSOLUTE; } @@ -4827,54 +4882,55 @@ pa_type_args (symbolP, is_export) Complain if one tries to EXPORT a CODE type since that's never done. Both GCC and HP C still try to IMPORT CODE types, so silently fix them to be ENTRY types. */ - if (symbolP->bsym->flags & BSF_FUNCTION) + if (S_IS_FUNCTION (symbolP)) { if (is_export) - as_tsktsk (_("Using ENTRY rather than CODE in export directive for %s"), symbolP->bsym->name); + as_tsktsk (_("Using ENTRY rather than CODE in export directive for %s"), + S_GET_NAME (symbolP)); - symbolP->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; type = SYMBOL_TYPE_ENTRY; } else { - symbolP->bsym->flags &= ~BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags &= ~BSF_FUNCTION; type = SYMBOL_TYPE_CODE; } } else if (strncasecmp (input_line_pointer, "data", 4) == 0) { input_line_pointer += 4; - symbolP->bsym->flags &= ~BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags &= ~BSF_FUNCTION; type = SYMBOL_TYPE_DATA; } else if ((strncasecmp (input_line_pointer, "entry", 5) == 0)) { input_line_pointer += 5; - symbolP->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; type = SYMBOL_TYPE_ENTRY; } else if (strncasecmp (input_line_pointer, "millicode", 9) == 0) { input_line_pointer += 9; - symbolP->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; type = SYMBOL_TYPE_MILLICODE; } else if (strncasecmp (input_line_pointer, "plabel", 6) == 0) { input_line_pointer += 6; - symbolP->bsym->flags &= ~BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags &= ~BSF_FUNCTION; type = SYMBOL_TYPE_PLABEL; } else if (strncasecmp (input_line_pointer, "pri_prog", 8) == 0) { input_line_pointer += 8; - symbolP->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; type = SYMBOL_TYPE_PRI_PROG; } else if (strncasecmp (input_line_pointer, "sec_prog", 8) == 0) { input_line_pointer += 8; - symbolP->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; type = SYMBOL_TYPE_SEC_PROG; } @@ -4882,7 +4938,7 @@ pa_type_args (symbolP, is_export) than BFD understands. This is how we get this information to the SOM BFD backend. */ #ifdef obj_set_symbol_type - obj_set_symbol_type (symbolP->bsym, (int) type); + obj_set_symbol_type (symbol_get_bfdsym (symbolP), (int) type); #endif /* Now that the type of the exported symbol has been handled, @@ -4903,7 +4959,9 @@ pa_type_args (symbolP, is_export) name = input_line_pointer; c = get_symbol_end (); arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name)); +#ifdef OBJ_SOM symbol->tc_data.ap.hppa_arg_reloc |= arg_reloc; +#endif *input_line_pointer = c; } /* The return value. */ @@ -4915,7 +4973,9 @@ pa_type_args (symbolP, is_export) name = input_line_pointer; c = get_symbol_end (); arg_reloc = pa_build_arg_reloc (name); +#ifdef OBJ_SOM symbol->tc_data.ap.hppa_arg_reloc |= arg_reloc; +#endif *input_line_pointer = c; } /* Privelege level. */ @@ -4925,7 +4985,9 @@ pa_type_args (symbolP, is_export) *p = c; input_line_pointer++; temp = atoi (input_line_pointer); +#ifdef OBJ_SOM symbol->tc_data.ap.hppa_priv_level = temp; +#endif c = get_symbol_end (); *input_line_pointer = c; } @@ -4976,7 +5038,7 @@ pa_import (unused) the the current segment. Note only BSF_FUNCTION really matters, we do not need to set the full SYMBOL_TYPE_* info. */ if (now_seg == text_section) - symbol->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION; /* If the section is undefined, then the symbol is undefined Since this is an import, leave the section undefined. */ @@ -5030,8 +5092,10 @@ static void pa_leave (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif as_bad (_("The .LEAVE pseudo-op is not supported")); demand_empty_rest_of_line (); @@ -5078,8 +5142,10 @@ static void pa_origin (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif s_org (0); pa_undefine_label (); @@ -5129,8 +5195,10 @@ pa_proc (unused) { struct call_info *call_info; +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif if (within_procedure) as_fatal (_("Nested procedures")); @@ -5176,7 +5244,7 @@ pa_proc (unused) if (label_symbol->lss_label) { last_call_info->start_symbol = label_symbol->lss_label; - label_symbol->lss_label->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (label_symbol->lss_label)->flags |= BSF_FUNCTION; } else as_bad (_("Missing function name for .PROC (corrupted label chain)")); @@ -5196,8 +5264,10 @@ pa_procend (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif /* If we are within a procedure definition, make sure we've defined a label for the procedure; handle case where the @@ -5215,7 +5285,8 @@ pa_procend (unused) if (label_symbol->lss_label) { last_call_info->start_symbol = label_symbol->lss_label; - label_symbol->lss_label->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (label_symbol->lss_label)->flags + |= BSF_FUNCTION; #ifdef OBJ_SOM /* Also handle allocation of a fixup to hold the unwind information when the label appears after the proc/procend. */ @@ -5257,6 +5328,38 @@ pa_procend (unused) pa_undefine_label (); } +/* If VALUE is an exact power of two between zero and 2^31, then + return log2 (VALUE). Else return -1. */ + +static int +log2 (value) + int value; +{ + int shift = 0; + + while ((1 << shift) != value && shift < 32) + shift++; + + if (shift >= 32) + return -1; + else + return shift; +} + + +#ifdef OBJ_SOM +/* Check to make sure we have a valid space and subspace. */ + +static void +pa_check_current_space_and_subspace () +{ + if (current_space == NULL) + as_fatal (_("Not in a space.\n")); + + if (current_subspace == NULL) + as_fatal (_("Not in a subspace.\n")); +} + /* Parse the parameters to a .SPACE directive; if CREATE_FLAG is nonzero, then create a new space entry to hold the information specified by the parameters to the .SPACE directive. */ @@ -5525,24 +5628,6 @@ pa_spnum (unused) demand_empty_rest_of_line (); } -/* If VALUE is an exact power of two between zero and 2^31, then - return log2 (VALUE). Else return -1. */ - -static int -log2 (value) - int value; -{ - int shift = 0; - - while ((1 << shift) != value && shift < 32) - shift++; - - if (shift >= 32) - return -1; - else - return shift; -} - /* Handle a .SUBSPACE pseudo-op; this switches the current subspace to the given subspace, creating the new subspace if necessary. @@ -5553,7 +5638,7 @@ static void pa_subspace (create_new) int create_new; { - char *name, *ss_name, *alias, c; + char *name, *ss_name, c; char loadable, code_only, common, dup_common, zero, sort; int i, access, space_index, alignment, quadrant, applicable, flags; sd_chain_struct *space; @@ -5587,7 +5672,6 @@ pa_subspace (create_new) space_index = ~0; alignment = 1; quadrant = 0; - alias = NULL; space = current_space; if (create_new) @@ -5624,8 +5708,6 @@ pa_subspace (create_new) quadrant = pa_def_subspaces[i].quadrant; access = pa_def_subspaces[i].access; sort = pa_def_subspaces[i].sort; - if (USE_ALIASES && pa_def_subspaces[i].alias) - alias = pa_def_subspaces[i].alias; break; } i++; @@ -5734,14 +5816,6 @@ pa_subspace (create_new) section = subseg_force_new (ss_name, 0); else if (ssd) section = ssd->ssd_seg; - else if (alias) - section = subseg_new (alias, 0); - else if (!alias && USE_ALIASES) - { - as_warn (_("Ignoring subspace decl due to ELF BFD bugs.")); - demand_empty_rest_of_line (); - return; - } else section = subseg_new (ss_name, 0); @@ -5798,10 +5872,7 @@ pa_spaces_begin () char *name; /* Pick the right name to use for the new section. */ - if (pa_def_spaces[i].alias && USE_ALIASES) - name = pa_def_spaces[i].alias; - else - name = pa_def_spaces[i].name; + name = pa_def_spaces[i].name; pa_def_spaces[i].segment = subseg_new (name, 0); create_new_space (pa_def_spaces[i].name, pa_def_spaces[i].spnum, @@ -5821,16 +5892,8 @@ pa_spaces_begin () /* Pick the right name for the new section and pick the right subsegment number. */ - if (pa_def_subspaces[i].alias && USE_ALIASES) - { - name = pa_def_subspaces[i].alias; - subsegment = pa_def_subspaces[i].subsegment; - } - else - { - name = pa_def_subspaces[i].name; - subsegment = 0; - } + name = pa_def_subspaces[i].name; + subsegment = 0; /* Create the new section. */ segment = subseg_new (name, subsegment); @@ -5839,7 +5902,7 @@ pa_spaces_begin () /* For SOM we want to replace the standard .text, .data, and .bss sections with our own. We also want to set BFD flags for all the built-in subspaces. */ - if (!strcmp (pa_def_subspaces[i].name, "$CODE$") && !USE_ALIASES) + if (!strcmp (pa_def_subspaces[i].name, "$CODE$")) { text_section = segment; applicable = bfd_applicable_section_flags (stdoutput); @@ -5849,7 +5912,7 @@ pa_spaces_begin () | SEC_READONLY | SEC_HAS_CONTENTS)); } - else if (!strcmp (pa_def_subspaces[i].name, "$DATA$") && !USE_ALIASES) + else if (!strcmp (pa_def_subspaces[i].name, "$DATA$")) { data_section = segment; applicable = bfd_applicable_section_flags (stdoutput); @@ -5860,14 +5923,14 @@ pa_spaces_begin () } - else if (!strcmp (pa_def_subspaces[i].name, "$BSS$") && !USE_ALIASES) + else if (!strcmp (pa_def_subspaces[i].name, "$BSS$")) { bss_section = segment; applicable = bfd_applicable_section_flags (stdoutput); bfd_set_section_flags (stdoutput, segment, applicable & SEC_ALLOC); } - else if (!strcmp (pa_def_subspaces[i].name, "$LIT$") && !USE_ALIASES) + else if (!strcmp (pa_def_subspaces[i].name, "$LIT$")) { applicable = bfd_applicable_section_flags (stdoutput); bfd_set_section_flags (stdoutput, segment, @@ -5876,8 +5939,7 @@ pa_spaces_begin () | SEC_READONLY | SEC_HAS_CONTENTS)); } - else if (!strcmp (pa_def_subspaces[i].name, "$MILLICODE$") - && !USE_ALIASES) + else if (!strcmp (pa_def_subspaces[i].name, "$MILLICODE$")) { applicable = bfd_applicable_section_flags (stdoutput); bfd_set_section_flags (stdoutput, segment, @@ -5886,7 +5948,7 @@ pa_spaces_begin () | SEC_READONLY | SEC_HAS_CONTENTS)); } - else if (!strcmp (pa_def_subspaces[i].name, "$UNWIND$") && !USE_ALIASES) + else if (!strcmp (pa_def_subspaces[i].name, "$UNWIND$")) { applicable = bfd_applicable_section_flags (stdoutput); bfd_set_section_flags (stdoutput, segment, @@ -6037,7 +6099,7 @@ create_new_subspace (space, name, loadable, code_only, common, we'll set it to 1 which "locks-in" the subspace attributes. */ SUBSPACE_DEFINED (chain_entry) = 0; - chain_entry->ssd_subseg = USE_ALIASES ? pa_next_subseg (space) : 0; + chain_entry->ssd_subseg = 0; chain_entry->ssd_seg = seg; chain_entry->ssd_next = NULL; @@ -6256,7 +6318,6 @@ pa_subspace_start (space, quadrant) sd_chain_struct *space; int quadrant; { -#ifdef OBJ_SOM /* FIXME. Assumes everyone puts read/write data at 0x4000000, this is not correct for the PA OSF1 port. */ if ((strcmp (SPACE_NAME (space), "$PRIVATE$") == 0) && quadrant == 1) @@ -6265,7 +6326,6 @@ pa_subspace_start (space, quadrant) return 0x40000000; else return 0; -#endif return 0; } @@ -6278,6 +6338,7 @@ pa_next_subseg (space) space->sd_last_subseg++; return space->sd_last_subseg; } +#endif /* Helper function for pa_stringer. Used to find the end of a string. */ @@ -6288,8 +6349,10 @@ pa_stringer_aux (s) { unsigned int c = *s & CHAR_MASK; +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif switch (c) { @@ -6430,9 +6493,11 @@ static void pa_data (unused) int unused; { +#ifdef OBJ_SOM current_space = is_defined_space ("$PRIVATE$"); current_subspace = pa_subsegment_to_subspace (current_space->sd_seg, 0); +#endif s_data (0); pa_undefine_label (); } @@ -6453,8 +6518,10 @@ static void pa_fill (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif s_fill (0); pa_undefine_label (); @@ -6466,8 +6533,10 @@ static void pa_lcomm (needs_align) int needs_align; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif s_lcomm (needs_align); pa_undefine_label (); @@ -6479,8 +6548,10 @@ static void pa_lsym (unused) int unused; { +#ifdef OBJ_SOM /* We must have a valid space and subspace. */ pa_check_current_space_and_subspace (); +#endif s_lsym (0); pa_undefine_label (); @@ -6492,9 +6563,11 @@ static void pa_text (unused) int unused; { +#ifdef OBJ_SOM current_space = is_defined_space ("$TEXT$"); current_subspace = pa_subsegment_to_subspace (current_space->sd_seg, 0); +#endif s_text (0); pa_undefine_label (); @@ -6549,7 +6622,7 @@ hppa_fix_adjustable (fixp) && (hppa_fix->segment->flags & SEC_CODE)) { /* Apparently sy_used_in_reloc never gets set for sub symbols. */ - fixp->fx_subsy->sy_used_in_reloc = 1; + symbol_mark_used_in_reloc (fixp->fx_subsy); return 0; } @@ -6571,7 +6644,7 @@ hppa_fix_adjustable (fixp) || hppa_fix->fx_r_field == e_lpsel) return 0; - if (fixp->fx_addsy && fixp->fx_addsy->bsym->flags & BSF_GLOBAL) + if (fixp->fx_addsy && S_IS_EXTERNAL (fixp->fx_addsy)) return 0; /* Reject absolute calls (jumps). */ @@ -6579,8 +6652,7 @@ hppa_fix_adjustable (fixp) return 0; /* Reject reductions of function symbols. */ - if (fixp->fx_addsy == 0 - || (fixp->fx_addsy->bsym->flags & BSF_FUNCTION) == 0) + if (fixp->fx_addsy == 0 || ! S_IS_FUNCTION (fixp->fx_addsy)) return 1; return 0; @@ -6612,15 +6684,16 @@ hppa_force_relocation (fixp) #define arg_reloc_stub_needed(CALLER, CALLEE) \ ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) +#ifdef OBJ_SOM /* It is necessary to force PC-relative calls/jumps to have a relocation entry if they're going to need either a argument relocation or long call stub. FIXME. Can't we need the same for absolute calls? */ if (fixp->fx_pcrel && fixp->fx_addsy && (arg_reloc_stub_needed ((long) ((obj_symbol_type *) - fixp->fx_addsy->bsym)->tc_data.ap.hppa_arg_reloc, - - hppa_fixp->fx_arg_reloc))) + symbol_get_bfdsym (fixp->fx_addsy))->tc_data.ap.hppa_arg_reloc, + hppa_fixp->fx_arg_reloc))) return 1; +#endif distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy) - md_pcrel_from (fixp)); /* Now check and see if we're going to need a long-branch stub. */ @@ -6677,7 +6750,7 @@ hppa_elf_mark_end_of_function () frag_now); assert (symbolP); - symbolP->bsym->flags = BSF_LOCAL; + S_CLEAR_EXTERNAL (symbolP); symbol_table_insert (symbolP); } @@ -6707,7 +6780,8 @@ elf_hppa_final_processing () call_info_pointer = call_info_pointer->ci_next) { elf_symbol_type *esym - = (elf_symbol_type *) call_info_pointer->start_symbol->bsym; + = ((elf_symbol_type *) + symbol_get_bfdsym (call_info_pointer->start_symbol)); esym->internal_elf_sym.st_size = S_GET_VALUE (call_info_pointer->end_symbol) - S_GET_VALUE (call_info_pointer->start_symbol) + 4; diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index c1541d9..13e10da 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -1,5 +1,6 @@ /* tc-hppa.h -- Header file for the PA - Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -48,9 +49,14 @@ /* FIXME. The lack of a place to put things which are both target cpu and target format dependent makes hacks like this necessary. */ #ifdef OBJ_ELF +#ifdef BFD64 +#include "bfd/elf64-hppa.h" +#define TARGET_FORMAT "elf64-hppa" +#else #include "bfd/elf32-hppa.h" #define TARGET_FORMAT "elf32-hppa" #endif +#endif #ifdef OBJ_SOM #include "bfd/som.h" @@ -128,9 +134,9 @@ void elf_hppa_final_processing PARAMS ((void)); *not* end up in the symbol table. Likewise for absolute symbols with local scope. */ #define tc_frob_symbol(sym,punt) \ - if ((S_GET_SEGMENT (sym) == &bfd_und_section && sym->sy_used == 0) \ + if ((S_GET_SEGMENT (sym) == &bfd_und_section && ! symbol_used_p (sym)) \ || (S_GET_SEGMENT (sym) == &bfd_abs_section \ - && (sym->bsym->flags & BSF_EXPORT) == 0)) \ + && ! S_IS_EXTERNAL (sym))) \ punt = 1 /* We need to be able to make relocations involving the difference of @@ -147,9 +153,10 @@ void elf_hppa_final_processing PARAMS ((void)); #ifdef OBJ_ELF #define tc_frob_symbol(sym,punt) \ { \ - if ((S_GET_SEGMENT (sym) == &bfd_und_section && sym->sy_used == 0) \ + if ((S_GET_SEGMENT (sym) == &bfd_und_section && ! symbol_used_p (sym)) \ || (S_GET_SEGMENT (sym) == &bfd_abs_section \ - && (sym->bsym->flags & BSF_EXPORT) == 0)) \ + && ! S_IS_EXTERNAL (sym)) \ + || strcmp (S_GET_NAME (sym), "$global$") == 0) \ punt = 1; \ } #endif diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 7149d71..30c9abf 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -740,7 +740,7 @@ pi (line, x) pt (x->types[i]); fprintf (stdout, "\n"); if (x->types[i] - & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX)) + & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX | RegXMM)) fprintf (stdout, "%s\n", x->regs[i]->reg_name); if (x->types[i] & Imm) pe (x->imms[i]); @@ -835,6 +835,7 @@ type_names[] = { Acc, "Acc" }, { JumpAbsolute, "Jump Absolute" }, { RegMMX, "rMMX" }, + { RegXMM, "rXMM" }, { EsSeg, "es" }, { 0, "" } }; @@ -948,7 +949,10 @@ tc_i386_fix_adjustable(fixP) #define BFD_RELOC_386_GOTOFF 0 #endif -int +static int +intel_float_operand PARAMS ((char *mnemonic)); + +static int intel_float_operand (mnemonic) char *mnemonic; { @@ -1244,7 +1248,6 @@ md_assemble (line) { register unsigned int overlap0, overlap1; - expressionS *exp; unsigned int overlap2; unsigned int found_reverse_match; int suffix_check; @@ -1256,11 +1259,12 @@ md_assemble (line) && (strncmp (mnemonic, "fsub", 4) !=0) && (strncmp (mnemonic, "fdiv", 4) !=0)) { - const reg_entry *temp_reg; - expressionS *temp_disp; - expressionS *temp_imm; + const reg_entry *temp_reg = NULL; + expressionS *temp_disp = NULL; + expressionS *temp_imm = NULL; unsigned int temp_type; - int xchg1, xchg2; + int xchg1 = 0; + int xchg2 = 0; if (i.operands == 2) { @@ -1552,8 +1556,10 @@ md_assemble (line) continue; } /* Any other register is bad */ - if (i.types[op] & (Reg | RegMMX | Control | Debug | Test - | FloatReg | FloatAcc | SReg2 | SReg3)) + if (i.types[op] & (Reg | RegMMX | RegXMM + | SReg2 | SReg3 + | Control | Debug | Test + | FloatReg | FloatAcc)) { as_bad (_("`%%%s' not allowed with `%s%c'"), i.regs[op]->reg_name, @@ -1740,12 +1746,12 @@ md_assemble (line) } } - if (i.tm.base_opcode == AMD_3DNOW_OPCODE) + if (i.tm.opcode_modifier & ImmExt) { - /* These AMD specific instructions have an opcode suffix which - is coded in the same place as an 8-bit immediate field - would be. Here we fake an 8-bit immediate operand from the - opcode suffix stored in tm.extension_opcode. */ + /* These AMD 3DNow! and Intel Katmai New Instructions have an + opcode suffix which is coded in the same place as an 8-bit + immediate field would be. Here we fake an 8-bit immediate + operand from the opcode suffix stored in tm.extension_opcode. */ expressionS *exp; @@ -1822,37 +1828,21 @@ md_assemble (line) { unsigned int source, dest; source = ((i.types[0] - & (Reg - | SReg2 - | SReg3 - | Control - | Debug - | Test - | RegMMX)) + & (Reg | RegMMX | RegXMM + | SReg2 | SReg3 + | Control | Debug | Test)) ? 0 : 1); dest = source + 1; - /* Certain instructions expect the destination to be - in the i.rm.reg field. This is by far the - exceptional case. For these instructions, if the - source operand is a register, we must reverse the - i.rm.reg and i.rm.regmem fields. We accomplish - this by pretending that the two register operands - were given in the reverse order. */ - if (i.tm.opcode_modifier & ReverseRegRegmem) - { - const reg_entry *tmp = i.regs[source]; - i.regs[source] = i.regs[dest]; - i.regs[dest] = tmp; - } - i.rm.mode = 3; - /* We must be careful to make sure that all - segment/control/test/debug/MMX registers go into - the i.rm.reg field (despite whether they are - source or destination operands). */ - if (i.regs[dest]->reg_type - & (SReg2 | SReg3 | Control | Debug | Test | RegMMX)) + /* One of the register operands will be encoded in the + i.tm.reg field, the other in the combined i.tm.mode + and i.tm.regmem fields. If no form of this + instruction supports a memory destination operand, + then we assume the source operand may sometimes be + a memory operand and so we need to store the + destination in the i.rm.reg field. */ + if ((i.tm.operand_types[dest] & AnyMem) == 0) { i.rm.reg = i.regs[dest]->reg_num; i.rm.regmem = i.regs[source]->reg_num; @@ -1981,6 +1971,8 @@ md_assemble (line) { /* Fakes a zero displacement assuming that i.types[op] holds the correct displacement size. */ + expressionS *exp; + exp = &disp_expressions[i.disp_operands++]; i.disps[op] = exp; exp->X_op = O_constant; @@ -1999,12 +1991,14 @@ md_assemble (line) { unsigned int op = ((i.types[0] - & (Reg | SReg2 | SReg3 | Control | Debug - | Test | RegMMX)) + & (Reg | RegMMX | RegXMM + | SReg2 | SReg3 + | Control | Debug | Test)) ? 0 : ((i.types[1] - & (Reg | SReg2 | SReg3 | Control | Debug - | Test | RegMMX)) + & (Reg | RegMMX | RegXMM + | SReg2 | SReg3 + | Control | Debug | Test)) ? 1 : 2)); /* If there is an extension opcode to put here, the @@ -2369,30 +2363,28 @@ md_assemble (line) { if (i.disps[n]->X_op == O_constant) { - if (i.types[n] & Disp8) - { - insn_size += 1; - p = frag_more (1); - md_number_to_chars (p, - (valueT) i.disps[n]->X_add_number, - 1); - } - else if (i.types[n] & Disp16) + int size = 4; + long val = (long) i.disps[n]->X_add_number; + + if (i.types[n] & (Disp8 | Disp16)) { - insn_size += 2; - p = frag_more (2); - md_number_to_chars (p, - (valueT) i.disps[n]->X_add_number, - 2); - } - else - { /* Disp32 */ - insn_size += 4; - p = frag_more (4); - md_number_to_chars (p, - (valueT) i.disps[n]->X_add_number, - 4); + long mask; + + size = 2; + mask = ~ (long) 0xffff; + if (i.types[n] & Disp8) + { + size = 1; + mask = ~ (long) 0xff; + } + + if ((val & mask) != 0 && (val & mask) != mask) + as_warn (_("%ld shortened to %ld"), + val, val & ~mask); } + insn_size += size; + p = frag_more (size); + md_number_to_chars (p, (valueT) val, size); } else if (i.types[n] & Disp32) { @@ -2425,30 +2417,27 @@ md_assemble (line) { if (i.imms[n]->X_op == O_constant) { - if (i.types[n] & (Imm8 | Imm8S)) - { - insn_size += 1; - p = frag_more (1); - md_number_to_chars (p, - (valueT) i.imms[n]->X_add_number, - 1); - } - else if (i.types[n] & Imm16) - { - insn_size += 2; - p = frag_more (2); - md_number_to_chars (p, - (valueT) i.imms[n]->X_add_number, - 2); - } - else + int size = 4; + long val = (long) i.imms[n]->X_add_number; + + if (i.types[n] & (Imm8 | Imm8S | Imm16)) { - insn_size += 4; - p = frag_more (4); - md_number_to_chars (p, - (valueT) i.imms[n]->X_add_number, - 4); + long mask; + + size = 2; + mask = ~ (long) 0xffff; + if (i.types[n] & (Imm8 | Imm8S)) + { + size = 1; + mask = ~ (long) 0xff; + } + if ((val & mask) != 0 && (val & mask) != mask) + as_warn (_("%ld shortened to %ld"), + val, val & ~mask); } + insn_size += size; + p = frag_more (size); + md_number_to_chars (p, (valueT) val, size); } else { /* not absolute_section */ @@ -2474,7 +2463,8 @@ md_assemble (line) && GOT_symbol == i.imms[n]->X_add_symbol && (i.imms[n]->X_op == O_symbol || (i.imms[n]->X_op == O_add - && (i.imms[n]->X_op_symbol->sy_value.X_op + && ((symbol_get_value_expression + (i.imms[n]->X_op_symbol)->X_op) == O_subtract)))) { r_type = BFD_RELOC_386_GOTPC; @@ -2561,7 +2551,8 @@ i386_immediate (imm_start) if (cp != NULL) { char *tmpbuf; - int len, first; + int len = 0; + int first; /* GOT relocations are not supported in 16 bit mode */ if (flag_16bit_code) @@ -2602,6 +2593,7 @@ i386_immediate (imm_start) exp_seg = expression (exp); + SKIP_WHITESPACE (); if (*input_line_pointer) as_bad (_("Ignoring junk `%s' after expression"), input_line_pointer); @@ -2620,9 +2612,13 @@ i386_immediate (imm_start) } else if (exp->X_op == O_constant) { + int bigimm = Imm32; + if (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0)) + bigimm = Imm16; + i.types[this_operand] |= - smallest_imm_type ((long) exp->X_add_number); - + (bigimm | smallest_imm_type ((long) exp->X_add_number)); + /* If a suffix is given, this operand may be shortended. */ switch (i.suffix) { @@ -2644,7 +2640,6 @@ i386_immediate (imm_start) #endif ) { - seg_unimplemented: as_bad (_("Unimplemented segment type %d in operand"), exp_seg); return 0; } @@ -2790,7 +2785,8 @@ i386_displacement (disp_start, disp_end) if (cp != NULL) { char *tmpbuf; - int len, first; + int len = 0; + int first; /* GOT relocations are not supported in 16 bit mode */ if (flag_16bit_code) @@ -2839,7 +2835,7 @@ i386_displacement (disp_start, disp_end) { if (S_IS_LOCAL(exp->X_add_symbol) && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section) - section_symbol(exp->X_add_symbol->bsym->section); + section_symbol (S_GET_SEGMENT (exp->X_add_symbol)); assert (exp->X_op == O_symbol); exp->X_op = O_subtract; exp->X_op_symbol = GOT_symbol; @@ -2847,6 +2843,7 @@ i386_displacement (disp_start, disp_end) } #endif + SKIP_WHITESPACE (); if (*input_line_pointer) as_bad (_("Ignoring junk `%s' after expression"), input_line_pointer); @@ -3456,6 +3453,11 @@ i386_operand (operand_string) else if (*op_string == IMMEDIATE_PREFIX) { /* ... or an immediate */ ++op_string; + if (i.types[this_operand] & JumpAbsolute) + { + as_bad (_("Immediate operand illegal with absolute jump")); + return 0; + } if (!i386_immediate (op_string)) return 0; } @@ -3469,8 +3471,8 @@ i386_operand (operand_string) int found_base_index_form; /* Start and end of displacement string expression (if found). */ - char *displacement_string_start; - char *displacement_string_end; + char *displacement_string_start = NULL; + char *displacement_string_end = NULL; do_memory_reference: @@ -3781,8 +3783,8 @@ md_convert_frag (headers, sec, fragP) #else void md_convert_frag (abfd, sec, fragP) - bfd *abfd; - segT sec; + bfd *abfd ATTRIBUTE_UNUSED; + segT sec ATTRIBUTE_UNUSED; register fragS *fragP; #endif { @@ -3798,7 +3800,7 @@ md_convert_frag (abfd, sec, fragP) /* Address we want to reach in file space. */ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; #ifdef BFD_ASSEMBLER /* not needed otherwise? */ - target_address += fragP->fr_symbol->sy_frag->fr_address; + target_address += symbol_get_frag (fragP->fr_symbol)->fr_address; #endif /* Address opcode resides at in file space. */ @@ -3864,8 +3866,8 @@ void md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) char *ptr; addressT from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; + fragS *frag ATTRIBUTE_UNUSED; + symbolS *to_symbol ATTRIBUTE_UNUSED; { long offset; @@ -3915,15 +3917,34 @@ md_apply_fix3 (fixP, valp, seg) register char *p = fixP->fx_where + fixP->fx_frag->fr_literal; valueT value = *valp; - if (fixP->fx_r_type == BFD_RELOC_32 && fixP->fx_pcrel) - fixP->fx_r_type = BFD_RELOC_32_PCREL; - #if defined (BFD_ASSEMBLER) && !defined (TE_Mach) + if (fixP->fx_pcrel) + { + switch (fixP->fx_r_type) + { + default: + break; + + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_32_PCREL; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_16_PCREL; + break; + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_8_PCREL; + break; + } + } + /* * This is a hack. There should be a better way to * handle this. */ - if (fixP->fx_r_type == BFD_RELOC_32_PCREL && fixP->fx_addsy) + if ((fixP->fx_r_type == BFD_RELOC_32_PCREL + || fixP->fx_r_type == BFD_RELOC_16_PCREL + || fixP->fx_r_type == BFD_RELOC_8_PCREL) + && fixP->fx_addsy) { #ifndef OBJ_AOUT if (OUTPUT_FLAVOR == bfd_target_elf_flavour @@ -3936,7 +3957,7 @@ md_apply_fix3 (fixP, valp, seg) #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) if (OUTPUT_FLAVOR == bfd_target_elf_flavour && (S_GET_SEGMENT (fixP->fx_addsy) == seg - || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0) + || symbol_section_p (fixP->fx_addsy)) && ! S_IS_EXTERNAL (fixP->fx_addsy) && ! S_IS_WEAK (fixP->fx_addsy) && S_IS_DEFINED (fixP->fx_addsy) @@ -4023,9 +4044,9 @@ md_apply_fix3 (fixP, valp, seg) default: break; } -#endif - -#endif +#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */ + *valp = value; +#endif /* defined (BFD_ASSEMBLER) && !defined (TE_Mach) */ md_number_to_chars (p, value, fixP->fx_size); return 1; @@ -4178,7 +4199,7 @@ size_t md_longopts_size = sizeof (md_longopts); int md_parse_option (c, arg) int c; - char *arg; + char *arg ATTRIBUTE_UNUSED; { switch (c) { @@ -4264,7 +4285,7 @@ md_undefined_symbol (name) /* Round up a section size to the appropriate boundary. */ valueT md_section_align (segment, size) - segT segment; + segT segment ATTRIBUTE_UNUSED; valueT size; { #ifdef OBJ_AOUT @@ -4299,7 +4320,7 @@ md_pcrel_from (fixP) static void s_bss (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register int temp; @@ -4324,12 +4345,9 @@ i386_validate_fix (fixp) } } -#define F(SZ,PCREL) (((SZ) << 1) + (PCREL)) -#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break - arelent * tc_gen_reloc (section, fixp) - asection *section; + asection *section ATTRIBUTE_UNUSED; fixS *fixp; { arelent *rel; @@ -4347,27 +4365,35 @@ tc_gen_reloc (section, fixp) code = fixp->fx_r_type; break; default: - switch (F (fixp->fx_size, fixp->fx_pcrel)) + if (fixp->fx_pcrel) { - MAP (1, 0, BFD_RELOC_8); - MAP (2, 0, BFD_RELOC_16); - MAP (4, 0, BFD_RELOC_32); - MAP (1, 1, BFD_RELOC_8_PCREL); - MAP (2, 1, BFD_RELOC_16_PCREL); - MAP (4, 1, BFD_RELOC_32_PCREL); - default: - if (fixp->fx_pcrel) - as_bad (_("Can not do %d byte pc-relative relocation"), - fixp->fx_size); - else - as_bad (_("Can not do %d byte relocation"), fixp->fx_size); - code = BFD_RELOC_32; - break; + switch (fixp->fx_size) + { + default: + as_bad (_("Can not do %d byte pc-relative relocation"), + fixp->fx_size); + code = BFD_RELOC_32_PCREL; + break; + case 1: code = BFD_RELOC_8_PCREL; break; + case 2: code = BFD_RELOC_16_PCREL; break; + case 4: code = BFD_RELOC_32_PCREL; break; + } + } + else + { + switch (fixp->fx_size) + { + default: + as_bad (_("Can not do %d byte relocation"), fixp->fx_size); + code = BFD_RELOC_32; + break; + case 1: code = BFD_RELOC_8; break; + case 2: code = BFD_RELOC_16; break; + case 4: code = BFD_RELOC_32; break; + } } break; } -#undef MAP -#undef F if (code == BFD_RELOC_32 && GOT_symbol @@ -4375,7 +4401,8 @@ tc_gen_reloc (section, fixp) code = BFD_RELOC_386_GOTPC; rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = &fixp->fx_addsy->bsym; + rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; /* HACK: Since i386 ELF uses Rel instead of Rela, encode the @@ -4470,6 +4497,6 @@ tc_coff_sizemachdep (frag) #endif /* I386COFF */ -#endif /* BFD_ASSEMBLER? */ +#endif /* ! BFD_ASSEMBLER */ /* end of tc-i386.c */ diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index d876d61..ef778c1 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -1,5 +1,6 @@ /* tc-i386.h -- Header file for tc-i386.c - Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation. + Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -270,14 +271,21 @@ extern const char extra_symbol_chars[]; #define Acc 0x200000 /* Accumulator %al or %ax or %eax */ #define JumpAbsolute 0x400000 #define RegMMX 0x800000 /* MMX register */ -#define EsSeg 0x1000000 /* String insn operand with fixed es segment */ +#define RegXMM 0x1000000 /* XMM registers in PIII */ +#define EsSeg 0x2000000 /* String insn operand with fixed es segment */ +/* InvMem is for instructions with a modrm byte that only allow a + general register encoding in the i.tm.mode and i.tm.regmem fields, + eg. control reg moves. They really ought to support a memory form, + but don't, so we add an InvMem flag to the register operand to + indicate that it should be encoded in the i.tm.regmem field. */ +#define InvMem 0x4000000 #define Reg (Reg8|Reg16|Reg32) /* gen'l register */ #define WordReg (Reg16|Reg32) #define ImplicitRegister (InOutPortReg|ShiftCount|Acc|FloatAcc) #define Imm (Imm8|Imm8S|Imm16|Imm32) /* gen'l immediate */ #define Disp (Disp8|Disp16|Disp32) /* General displacement */ -#define AnyMem (Disp|BaseIndex) /* General memory */ +#define AnyMem (Disp|BaseIndex|InvMem) /* General memory */ /* The following aliases are defined because the opcode table carefully specifies the allowed memory types for each instruction. At the moment we can only tell a memory reference size by the @@ -323,7 +331,6 @@ typedef struct #define D 0x2 /* D = 0 if Reg --> Regmem; D = 1 if Regmem --> Reg: MUST BE 0x2 */ #define Modrm 0x4 -#define ReverseRegRegmem 0x8 /* swap reg,regmem fields for 2 reg case */ #define FloatR 0x8 /* src/dest swap for floats: MUST BE 0x8 */ #define ShortForm 0x10 /* register is in low 3 bits of opcode */ #define FloatMF 0x20 /* FP insn memory format bit, sized by 0x4 */ @@ -341,12 +348,13 @@ typedef struct #define No_wSuf 0x20000 /* w suffix on instruction illegal */ #define No_lSuf 0x40000 /* l suffix on instruction illegal */ #define No_sSuf 0x80000 /* s suffix on instruction illegal */ -#define FWait 0x100000 /* instruction needs FWAIT */ -#define IsString 0x200000 /* quick test for string instructions */ -#define regKludge 0x400000 /* fake an extra reg operand for clr, imul */ -#define IsPrefix 0x800000 /* opcode is a prefix */ -#define No_dSuf 0x1000000 /* d suffix on instruction illegal */ -#define No_xSuf 0x2000000 /* x suffix on instruction illegal */ +#define No_dSuf 0x100000 /* d suffix on instruction illegal */ +#define No_xSuf 0x200000 /* x suffix on instruction illegal */ +#define FWait 0x400000 /* instruction needs FWAIT */ +#define IsString 0x800000 /* quick test for string instructions */ +#define regKludge 0x1000000 /* fake an extra reg operand for clr, imul */ +#define IsPrefix 0x2000000 /* opcode is a prefix */ +#define ImmExt 0x4000000 /* instruction has extension in 8 bit imm */ #define Ugh 0x80000000 /* deprecated fp insn, gets a warning */ /* operand_types[i] describes the type of operand i. This is made @@ -425,18 +433,10 @@ extern const struct relax_type md_relax_table[]; extern int flag_16bit_code; -#ifdef BFD_ASSEMBLER -#define md_maybe_text() \ - ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0) -#else -#define md_maybe_text() \ - (now_seg != data_section && now_seg != bss_section) -#endif - #define md_do_align(n, fill, len, max, around) \ if ((n) && !need_pass_2 \ && (!(fill) || ((char)*(fill) == (char)0x90 && (len) == 1)) \ - && md_maybe_text ()) \ + && subseg_text_p (now_seg)) \ { \ char *p; \ p = frag_var (rs_align_code, 15, 1, (relax_substateT) max, \ diff --git a/gas/config/tc-i860.c b/gas/config/tc-i860.c index f2e2b19..3317282 100644 --- a/gas/config/tc-i860.c +++ b/gas/config/tc-i860.c @@ -1,5 +1,5 @@ /* tc-i860.c -- Assemble for the I860 - Copyright (C) 1989, 92, 93, 94, 95, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 92, 93, 94, 95, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -1118,9 +1118,9 @@ emit_machine_reloc (fixP, segment_address_in_file) ri.r_extern = 0; ri.r_symbolnum = S_GET_TYPE (symbolP); } - if (symbolP && symbolP->sy_frag) + if (symbolP && symbol_get_frag (symbolP)) { - ri.r_addend = symbolP->sy_frag->fr_address; + ri.r_addend = symbol_get_frag (symbolP)->fr_address; } ri.r_type = fixP->fx_r_type; if (fixP->fx_pcrel) @@ -1184,9 +1184,9 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file) | ((r_extern << 6) & 0x40) | (fixP->fx_r_type & 0x3F)); - if (fixP->fx_addsy->sy_frag) + if (symbol_get_frag (fixP->fx_addsy)) { - r_addend = fixP->fx_addsy->sy_frag->fr_address; + r_addend = symbol_get_frag (fixP->fx_addsy)->fr_address; } if (fixP->fx_pcrel) diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c index 936b662..d8c15c0 100644 --- a/gas/config/tc-i960.c +++ b/gas/config/tc-i960.c @@ -1,5 +1,5 @@ /* tc-i960.c - All the i80960-specific stuff - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS. @@ -101,7 +101,22 @@ #define TC_S_FORCE_TO_SYSPROC(s) (S_SET_STORAGE_CLASS((s), C_SCALL)) #else /* ! OBJ_COFF */ -you lose; +#ifdef OBJ_ELF +#define TC_S_IS_SYSPROC(s) 0 + +#define TC_S_IS_BALNAME(s) 0 +#define TC_S_IS_CALLNAME(s) 0 +#define TC_S_IS_BADPROC(s) 0 + +#define TC_S_SET_SYSPROC(s, p) +#define TC_S_GET_SYSPROC(s) 0 + +#define TC_S_FORCE_TO_BALNAME(s) +#define TC_S_FORCE_TO_CALLNAME(s) +#define TC_S_FORCE_TO_SYSPROC(s) +#else + #error COFF, a.out, b.out, and ELF are the only supported formats. +#endif /* ! OBJ_ELF */ #endif /* ! OBJ_COFF */ #endif /* ! OBJ_A/BOUT */ @@ -1009,7 +1024,6 @@ md_show_usage (stream) } -#ifndef BFD_ASSEMBLER /***************************************************************************** md_convert_frag: Called by base assembler after address relaxation is finished: modify @@ -1023,11 +1037,19 @@ md_show_usage (stream) Replace the cobr with a two instructions (a compare and a branch). *************************************************************************** */ +#ifndef BFD_ASSEMBLER void md_convert_frag (headers, seg, fragP) object_headers *headers; segT seg; fragS *fragP; +#else +void +md_convert_frag (abfd, sec, fragP) + bfd *abfd; + segT sec; + fragS *fragP; +#endif { fixS *fixP; /* Structure describing needed address fix */ @@ -1082,6 +1104,7 @@ md_estimate_size_before_relax (fragP, segment_type) return 0; } /* md_estimate_size_before_relax() */ +#if defined(OBJ_AOUT) | defined(OBJ_BOUT) /***************************************************************************** md_ri_to_chars: @@ -1096,7 +1119,8 @@ md_estimate_size_before_relax (fragP, segment_type) does do the reordering (Ian Taylor 28 Aug 92). *************************************************************************** */ -void + +static void md_ri_to_chars (where, ri) char *where; struct relocation_info *ri; @@ -1114,7 +1138,8 @@ md_ri_to_chars (where, ri) | (ri->r_callj << 6)); } -#endif /* BFD_ASSEMBLER */ +#endif /* defined(OBJ_AOUT) | defined(OBJ_BOUT) */ + /* FOLLOWING ARE THE LOCAL ROUTINES, IN ALPHABETICAL ORDER */ @@ -2613,7 +2638,9 @@ s_leafproc (n_ops, args) } TC_S_FORCE_TO_BALNAME (balP); +#ifndef OBJ_ELF tc_set_bal_of_call (callP, balP); +#endif } /* if only one arg, or the args are the same */ } @@ -2819,25 +2846,42 @@ md_pcrel_from (fixP) return fixP->fx_where + fixP->fx_frag->fr_address; } +#ifdef BFD_ASSEMBLER +int +md_apply_fix (fixP, valp) + fixS *fixP; + valueT *valp; +#else void md_apply_fix (fixP, val) fixS *fixP; long val; +#endif { +#ifdef BFD_ASSEMBLER + long val = *valp; +#endif char *place = fixP->fx_where + fixP->fx_frag->fr_literal; if (!fixP->fx_bit_fixP) { +#ifndef BFD_ASSEMBLER /* For callx, we always want to write out zero, and emit a symbolic relocation. */ if (fixP->fx_bsr) val = 0; fixP->fx_addnumber = val; +#endif + md_number_to_imm (place, val, fixP->fx_size, fixP); } else md_number_to_field (place, val, fixP->fx_bit_fixP); + +#ifdef BFD_ASSEMBLER + return 0; +#endif } #if defined(OBJ_AOUT) | defined(OBJ_BOUT) @@ -2937,8 +2981,14 @@ md_section_align (seg, addr) segT seg; valueT addr; /* Address to be rounded up */ { - return ((addr + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg])); -} /* md_section_align() */ + int align; +#ifdef BFD_ASSEMBLER + align = bfd_get_section_alignment (stdoutput, seg); +#else + align = section_alignment[(int) seg]; +#endif + return (addr + (1 << align) - 1) & (-1 << align); +} extern int coff_flags; @@ -3007,6 +3057,8 @@ tc_headers_hook (headers) #endif /* OBJ_COFF */ +#ifndef BFD_ASSEMBLER + /* Things going on here: For bout, We need to assure a couple of simplifying @@ -3066,6 +3118,8 @@ tc_crawl_symbol_chain (headers) } /* walk the symbol chain */ } +#endif /* ! BFD_ASSEMBLER */ + /* For aout or bout, the bal immediately follows the call. For coff, we cheat and store a pointer to the bal symbol in the @@ -3105,7 +3159,7 @@ tc_set_bal_of_call (callP, balP) } /* if not in order */ #else /* ! OBJ_ABOUT */ - (as yet unwritten.); + as_fatal ("Only supported for a.out, b.out, or COFF"); #endif /* ! OBJ_ABOUT */ #endif /* ! OBJ_COFF */ } @@ -3124,7 +3178,7 @@ tc_get_bal_of_call (callP) #ifdef OBJ_ABOUT retval = symbol_next (callP); #else - (as yet unwritten.); + as_fatal ("Only supported for a.out, b.out, or COFF"); #endif /* ! OBJ_ABOUT */ #endif /* ! OBJ_COFF */ @@ -3228,4 +3282,68 @@ i960_validate_fix (fixP, this_segment_type, add_symbolPP) return 0; } +#ifdef BFD_ASSEMBLER + +/* From cgen.c: */ + +static short +tc_bfd_fix2rtype (fixP) + fixS *fixP; +{ +#if 0 + if (fixP->fx_bsr) + abort (); +#endif + + if (fixP->fx_pcrel == 0 && fixP->fx_size == 4) + return BFD_RELOC_32; + + if (fixP->fx_pcrel != 0 && fixP->fx_size == 4) + return BFD_RELOC_24_PCREL; + + abort (); + return 0; +} + +/* Translate internal representation of relocation info to BFD target + format. + + FIXME: To what extent can we get all relevant targets to use this? */ + +arelent * +tc_gen_reloc (section, fixP) + asection *section; + fixS *fixP; +{ + arelent * reloc; + + reloc = (arelent *) xmalloc (sizeof (arelent)); + + /* HACK: Is this right? */ + fixP->fx_r_type = tc_bfd_fix2rtype (fixP); + + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); + if (reloc->howto == (reloc_howto_type *) NULL) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + "internal error: can't export reloc type %d (`%s')", + fixP->fx_r_type, + bfd_get_reloc_code_name (fixP->fx_r_type)); + return NULL; + } + + assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); + + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); + reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; + reloc->addend = fixP->fx_addnumber; + + return reloc; +} + +/* end from cgen.c */ + +#endif /* BFD_ASSEMBLER */ + /* end of tc-i960.c */ diff --git a/gas/config/tc-i960.h b/gas/config/tc-i960.h index f606967..2746ede 100644 --- a/gas/config/tc-i960.h +++ b/gas/config/tc-i960.h @@ -1,5 +1,5 @@ /* tc-i960.h - Basic 80960 instruction formats. - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -22,6 +22,11 @@ #ifndef TC_I960 #define TC_I960 1 +#ifdef OBJ_ELF +#define TARGET_FORMAT "elf32-i960" +#define TARGET_ARCH bfd_arch_i960 +#endif + #define TARGET_BYTES_BIG_ENDIAN 0 #define WORKING_DOT_WORD @@ -125,7 +130,7 @@ struct relocation_info #ifdef OBJ_COFF /* We store the bal information in the sy_tc field. */ -#define TC_SYMFIELD_TYPE struct symbol * +#define TC_SYMFIELD_TYPE symbolS * #define TC_ADJUST_RELOC_COUNT(FIXP,COUNT) \ { fixS *tcfixp = (FIXP); \ @@ -135,20 +140,36 @@ struct relocation_info } #endif -extern int i960_validate_fix PARAMS ((struct fix *, segT, struct symbol **)); +extern int i960_validate_fix PARAMS ((struct fix *, segT, symbolS **)); #define TC_VALIDATE_FIX(FIXP,SEGTYPE,LABEL) \ if (i960_validate_fix (FIXP, SEGTYPE, &add_symbolP) != 0) goto LABEL +#ifdef OBJ_ELF +#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ + ((FIX)->fx_addsy == NULL \ + || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ + && ! S_IS_WEAK ((FIX)->fx_addsy) \ + && S_IS_DEFINED ((FIX)->fx_addsy) \ + && ! S_IS_COMMON ((FIX)->fx_addsy))) +#endif + +#ifndef OBJ_ELF #define tc_fix_adjustable(FIXP) ((FIXP)->fx_bsr == 0) +#else +#define tc_fix_adjustable(FIXP) \ + ((FIXP)->fx_bsr == 0 \ + && ! S_IS_EXTERNAL ((FIXP)->fx_addsy) \ + && ! S_IS_WEAK ((FIXP)->fx_addsy)) +#endif extern void brtab_emit PARAMS ((void)); #define md_end() brtab_emit () extern void reloc_callj (); -extern void tc_set_bal_of_call PARAMS ((struct symbol *, struct symbol *)); +extern void tc_set_bal_of_call PARAMS ((symbolS *, symbolS *)); -extern struct symbol *tc_get_bal_of_call PARAMS ((struct symbol *)); +extern struct symbol *tc_get_bal_of_call PARAMS ((symbolS *)); extern void i960_handle_align (); #define HANDLE_ALIGN(FRAG) i960_handle_align (FRAG) diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c index 997e623..300f997 100644 --- a/gas/config/tc-m32r.c +++ b/gas/config/tc-m32r.c @@ -136,11 +136,11 @@ struct option md_longopts[] = /* Sigh. I guess all warnings must now have both variants. */ #define OPTION_WARN_UNMATCHED (OPTION_MD_BASE + 4) - {"warn-unmatched-high", OPTION_WARN_UNMATCHED}, - {"Wuh", OPTION_WARN_UNMATCHED}, + {"warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED}, + {"Wuh", no_argument, NULL, OPTION_WARN_UNMATCHED}, #define OPTION_NO_WARN_UNMATCHED (OPTION_MD_BASE + 5) - {"no-warn-unmatched-high", OPTION_WARN_UNMATCHED}, - {"Wnuh", OPTION_WARN_UNMATCHED}, + {"no-warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED}, + {"Wnuh", no_argument, NULL, OPTION_WARN_UNMATCHED}, #if 0 /* not supported yet */ #define OPTION_RELAX (OPTION_MD_BASE + 6) @@ -179,6 +179,10 @@ md_parse_option (c, arg) #endif default: + if (arg) + fprintf (stderr, _("%s: unrecognised command line option: -%c\n"), myname, c); + else + fprintf (stderr, _("%s: unrecognised command line option: -%c%s\n"), myname, c, arg); return 0; } return 1; @@ -245,7 +249,7 @@ m32r_do_align (n, fill, len, max) { /* Only do this if the fill pattern wasn't specified. */ if (fill == NULL - && (now_seg->flags & SEC_CODE) != 0 + && subseg_text_p (now_seg) /* Only do this special handling if aligning to at least a 4 byte boundary. */ && n > 1 @@ -336,7 +340,7 @@ debug_sym (ignore) link->symbol = symbolP; link->next = debug_sym_link; debug_sym_link = link; - symbolP->local = 1; + symbol_get_obj (symbolP)->local = 1; } *end_name = delim; @@ -694,7 +698,7 @@ m32r_scomm (ignore) return; } - if (symbolP->local) + if (symbol_get_obj (symbolP)->local) { segT old_sec = now_seg; int old_subsec = now_subseg; @@ -707,9 +711,9 @@ m32r_scomm (ignore) frag_align (align2, 0, 0); if (S_GET_SEGMENT (symbolP) == sbss_section) - symbolP->sy_frag->fr_symbol = 0; + symbol_get_frag (symbolP)->fr_symbol = 0; - symbolP->sy_frag = frag_now; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size, (char *) 0); @@ -936,7 +940,7 @@ md_convert_frag (abfd, sec, fragP) { /* Address we want to reach in file space. */ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; - target_address += fragP->fr_symbol->sy_frag->fr_address; + target_address += symbol_get_frag (fragP->fr_symbol)->fr_address; addend = (target_address - (opcode_address & -4)) >> 2; } diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 856dd4e..0749665 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1,5 +1,5 @@ /* tc-m68k.c -- Assemble for the m68k family - Copyright (C) 1987, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1987, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -27,6 +27,10 @@ #include "opcode/m68k.h" #include "m68k-parse.h" +#if defined (OBJ_ELF) +#include "elf/m68k.h" +#endif + /* This string holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful. The macro tc_comment_chars points to this. We use this, rather than the @@ -189,7 +193,7 @@ static const enum m68k_register m68060_control_regs[] = { USP, VBR, URP, SRP, PCR, 0 }; -static const enum m68k_register mcf5200_control_regs[] = { +static const enum m68k_register mcf_control_regs[] = { CACR, TC, ITT0, ITT1, DTT0, DTT1, VBR, ROMBAR, RAMBAR0, RAMBAR1, MBAR, 0 @@ -247,9 +251,10 @@ struct m68k_it reloc[5]; /* Five is enough??? */ }; -#define cpu_of_arch(x) ((x) & (m68000up|mcf5200)) +#define cpu_of_arch(x) ((x) & (m68000up|mcf)) #define float_of_arch(x) ((x) & mfloat) #define mmu_of_arch(x) ((x) & mmmu) +#define arch_coldfire_p(x) (((x) & mcf) != 0) /* Macros for determining if cpu supports a specific addressing mode */ #define HAVE_LONG_BRANCH(x) ((x) & (m68020|m68030|m68040|m68060|cpu32)) @@ -391,6 +396,8 @@ static const struct m68k_cpu archs[] = { { m68881, "68881", 0 }, { m68851, "68851", 0 }, { mcf5200, "5200", 0 }, + { mcf5206e, "5206e", 0 }, + { mcf5307, "5307", 0}, /* Aliases (effectively, so far as gas is concerned) for the above cpus. */ { m68020, "68k", 1 }, @@ -418,6 +425,9 @@ static const struct m68k_cpu archs[] = { { cpu32, "68349", 1 }, { cpu32, "68360", 1 }, { m68881, "68882", 1 }, + { mcf5200, "5202", 1 }, + { mcf5200, "5204", 1 }, + { mcf5200, "5206", 1 }, }; static const int n_archs = sizeof (archs) / sizeof (archs[0]); @@ -897,7 +907,8 @@ tc_gen_reloc (section, fixp) #undef MAP reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; #ifndef OBJ_ELF if (fixp->fx_pcrel) @@ -1471,11 +1482,26 @@ m68k_ip (instring) losing++; break; + case 'E': + if (opP->reg != ACC) + losing++; + break; + case 'F': if (opP->mode != FPREG) losing++; break; + case 'G': + if (opP->reg != MACSR) + losing++; + break; + + case 'H': + if (opP->reg != MASK) + losing++; + break; + case 'I': if (opP->mode != CONTROL || opP->reg < COP0 @@ -1737,6 +1763,19 @@ m68k_ip (instring) ++losing; break; + case 'u': + if (opP->reg < DATA0L || opP->reg > ADDR7U) + losing++; + /* FIXME: kludge instead of fixing parser: + upper/lower registers are *not* CONTROL + registers, but ordinary ones. */ + if ((opP->reg >= DATA0L && opP->reg <= DATA7L) + || (opP->reg >= DATA0U && opP->reg <= DATA7U)) + opP->mode = DREG; + else + opP->mode = AREG; + break; + default: abort (); } /* switch on type of operand */ @@ -1994,11 +2033,11 @@ m68k_ip (instring) && ((opP->disp.size == SIZE_UNSPEC && flag_short_refs == 0 && cpu_of_arch (current_architecture) >= m68020 - && cpu_of_arch (current_architecture) != mcf5200) + && ! arch_coldfire_p (current_architecture)) || opP->disp.size == SIZE_LONG))) { if (cpu_of_arch (current_architecture) < m68020 - || cpu_of_arch (current_architecture) == mcf5200) + || arch_coldfire_p (current_architecture)) opP->error = _("displacement too large for this architecture; needs 68020 or higher"); if (opP->reg == PC) @@ -2107,12 +2146,16 @@ m68k_ip (instring) if ((opP->index.scale != 1 && cpu_of_arch (current_architecture) < m68020) || (opP->index.scale == 8 - && current_architecture == mcf5200)) + && arch_coldfire_p (current_architecture))) { opP->error = _("scale factor invalid on this architecture; needs cpu32 or 68020 or higher"); } + if (arch_coldfire_p (current_architecture) + && opP->index.size == SIZE_WORD) + opP->error = _("invalid index size for coldfire"); + switch (opP->index.scale) { case 1: @@ -2144,7 +2187,7 @@ m68k_ip (instring) { if (siz1 == SIZE_BYTE || cpu_of_arch (current_architecture) < m68020 - || cpu_of_arch (current_architecture) == mcf5200 + || arch_coldfire_p (current_architecture) || (siz1 == SIZE_UNSPEC && ! isvar (&opP->disp) && issbyte (baseo))) @@ -2211,7 +2254,7 @@ m68k_ip (instring) /* It isn't simple. */ if (cpu_of_arch (current_architecture) < m68020 - || cpu_of_arch (current_architecture) == mcf5200) + || arch_coldfire_p (current_architecture)) opP->error = _("invalid operand mode for this architecture; needs 68020 or higher"); @@ -2570,10 +2613,17 @@ m68k_ip (instring) install_operand (s[1], opP->reg - DATA); break; + case 'E': /* Ignore it */ + break; + case 'F': install_operand (s[1], opP->reg - FP0); break; + case 'G': /* Ignore it */ + case 'H': + break; + case 'I': tmpreg = opP->reg - COP0; install_operand (s[1], tmpreg); @@ -2901,6 +2951,11 @@ m68k_ip (instring) addword (tmpreg >> 16); addword (tmpreg & 0xFFFF); break; + case 'u': + install_operand (s[1], opP->reg - DATA0L); + opP->reg -= (DATA0L); + opP->reg &= 0x0F; /* remove upper/lower bit */ + break; default: abort (); } @@ -3040,6 +3095,30 @@ install_operand (mode, val) the_ins.opcode[1] = (val >> 16); the_ins.opcode[2] = val & 0xffff; break; + case 'm': + the_ins.opcode[0] |= ((val & 0x8) << (6 - 3)); + the_ins.opcode[0] |= ((val & 0x7) << 9); + the_ins.opcode[1] |= ((val & 0x10) << (7 - 4)); + break; + case 'n': + the_ins.opcode[0] |= ((val & 0x8) << (6 - 3)); + the_ins.opcode[0] |= ((val & 0x7) << 9); + break; + case 'o': + the_ins.opcode[1] |= val << 12; + the_ins.opcode[1] |= ((val & 0x10) << (7 - 4)); + break; + case 'M': + the_ins.opcode[0] |= (val & 0xF); + the_ins.opcode[1] |= ((val & 0x10) << (6 - 4)); + break; + case 'N': + the_ins.opcode[1] |= (val & 0xF); + the_ins.opcode[1] |= ((val & 0x10) << (6 - 4)); + break; + case 'h': + the_ins.opcode[1] |= ((val != 1) << 10); + break; case 'c': default: as_fatal (_("failed sanity check.")); @@ -3241,6 +3320,10 @@ static const struct init_entry init_table[] = { "ccr", CCR }, { "cc", CCR }, + { "acc", ACC }, + { "macsr", MACSR }, + { "mask", MASK }, + /* control registers */ { "sfc", SFC }, /* Source Function Code */ { "sfcr", SFC }, @@ -3345,6 +3428,43 @@ static const struct init_entry init_table[] = { "za6", ZADDR6 }, { "za7", ZADDR7 }, + /* Upper and lower data and address registers, used by macw and msacw. */ + { "d0l", DATA0L }, + { "d1l", DATA1L }, + { "d2l", DATA2L }, + { "d3l", DATA3L }, + { "d4l", DATA4L }, + { "d5l", DATA5L }, + { "d6l", DATA6L }, + { "d7l", DATA7L }, + + { "a0l", ADDR0L }, + { "a1l", ADDR1L }, + { "a2l", ADDR2L }, + { "a3l", ADDR3L }, + { "a4l", ADDR4L }, + { "a5l", ADDR5L }, + { "a6l", ADDR6L }, + { "a7l", ADDR7L }, + + { "d0u", DATA0U }, + { "d1u", DATA1U }, + { "d2u", DATA2U }, + { "d3u", DATA3U }, + { "d4u", DATA4U }, + { "d5u", DATA5U }, + { "d6u", DATA6U }, + { "d7u", DATA7U }, + + { "a0u", ADDR0U }, + { "a1u", ADDR1U }, + { "a2u", ADDR2U }, + { "a3u", ADDR3U }, + { "a4u", ADDR4U }, + { "a5u", ADDR5U }, + { "a6u", ADDR6U }, + { "a7u", ADDR7U }, + { 0, 0 } }; @@ -3779,7 +3899,9 @@ select_control_regs () control_regs = cpu32_control_regs; break; case mcf5200: - control_regs = mcf5200_control_regs; + case mcf5206e: + case mcf5307: + control_regs = mcf_control_regs; break; default: abort (); @@ -3853,7 +3975,7 @@ m68k_init_after_args () select_control_regs (); if (cpu_of_arch (current_architecture) < m68020 - || cpu_of_arch (current_architecture) == mcf5200) + || arch_coldfire_p (current_architecture)) md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0; } @@ -4171,7 +4293,7 @@ md_convert_frag_1 (fragP) disp = (disp + fragP->fr_offset) - object_address; #ifdef BFD_ASSEMBLER - disp += fragP->fr_symbol->sy_frag->fr_address; + disp += symbol_get_frag (fragP->fr_symbol)->fr_address; #endif switch (fragP->fr_subtype) @@ -4373,8 +4495,8 @@ md_convert_frag (headers, sec, fragP) void md_convert_frag (abfd, sec, fragP) - bfd *abfd; - segT sec; + bfd *abfd ATTRIBUTE_UNUSED; + segT sec ATTRIBUTE_UNUSED; fragS *fragP; { md_convert_frag_1 (fragP); @@ -4620,14 +4742,14 @@ md_estimate_size_before_relax (fragP, segment) word mode. */ if (fragP->fr_symbol && S_GET_VALUE (fragP->fr_symbol) == 0) { + fragS *stop; fragS *l; - for (l = fragP->fr_next; - l != fragP->fr_symbol->sy_frag; - l = l->fr_next) + stop = symbol_get_frag (fragP->fr_symbol); + for (l = fragP->fr_next; l != stop; l = l->fr_next) if (l->fr_fix + l->fr_var != 0) break; - if (l == fragP->fr_symbol->sy_frag) + if (l == stop) { fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), SHORT); fragP->fr_var += 2; @@ -4712,8 +4834,8 @@ void md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) char *ptr; addressT from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; + fragS *frag ATTRIBUTE_UNUSED; + symbolS *to_symbol ATTRIBUTE_UNUSED; { valueT offset; @@ -4898,7 +5020,7 @@ get_num (exp, ok) static void s_data1 (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { subseg_set (data_section, 1); demand_empty_rest_of_line (); @@ -4906,7 +5028,7 @@ s_data1 (ignore) static void s_data2 (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { subseg_set (data_section, 2); demand_empty_rest_of_line (); @@ -4914,7 +5036,7 @@ s_data2 (ignore) static void s_bss (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { /* We don't support putting frags in the BSS segment, we fake it by marking in_bss, then looking at s_skip for clues. */ @@ -4925,7 +5047,7 @@ s_bss (ignore) static void s_even (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register int temp; register long temp_fill; @@ -4940,7 +5062,7 @@ s_even (ignore) static void s_proc (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { demand_empty_rest_of_line (); } @@ -5016,7 +5138,7 @@ mri_chip () static void s_chip (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *stop = NULL; char stopc; @@ -5033,7 +5155,7 @@ s_chip (ignore) static void s_fopt (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { SKIP_WHITESPACE (); @@ -5143,7 +5265,7 @@ static const struct opt_action opt_table[] = static void s_opt (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { do { @@ -5211,8 +5333,8 @@ s_opt (ignore) static void skip_to_comma (arg, on) - int arg; - int on; + int arg ATTRIBUTE_UNUSED; + int on ATTRIBUTE_UNUSED; { while (*input_line_pointer != ',' && ! is_end_of_line[(unsigned char) *input_line_pointer]) @@ -5223,8 +5345,8 @@ skip_to_comma (arg, on) static void opt_nest (arg, on) - int arg; - int on; + int arg ATTRIBUTE_UNUSED; + int on ATTRIBUTE_UNUSED; { if (*input_line_pointer != '=') { @@ -5240,8 +5362,8 @@ opt_nest (arg, on) static void opt_chip (arg, on) - int arg; - int on; + int arg ATTRIBUTE_UNUSED; + int on ATTRIBUTE_UNUSED; { if (*input_line_pointer != '=') { @@ -5257,7 +5379,7 @@ opt_chip (arg, on) static void opt_list (arg, on) - int arg; + int arg ATTRIBUTE_UNUSED; int on; { listing_list (on); @@ -5267,7 +5389,7 @@ opt_list (arg, on) static void opt_list_symbols (arg, on) - int arg; + int arg ATTRIBUTE_UNUSED; int on; { if (on) @@ -5280,7 +5402,7 @@ opt_list_symbols (arg, on) static void s_reg (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *s; int c; @@ -5351,7 +5473,7 @@ s_reg (ignore) S_SET_SEGMENT (line_label, reg_section); S_SET_VALUE (line_label, ~mask); - line_label->sy_frag = &zero_address_frag; + symbol_set_frag (line_label, &zero_address_frag); if (flag_mri) mri_comment_end (stop, stopc); @@ -5384,7 +5506,7 @@ static struct save_opts *save_stack; static void s_save (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { struct save_opts *s; @@ -5409,7 +5531,7 @@ s_save (ignore) static void s_restore (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { struct save_opts *s; @@ -6086,7 +6208,7 @@ s_mri_else (qual) static void s_mri_endi (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { if (mri_control_stack == NULL || mri_control_stack->type != mri_if) @@ -6429,7 +6551,7 @@ s_mri_for (qual) static void s_mri_endf (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { if (mri_control_stack == NULL || mri_control_stack->type != mri_for) @@ -6465,7 +6587,7 @@ s_mri_endf (ignore) static void s_mri_repeat (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { struct mri_control_info *n; @@ -6570,7 +6692,7 @@ s_mri_while (qual) static void s_mri_endw (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *buf; @@ -6929,7 +7051,7 @@ is_label (str) /* ARGSUSED */ symbolS * md_undefined_symbol (name) - char *name; + char *name ATTRIBUTE_UNUSED; { return 0; } @@ -6937,7 +7059,7 @@ md_undefined_symbol (name) /* Round up a section size to the appropriate boundary. */ valueT md_section_align (segment, size) - segT segment; + segT segment ATTRIBUTE_UNUSED; valueT size; { #ifdef OBJ_AOUT @@ -7005,5 +7127,12 @@ tc_coff_sizemachdep (frag) #endif #endif - +#ifdef OBJ_ELF +void m68k_elf_final_processing() +{ + /* Set file-specific flags if this is a cpu32 processor */ + if (cpu_of_arch (current_architecture) & cpu32) + elf_elfheader (stdoutput)->e_flags |= EF_CPU32; +} +#endif /* end of tc-m68k.c */ diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h index bc8308a..b8492b9 100644 --- a/gas/config/tc-m68k.h +++ b/gas/config/tc-m68k.h @@ -1,5 +1,5 @@ /* This file is tc-m68k.h - Copyright (C) 1987, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1987, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -22,7 +22,6 @@ #define TC_M68K 1 #ifdef ANSI_PROTOTYPES -struct symbol; struct fix; #endif @@ -138,13 +137,13 @@ extern void m68k_mri_mode_change PARAMS ((int)); extern int m68k_conditional_pseudoop PARAMS ((pseudo_typeS *)); #define tc_conditional_pseudoop(pop) m68k_conditional_pseudoop (pop) -extern void m68k_frob_label PARAMS ((struct symbol *)); +extern void m68k_frob_label PARAMS ((symbolS *)); #define tc_frob_label(sym) m68k_frob_label (sym) extern void m68k_flush_pending_output PARAMS ((void)); #define md_flush_pending_output() m68k_flush_pending_output () -extern void m68k_frob_symbol PARAMS ((struct symbol *)); +extern void m68k_frob_symbol PARAMS ((symbolS *)); #ifdef BFD_ASSEMBLER @@ -176,6 +175,8 @@ while (0) #define tc_fix_adjustable(X) tc_m68k_fix_adjustable(X) extern int tc_m68k_fix_adjustable PARAMS ((struct fix *)); +#define elf_tc_final_processing m68k_elf_final_processing +extern void m68k_elf_final_processing PARAMS ((void)); #endif #define TC_FORCE_RELOCATION(FIX) \ diff --git a/gas/config/tc-m88k.c b/gas/config/tc-m88k.c index 931a496a..f77460a 100644 --- a/gas/config/tc-m88k.c +++ b/gas/config/tc-m88k.c @@ -1,7 +1,7 @@ /* m88k.c -- Assembler for the Motorola 88000 Contributed by Devon Bowen of Buffalo University and Torbjorn Granlund of the Swedish Institute of Computer Science. - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -1214,9 +1214,9 @@ emit_relocations (fixP, segment_address_in_file) ri.r_extern = 0; ri.r_symbolnum = symbolP->sy_type & N_TYPE; } - if (symbolP && symbolP->sy_frag) + if (symbolP && symbol_get_frag (symbolP)) { - ri.r_addend = symbolP->sy_frag->fr_address; + ri.r_addend = symbol_get_frag (symbolP)->fr_address; } ri.r_type = fixP->fx_r_type; if (fixP->fx_pcrel) @@ -1294,10 +1294,10 @@ s_bss () frag_align (bss_align, 0, 0); /* detach from old frag */ - if (symbolP->sy_type == N_BSS && symbolP->sy_frag != NULL) - symbolP->sy_frag->fr_symbol = NULL; + if (symbolP->sy_type == N_BSS && symbol_get_frag (symbolP) != NULL) + symbol_get_frag (symbolP)->fr_symbol = NULL; - symbolP->sy_frag = frag_now; + symbol_set_frag (symbolP, frag_now); p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, (offsetT) temp, (char *)0); *p = 0; diff --git a/gas/config/tc-mcore.c b/gas/config/tc-mcore.c index 7e78435..d33fc9f 100644 --- a/gas/config/tc-mcore.c +++ b/gas/config/tc-mcore.c @@ -1,6 +1,5 @@ /* tc-mcore.c -- Assemble code for M*Core - - Copyright (C) 1993,1994, 1999 Free Software Foundation. + Copyright (C) 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -53,16 +52,19 @@ static void dump_literals PARAMS ((int)); static void check_literals PARAMS ((int, int)); static void mcore_s_text PARAMS ((int)); static void mcore_s_data PARAMS ((int)); -#ifdef OBJ_ELF static void mcore_s_section PARAMS ((int)); +static void mcore_s_bss PARAMS ((int)); +#ifdef OBJ_ELF +static void mcore_s_comm PARAMS ((int)); #endif + /* Several places in this file insert raw instructions into the object. They should use MCORE_INST_XXX macros to get the opcodes and then use these two macros to crack the MCORE_INST value into the appropriate byte values. */ -#define INST_BYTE0(x) (((x) >> 8) & 0xFF) -#define INST_BYTE1(x) ((x) & 0xFF) +#define INST_BYTE0(x) (((x) >> 8) & 0xFF) +#define INST_BYTE1(x) ((x) & 0xFF) const char comment_chars[] = "#/"; const char line_separator_chars[] = ";"; @@ -70,7 +72,6 @@ const char line_comment_chars[] = "#/"; const int md_reloc_size = 8; -static int relax; /* set if -relax seen */ static int do_jsri2bsr = 0; /* change here from 1 by Cruess 19 August 97 */ static int sifilter_mode = 0; @@ -165,7 +166,6 @@ const pseudo_typeS md_pseudo_table[] = { "import", s_ignore, 0 }, { "literals", mcore_s_literals, 0 }, { "page", listing_eject, 0 }, - { "bss", s_lcomm_bytes, 1 }, /* The following are to intercept the placement of data into the text section (eg addresses for a switch table), so that the space they @@ -197,13 +197,15 @@ const pseudo_typeS md_pseudo_table[] = /* Allow for the effect of section changes. */ { "text", mcore_s_text, 0 }, { "data", mcore_s_data, 0 }, - -#ifdef OBJ_ELF + { "bss", mcore_s_bss, 1 }, +#ifdef OBJ_EF + { "comm", mcore_s_comm, 0 }, +#endif { "section", mcore_s_section, 0 }, { "section.s", mcore_s_section, 0 }, { "sect", mcore_s_section, 0 }, { "sect.s", mcore_s_section, 0 }, -#endif + { 0, 0, 0 } }; @@ -304,13 +306,20 @@ mcore_stringer (append_zero) check_literals (2, 0); } +/* Handle the section changing pseudo-ops. These call through to the + normal implementations, but they dump the literal pool first. */ + static void mcore_s_text (ignore) int ignore; { dump_literals (0); +#ifdef OBJ_ELF + obj_elf_text (ignore); +#else s_text (ignore); +#endif } static void @@ -319,9 +328,47 @@ mcore_s_data (ignore) { dump_literals (0); +#ifdef OBJ_ELF + obj_elf_data (ignore); +#else s_data (ignore); +#endif } +static void +mcore_s_section (ignore) + int ignore; +{ + dump_literals (0); + +#ifdef OBJ_ELF + obj_elf_section (ignore); +#endif +#ifdef OBJ_COFF + obj_coff_section (ignore); +#endif +} + +static void +mcore_s_bss (needs_align) + int needs_align; +{ + dump_literals (0); + + s_lcomm_bytes (needs_align); +} + +#ifdef OBJ_ELF +static void +mcore_s_comm (needs_align) + int needs_align; +{ + dump_literals (0); + + obj_elf_common (needs_align); +} +#endif + /* This function is called once, at assembler startup time. This should set up all the tables, etc that the MD part of the assembler needs. */ void @@ -394,7 +441,7 @@ parse_reg (s, reg) } else if ( tolower (s[0]) == 's' && tolower (s[1]) == 'p' - && (isspace (s[2]) || s[2] == ',')) + && ! isalnum (s[2])) { * reg = 0; return s + 2; @@ -533,13 +580,16 @@ make_name (s, p, n) s[7] = 0; } +#define POOL_END_LABEL ".LE" +#define POOL_START_LABEL ".LS" + static void dump_literals (isforce) int isforce; { int i; struct literal * p; - struct symbol * brarsym; + symbolS * brarsym; if (poolsize == 0) return; @@ -550,7 +600,7 @@ dump_literals (isforce) char * output; char brarname[8]; - make_name (brarname, ".YP.", poolnumber); + make_name (brarname, POOL_END_LABEL, poolnumber); brarsym = symbol_make (brarname); @@ -642,7 +692,7 @@ enter_literal (e, ispcrel) if (++ poolnumber > 0xFFFF) as_fatal (_("more than 65K literal pools")); - make_name (poolname, ".XP.", poolnumber); + make_name (poolname, POOL_START_LABEL, poolnumber); poolsym = symbol_make (poolname); symbol_table_insert (poolsym); poolspan = 0; @@ -877,8 +927,8 @@ md_assemble (str) fixes problem of an interrupt during a jmp.. */ if (sifilter_mode) { - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); } break; @@ -896,20 +946,20 @@ md_assemble (str) { /* Replace with: bsr .+2 ; addi r15,6; jmp rx ; jmp rx */ inst = MCORE_INST_BSR; /* with 0 displacement */ - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); inst = MCORE_INST_ADDI; inst |= 15; /* addi r15,6 */ inst |= (6 - 1) << 4; /* over the jmp's */ - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); inst = MCORE_INST_JMP | reg; - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); /* 2nd emitted in fallthru */ } @@ -1496,8 +1546,8 @@ md_assemble (str) as_bad (_("unimplemented opcode \"%s\""), name); } - output[0] = inst >> 8; - output[1] = inst; + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); check_literals (opcode->transfer, isize); } @@ -1531,7 +1581,7 @@ md_atof (type, litP, sizeP) { int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE * wordP; + int i; char * t; char * atof_ieee (); @@ -1573,26 +1623,25 @@ md_atof (type, litP, sizeP) *sizeP = prec * sizeof (LITTLENUM_TYPE); - for (wordP = words; prec--;) - { - md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } + for (i = 0; i < prec; i++) + { + md_number_to_chars (litP, (valueT) words[i], + sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } return 0; } CONST char * md_shortopts = ""; -#define OPTION_RELAX (OPTION_MD_BASE) -#define OPTION_JSRI2BSR_ON (OPTION_MD_BASE + 1) -#define OPTION_JSRI2BSR_OFF (OPTION_MD_BASE + 2) -#define OPTION_SIFILTER_ON (OPTION_MD_BASE + 3) -#define OPTION_SIFILTER_OFF (OPTION_MD_BASE + 4) +#define OPTION_JSRI2BSR_ON (OPTION_MD_BASE + 0) +#define OPTION_JSRI2BSR_OFF (OPTION_MD_BASE + 1) +#define OPTION_SIFILTER_ON (OPTION_MD_BASE + 2) +#define OPTION_SIFILTER_OFF (OPTION_MD_BASE + 3) struct option md_longopts[] = { - { "relax", no_argument, NULL, OPTION_RELAX}, { "no-jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_OFF}, { "jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_ON}, { "sifilter", no_argument, NULL, OPTION_SIFILTER_ON}, @@ -1613,7 +1662,6 @@ md_parse_option (c, arg) switch (c) { - case OPTION_RELAX: relax = 1; break; case OPTION_JSRI2BSR_ON: do_jsri2bsr = 1; break; case OPTION_JSRI2BSR_OFF: do_jsri2bsr = 0; break; case OPTION_SIFILTER_ON: sifilter_mode = 1; break; @@ -1630,9 +1678,8 @@ md_show_usage (stream) { fprintf (stream, _("\ MCORE specific options:\n\ - -{no-}jsri2bsr {dis}able jsri to bsr transformation (def: off)\n\ - -{no-}sifilter {dis}able silicon filter behavior (def: off)\n\ - -relax alter jump instructions for long displacements\n")); + -{no-}jsri2bsr {dis}able jsri to bsr transformation (def: dis)\n\ + -{no-}sifilter {dis}able silicon filter behavior (def: dis)")); } int md_short_jump_size; @@ -1670,7 +1717,7 @@ md_convert_frag (abfd, sec, fragP) int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal); - targ_addr += fragP->fr_symbol->sy_frag->fr_address; + targ_addr += symbol_get_frag (fragP->fr_symbol)->fr_address; switch (fragP->fr_subtype) { @@ -1683,14 +1730,17 @@ md_convert_frag (abfd, sec, fragP) int disp = targ_addr - next_inst; if (disp & 1) - as_bad (_("odd displacement at %x"), next_inst - 2); + as_bad (_("odd displacement at %x"), next_inst - 2); disp >>= 1; - t0 = buffer[0] & 0xF8; + { + t0 = buffer[0] & 0xF8; + + md_number_to_chars (buffer, disp, 2); - md_number_to_chars (buffer, disp, 2); + buffer[0] = (buffer[0] & 0x07) | t0; + } - buffer[0] = (buffer[0] & 0x07) | t0; fragP->fr_fix += 2; fragP->fr_var = 0; } @@ -1712,15 +1762,18 @@ md_convert_frag (abfd, sec, fragP) int first_inst = fragP->fr_fix + fragP->fr_address; int needpad = (first_inst & 3); - buffer[0] ^= 0x08; /* Toggle T/F bit */ + buffer[0] ^= 0x08; /* Toggle T/F bit */ buffer[2] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi */ buffer[3] = INST_BYTE1 (MCORE_INST_JMPI); if (needpad) { - buffer[1] = 4; /* branch over jmpi, pad, and ptr */ - buffer[3] = 1; /* jmpi offset of 1 gets the pointer */ + { + buffer[1] = 4; /* branch over jmpi, pad, and ptr */ + buffer[3] = 1; /* jmpi offset of 1 gets the pointer */ + } + buffer[4] = 0; /* alignment/pad */ buffer[5] = 0; buffer[6] = 0; /* space for 32 bit address */ @@ -1740,8 +1793,11 @@ md_convert_frag (abfd, sec, fragP) shrinking the fragment. '3' is the amount of code that we inserted here, but '4' is right for the space we reserved for this fragment. */ - buffer[1] = 3; /* branch over jmpi, and ptr */ - buffer[3] = 0; /* jmpi offset of 0 gets the pointer */ + { + buffer[1] = 3; /* branch over jmpi, and ptr */ + buffer[3] = 0; /* jmpi offset of 0 gets the pointer */ + } + buffer[4] = 0; /* space for 32 bit address */ buffer[5] = 0; buffer[6] = 0; @@ -1752,12 +1808,12 @@ md_convert_frag (abfd, sec, fragP) fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32); fragP->fr_fix += C32_LEN; - /* frag is actually shorter (see the other side of this ifdef) - but gas isn't prepared for that. We have to re-adjust + /* Frag is actually shorter (see the other side of this ifdef) + but gas isn't prepared for that. We have to re-adjust the branch displacement so that it goes beyond the full length of the fragment, not just what we actually filled in. */ - buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */ + buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */ } fragP->fr_var = 0; @@ -1782,7 +1838,7 @@ md_convert_frag (abfd, sec, fragP) if (needpad) { - buffer[1] = 1; /* jmpi offset of 1 since padded */ + buffer[1] = 1; /* jmpi offset of 1 since padded */ buffer[2] = 0; /* alignment */ buffer[3] = 0; buffer[4] = 0; /* space for 32 bit address */ @@ -1798,7 +1854,7 @@ md_convert_frag (abfd, sec, fragP) } else { - buffer[1] = 0; /* jmpi offset of 0 if no pad */ + buffer[1] = 0; /* jmpi offset of 0 if no pad */ buffer[2] = 0; /* space for 32 bit address */ buffer[3] = 0; buffer[4] = 0; @@ -1865,9 +1921,9 @@ md_apply_fix3 (fixP, valp, segment) as_bad_where (file, fixP->fx_line, _("pcrel for branch to %s too far (0x%x)"), symname, val); - buf[0] |= ((val >> 8) & 0x7); - buf[1] |= (val & 0xff); - break; + buf[0] |= ((val >> 8) & 0x7); + buf[1] |= (val & 0xff); + break; case BFD_RELOC_MCORE_PCREL_IMM8BY4: /* lower 8 bits of 2 byte opcode */ val += 3; @@ -1878,14 +1934,14 @@ md_apply_fix3 (fixP, valp, segment) symname, val); else buf[1] |= (val & 0xff); - break; + break; case BFD_RELOC_MCORE_PCREL_IMM4BY2: /* loopt instruction */ if ((val < -32) || (val > -2)) as_bad_where (file, fixP->fx_line, _("pcrel for loopt too far (0x%x)"), val); val /= 2; - buf[1] |= (val & 0xf); + buf[1] |= (val & 0xf); break; case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: @@ -1898,8 +1954,8 @@ md_apply_fix3 (fixP, valp, segment) nval |= MCORE_INST_BSR; /* REPLACE the instruction, don't just modify it. */ - buf[0] = ((nval >> 8) & 0xff); - buf[1] = (nval & 0xff); + buf[0] = INST_BYTE0 (nval); + buf[1] = INST_BYTE1 (nval); } else fixP->fx_done = 0; @@ -1923,21 +1979,14 @@ md_apply_fix3 (fixP, valp, segment) #endif { if (fixP->fx_size == 4) - { - *buf++ = val >> 24; - *buf++ = val >> 16; - *buf++ = val >> 8; - *buf = val; - } + ; else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767) - { - *buf++ = val >> 8; - *buf = val; - } + ; else if (fixP->fx_size == 1 && val >= -256 && val <= 255) - *buf = val; + ; else abort (); + md_number_to_chars (buf, val, fixP->fx_size); } break; } @@ -2022,21 +2071,20 @@ md_estimate_size_before_relax (fragP, segment_type) } /* Put number into target byte order */ - void md_number_to_chars (ptr, use, nbytes) char * ptr; valueT use; int nbytes; { - switch (nbytes) - { - case 4: *ptr++ = (use >> 24) & 0xff; /* fall through */ - case 3: *ptr++ = (use >> 16) & 0xff; /* fall through */ - case 2: *ptr++ = (use >> 8) & 0xff; /* fall through */ - case 1: *ptr++ = (use >> 0) & 0xff; break; - default: abort (); - } + switch (nbytes) + { + case 4: *ptr++ = (use >> 24) & 0xff; /* fall through */ + case 3: *ptr++ = (use >> 16) & 0xff; /* fall through */ + case 2: *ptr++ = (use >> 8) & 0xff; /* fall through */ + case 1: *ptr++ = (use >> 0) & 0xff; break; + default: abort (); + } } /* Round up a section size to the appropriate boundary. */ @@ -2117,7 +2165,8 @@ tc_gen_reloc (section, fixp) } rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = & fixp->fx_addsy->bsym; + rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; /* Always pass the addend along! */ rel->addend = fixp->fx_addnumber; @@ -2169,15 +2218,4 @@ mcore_fix_adjustable (fixP) return 1; } - -/* Handle the .section pseudo-op. This is like the usual one, but it - dumps the literal pool before changing the section. */ -static void -mcore_s_section (ignore) - int ignore; -{ - dump_literals (0); - - obj_elf_section (ignore); -} #endif /* OBJ_ELF */ diff --git a/gas/config/tc-mcore.h b/gas/config/tc-mcore.h index 9e487c9..e713c27 100644 --- a/gas/config/tc-mcore.h +++ b/gas/config/tc-mcore.h @@ -65,7 +65,12 @@ extern const struct relax_type md_relax_table[]; #define TARGET_FORMAT (target_big_endian ? "pe-mcore-big" : "pe-mcore-little") -#define TARGET_SYMBOL_FIELDS int sy_flags ; +struct mcore_tc_sy +{ + int sy_flags; +}; + +#define TC_SYMFIELD_TYPE struct mcore_tc_sy #endif /* OBJ_COFF */ @@ -93,7 +98,6 @@ extern boolean mcore_fix_adjustable PARAMS ((struct fix *)); # error No target format specified. #endif -#include "struc-symbol.h" /* For definition of symbolS */ #include "write.h" /* For definition of fixS */ extern void md_begin PARAMS ((void)); diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 3d865fd..c9b0632 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1,5 +1,5 @@ /* tc-mips.c -- assemble code for a MIPS chip. - Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Contributed by the OSF and Ralph Campbell. Written by Keith Knowles and Ralph Campbell, working independently. Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus @@ -54,7 +54,6 @@ static int mips_output_flavor () { return OUTPUT_FLAVOR; } #undef S_GET_SIZE #undef S_SET_ALIGN #undef S_SET_SIZE -#undef TARGET_SYMBOL_FIELDS #undef obj_frob_file #undef obj_frob_file_after_relocs #undef obj_frob_symbol @@ -1373,8 +1372,8 @@ mips16_mark_labels () if (OUTPUT_FLAVOR == bfd_target_elf_flavour) S_SET_OTHER (l->label, STO_MIPS16); #endif - if ((l->label->sy_value.X_add_number & 1) == 0) - ++l->label->sy_value.X_add_number; + if ((S_GET_VALUE (l->label) & 1) == 0) + S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); } } } @@ -1656,11 +1655,11 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) for (l = insn_labels; l != NULL; l = l->next) { assert (S_GET_SEGMENT (l->label) == now_seg); - l->label->sy_frag = frag_now; + symbol_set_frag (l->label, frag_now); S_SET_VALUE (l->label, (valueT) frag_now_fix ()); /* mips16 text labels are stored as odd. */ if (mips_opts.mips16) - ++l->label->sy_value.X_add_number; + S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); } #ifndef NO_ECOFF_DEBUGGING @@ -2360,11 +2359,11 @@ mips_emit_delays (insns) for (l = insn_labels; l != NULL; l = l->next) { assert (S_GET_SEGMENT (l->label) == now_seg); - l->label->sy_frag = frag_now; + symbol_set_frag (l->label, frag_now); S_SET_VALUE (l->label, (valueT) frag_now_fix ()); /* mips16 text labels are stored as odd. */ if (mips_opts.mips16) - ++l->label->sy_value.X_add_number; + S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); } } } @@ -4103,11 +4102,12 @@ macro (ip) if (mips_pic == EMBEDDED_PIC && offset_expr.X_op == O_subtract && now_seg == text_section - && (offset_expr.X_op_symbol->sy_value.X_op == O_constant + && (symbol_constant_p (offset_expr.X_op_symbol) ? S_GET_SEGMENT (offset_expr.X_op_symbol) == text_section - : (offset_expr.X_op_symbol->sy_value.X_op == O_symbol - && (S_GET_SEGMENT (offset_expr.X_op_symbol - ->sy_value.X_add_symbol) + : (symbol_equated_p (offset_expr.X_op_symbol) + && (S_GET_SEGMENT + (symbol_get_value_expression (offset_expr.X_op_symbol) + ->X_add_symbol) == text_section))) && breg == 0 && offset_expr.X_add_number == 0) @@ -6956,13 +6956,13 @@ mips_ip (str, ip) /* If the instruction contains a '.', we first try to match an instruction including the '.'. Then we try again without the '.'. */ insn = NULL; - for (s = str; *s != '\0' && !isspace(*s); ++s) + for (s = str; *s != '\0' && !isspace ((unsigned char) *s); ++s) continue; /* If we stopped on whitespace, then replace the whitespace with null for the call to hash_find. Save the character we replaced just in case we have to re-parse the instruction. */ - if (isspace (*s)) + if (isspace ((unsigned char) *s)) { save_c = *s; *s++ = '\0'; @@ -6980,7 +6980,7 @@ mips_ip (str, ip) *(--s) = save_c; /* Scan up to the first '.' or whitespace. */ - for (s = str; *s != '\0' && *s != '.' && !isspace (*s); ++s) + for (s = str; *s != '\0' && *s != '.' && !isspace ((unsigned char) *s); ++s) continue; /* If we did not find a '.', then we can quit now. */ @@ -7246,7 +7246,7 @@ mips_ip (str, ip) if (s[0] == '$') { - if (isdigit (s[1])) + if (isdigit ((unsigned char) s[1])) { ++s; regno = 0; @@ -7256,7 +7256,7 @@ mips_ip (str, ip) regno += *s - '0'; ++s; } - while (isdigit (*s)); + while (isdigit ((unsigned char) *s)); if (regno > 31) as_bad (_("Invalid register number (%d)"), regno); } @@ -7297,23 +7297,22 @@ mips_ip (str, ip) else if (itbl_have_entries) { char *p, *n; - int r; + unsigned long r; - p = s+1; /* advance past '$' */ + p = s + 1; /* advance past '$' */ n = itbl_get_field (&p); /* n is name */ - /* See if this is a register defined in an - itbl entry */ - r = itbl_get_reg_val (n); - if (r) + /* See if this is a register defined in an + itbl entry. */ + if (itbl_get_reg_val (n, &r)) { /* Get_field advances to the start of the next field, so we need to back - rack to the end of the last field. */ + rack to the end of the last field. */ if (p) s = p - 1; else - s = strchr (s,'\0'); + s = strchr (s, '\0'); regno = r; } else @@ -7406,7 +7405,7 @@ mips_ip (str, ip) case 'V': case 'W': s_reset = s; - if (s[0] == '$' && s[1] == 'f' && isdigit (s[2])) + if (s[0] == '$' && s[1] == 'f' && isdigit ((unsigned char) s[2])) { s += 2; regno = 0; @@ -7416,7 +7415,7 @@ mips_ip (str, ip) regno += *s - '0'; ++s; } - while (isdigit (*s)); + while (isdigit ((unsigned char) *s)); if (regno > 31) as_bad (_("Invalid float register number (%d)"), regno); @@ -7848,7 +7847,7 @@ mips_ip (str, ip) regno += *s - '0'; ++s; } - while (isdigit (*s)); + while (isdigit ((unsigned char) *s)); if (regno > 7) as_bad (_("invalid condition code register $fcc%d"), regno); if (*args == 'N') @@ -7901,7 +7900,7 @@ mips16_ip (str, ip) mips16_small = false; mips16_ext = false; - for (s = str; islower (*s); ++s) + for (s = str; islower ((unsigned char) *s); ++s) ; switch (*s) { @@ -8034,7 +8033,7 @@ mips16_ip (str, ip) if (s[0] != '$') break; s_reset = s; - if (isdigit (s[1])) + if (isdigit ((unsigned char) s[1])) { ++s; regno = 0; @@ -8044,7 +8043,7 @@ mips16_ip (str, ip) regno += *s - '0'; ++s; } - while (isdigit (*s)); + while (isdigit ((unsigned char) *s)); if (regno > 31) { as_bad (_("invalid register number (%d)"), regno); @@ -8315,7 +8314,7 @@ mips16_ip (str, ip) ++s; } reg1 = 0; - while (isdigit (*s)) + while (isdigit ((unsigned char) *s)) { reg1 *= 10; reg1 += *s - '0'; @@ -8342,7 +8341,7 @@ mips16_ip (str, ip) } } reg2 = 0; - while (isdigit (*s)) + while (isdigit ((unsigned char) *s)) { reg2 *= 10; reg2 += *s - '0'; @@ -8626,9 +8625,9 @@ my_getSmallExpression (ep, str) ; if (sp - 4 >= str && sp[-1] == RP) { - if (isdigit (sp[-2])) + if (isdigit ((unsigned char) sp[-2])) { - for (sp -= 3; sp >= str && isdigit (*sp); sp--) + for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--) ; if (*sp == '$' && sp > str && sp[-1] == LP) { @@ -8699,10 +8698,10 @@ my_getExpression (ep, str) && ep->X_op == O_symbol && strcmp (S_GET_NAME (ep->X_add_symbol), FAKE_LABEL_NAME) == 0 && S_GET_SEGMENT (ep->X_add_symbol) == now_seg - && ep->X_add_symbol->sy_frag == frag_now - && ep->X_add_symbol->sy_value.X_op == O_constant - && ep->X_add_symbol->sy_value.X_add_number == frag_now_fix ()) - ++ep->X_add_symbol->sy_value.X_add_number; + && symbol_get_frag (ep->X_add_symbol) == frag_now + && symbol_constant_p (ep->X_add_symbol) + && S_GET_VALUE (ep->X_add_symbol) == frag_now_fix ()) + S_SET_VALUE (ep->X_add_symbol, S_GET_VALUE (ep->X_add_symbol) + 1); } /* Turn a string in input_line_pointer into a floating point constant @@ -9472,13 +9471,13 @@ md_apply_fix (fixP, valueP) if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour) if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 || S_IS_WEAK (fixP->fx_addsy) - || (fixP->fx_addsy->sy_used_in_reloc - && (bfd_get_section_flags (stdoutput, - S_GET_SEGMENT (fixP->fx_addsy)) - & SEC_LINK_ONCE != 0) - || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), - ".gnu.linkonce", - sizeof (".gnu.linkonce") - 1))) + || (symbol_used_in_reloc_p (fixP->fx_addsy) + && (((bfd_get_section_flags (stdoutput, + S_GET_SEGMENT (fixP->fx_addsy)) + & SEC_LINK_ONCE) != 0) + || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), + ".gnu.linkonce", + sizeof (".gnu.linkonce") - 1)))) { value -= S_GET_VALUE (fixP->fx_addsy); @@ -9529,7 +9528,7 @@ md_apply_fix (fixP, valueP) case BFD_RELOC_PCREL_HI16_S: /* The addend for this is tricky if it is internal, so we just do everything here rather than in bfd_install_relocation. */ - if ((fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0) + if ((symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0) { /* For an external symbol adjust by the address to make it pcrel_offset. We use the address of the RELLO reloc @@ -9549,7 +9548,7 @@ md_apply_fix (fixP, valueP) case BFD_RELOC_PCREL_LO16: /* The addend for this is tricky if it is internal, so we just do everything here rather than in bfd_install_relocation. */ - if ((fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0) + if ((symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0) value += fixP->fx_frag->fr_address + fixP->fx_where; buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where; if (target_big_endian) @@ -9818,7 +9817,7 @@ mips_align (to, fill, label) if (label != NULL) { assert (S_GET_SEGMENT (label) == now_seg); - label->sy_frag = frag_now; + symbol_set_frag (label, frag_now); S_SET_VALUE (label, (valueT) frag_now_fix ()); } } @@ -10002,10 +10001,12 @@ s_float_cons (type) mips_emit_delays (false); if (auto_align) - if (type == 'd') - mips_align (3, 0, label); - else - mips_align (2, 0, label); + { + if (type == 'd') + mips_align (3, 0, label); + else + mips_align (2, 0, label); + } mips_clear_insn_labels (); @@ -10053,7 +10054,7 @@ s_mips_globl (x) flag = BSF_FUNCTION; } - symbolP->bsym->flags |= flag; + symbol_get_bfdsym (symbolP)->flags |= flag; S_SET_EXTERNAL (symbolP); demand_empty_rest_of_line (); @@ -10297,7 +10298,7 @@ s_cpload (ignore) ex.X_add_number = 0; /* In ELF, this symbol is implicitly an STT_OBJECT symbol. */ - ex.X_add_symbol->bsym->flags |= BSF_OBJECT; + symbol_get_bfdsym (ex.X_add_symbol)->flags |= BSF_OBJECT; macro_build_lui ((char *) NULL, &icnt, &ex, GP); macro_build ((char *) NULL, &icnt, &ex, "addiu", "t,r,j", GP, GP, @@ -10489,7 +10490,7 @@ s_mips_weakext (ignore) ignore_rest_of_line(); return; } - symbolP->sy_value = exp; + symbol_set_value_expression (symbolP, &exp); } demand_empty_rest_of_line (); @@ -10601,15 +10602,16 @@ nopic_need_relax (sym, before_relaxing) else if ((! S_IS_DEFINED (sym) || S_IS_COMMON (sym)) && (0 #ifndef NO_ECOFF_DEBUGGING - || (sym->ecoff_extern_size != 0 - && sym->ecoff_extern_size <= g_switch_value) + || (symbol_get_obj (sym)->ecoff_extern_size != 0 + && (symbol_get_obj (sym)->ecoff_extern_size + <= g_switch_value)) #endif /* We must defer this decision until after the whole file has been read, since there might be a .extern after the first use of this symbol. */ || (before_relaxing #ifndef NO_ECOFF_DEBUGGING - && sym->ecoff_extern_size == 0 + && symbol_get_obj (sym)->ecoff_extern_size == 0 #endif && S_GET_VALUE (sym) == 0) || (S_GET_VALUE (sym) != 0 @@ -10679,23 +10681,26 @@ mips16_extended_frag (fragp, sec, stretch) maxtiny = (1 << (op->nbits - 1)) - 1; } - /* We can't call S_GET_VALUE here, because we don't want to lock in - a particular frag address. */ - if (fragp->fr_symbol->sy_value.X_op == O_constant) + /* We can't always call S_GET_VALUE here, because we don't want to + lock in a particular frag address. */ + if (symbol_constant_p (fragp->fr_symbol)) { - val = (fragp->fr_symbol->sy_value.X_add_number - + fragp->fr_symbol->sy_frag->fr_address); + val = (S_GET_VALUE (fragp->fr_symbol) + + symbol_get_frag (fragp->fr_symbol)->fr_address); symsec = S_GET_SEGMENT (fragp->fr_symbol); } - else if (fragp->fr_symbol->sy_value.X_op == O_symbol - && (fragp->fr_symbol->sy_value.X_add_symbol->sy_value.X_op - == O_constant)) + else if (symbol_equated_p (fragp->fr_symbol) + && (symbol_constant_p + (symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol))) { - val = (fragp->fr_symbol->sy_value.X_add_symbol->sy_value.X_add_number - + fragp->fr_symbol->sy_value.X_add_symbol->sy_frag->fr_address - + fragp->fr_symbol->sy_value.X_add_number - + fragp->fr_symbol->sy_frag->fr_address); - symsec = S_GET_SEGMENT (fragp->fr_symbol->sy_value.X_add_symbol); + symbolS *eqsym; + + eqsym = symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol; + val = (S_GET_VALUE (eqsym) + + symbol_get_frag (eqsym)->fr_address + + symbol_get_value_expression (fragp->fr_symbol)->X_add_number + + symbol_get_frag (fragp->fr_symbol)->fr_address); + symsec = S_GET_SEGMENT (eqsym); } else return 1; @@ -10737,7 +10742,8 @@ mips16_extended_frag (fragp, sec, stretch) in STRETCH in order to get a better estimate of the address. This particularly matters because of the shift bits. */ if (stretch != 0 - && fragp->fr_symbol->sy_frag->fr_address >= fragp->fr_address) + && (symbol_get_frag (fragp->fr_symbol)->fr_address + >= fragp->fr_address)) { fragS *f; @@ -10748,7 +10754,7 @@ mips16_extended_frag (fragp, sec, stretch) a maximum number of bytes to skip when doing an alignment. */ for (f = fragp; - f != NULL && f != fragp->fr_symbol->sy_frag; + f != NULL && f != symbol_get_frag (fragp->fr_symbol); f = f->fr_next) { if (f->fr_type == rs_align || f->fr_type == rs_align_code) @@ -10882,14 +10888,14 @@ md_estimate_size_before_relax (fragp, segtype) sym = fragp->fr_symbol; /* Handle the case of a symbol equated to another symbol. */ - while (sym->sy_value.X_op == O_symbol + while (symbol_equated_p (sym) && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) { symbolS *n; /* It's possible to get a loop here in a badly written program. */ - n = sym->sy_value.X_add_symbol; + n = symbol_get_value_expression (sym)->X_add_symbol; if (n == sym) break; sym = n; @@ -10967,7 +10973,8 @@ tc_gen_reloc (section, fixp) reloc = retval[0] = (arelent *) xmalloc (sizeof (arelent)); retval[1] = NULL; - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; if (mips_pic == EMBEDDED_PIC @@ -10984,7 +10991,7 @@ tc_gen_reloc (section, fixp) else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16) { /* We use a special addend for an internal RELLO reloc. */ - if (fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) + if (symbol_section_p (fixp->fx_addsy)) reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy); else reloc->addend = fixp->fx_addnumber + reloc->address; @@ -10996,7 +11003,7 @@ tc_gen_reloc (section, fixp) /* We use a special addend for an internal RELHI reloc. The reloc is relative to the RELLO; adjust the addend accordingly. */ - if (fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) + if (symbol_section_p (fixp->fx_addsy)) reloc->addend = (fixp->fx_next->fx_frag->fr_address + fixp->fx_next->fx_where - S_GET_VALUE (fixp->fx_subsy)); @@ -11055,7 +11062,8 @@ tc_gen_reloc (section, fixp) reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc2 = retval[1] = (arelent *) xmalloc (sizeof (arelent)); retval[2] = NULL; - reloc2->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc2->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc2->address = (reloc->address + (RELAX_RELOC2 (fixp->fx_frag->fr_subtype) - RELAX_RELOC1 (fixp->fx_frag->fr_subtype))); @@ -11433,7 +11441,7 @@ mips_elf_final_processing () typedef struct proc { - struct symbol *isym; + symbolS *isym; unsigned long reg_mask; unsigned long reg_offset; unsigned long fpreg_mask; @@ -11472,14 +11480,14 @@ get_number () ++input_line_pointer; negative = 1; } - if (!isdigit (*input_line_pointer)) + if (!isdigit ((unsigned char) *input_line_pointer)) as_bad (_("Expected simple number.")); if (input_line_pointer[0] == '0') { if (input_line_pointer[1] == 'x') { input_line_pointer += 2; - while (isxdigit (*input_line_pointer)) + while (isxdigit ((unsigned char) *input_line_pointer)) { val <<= 4; val |= hex_value (*input_line_pointer++); @@ -11489,7 +11497,7 @@ get_number () else { ++input_line_pointer; - while (isdigit (*input_line_pointer)) + while (isdigit ((unsigned char) *input_line_pointer)) { val <<= 3; val |= *input_line_pointer++ - '0'; @@ -11497,14 +11505,14 @@ get_number () return negative ? -val : val; } } - if (!isdigit (*input_line_pointer)) + if (!isdigit ((unsigned char) *input_line_pointer)) { printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer, *input_line_pointer); as_warn (_("Invalid number")); return -1; } - while (isdigit (*input_line_pointer)) + while (isdigit ((unsigned char) *input_line_pointer)) { val *= 10; val += *input_line_pointer++ - '0'; @@ -11630,7 +11638,8 @@ s_mips_ent (aent) if (*input_line_pointer == ',') input_line_pointer++; SKIP_WHITESPACE (); - if (isdigit (*input_line_pointer) || *input_line_pointer == '-') + if (isdigit ((unsigned char) *input_line_pointer) + || *input_line_pointer == '-') number = get_number (); #ifdef BFD_ASSEMBLER @@ -11658,7 +11667,7 @@ s_mips_ent (aent) cur_proc_ptr->isym = symbolP; - symbolP->bsym->flags |= BSF_FUNCTION; + symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; numprocs++; } diff --git a/gas/config/tc-mips.h b/gas/config/tc-mips.h index 868aede..ccfd998 100644 --- a/gas/config/tc-mips.h +++ b/gas/config/tc-mips.h @@ -1,5 +1,5 @@ /* tc-mips.h -- header file for tc-mips.c. - Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1993, 94, 95, 96, 97, 1999 Free Software Foundation, Inc. Contributed by the OSF and Ralph Campbell. Written by Keith Knowles and Ralph Campbell, working independently. Modified for ECOFF support by Ian Lance Taylor of Cygnus Support. @@ -85,7 +85,7 @@ extern void mips_init_after_args PARAMS ((void)); extern int mips_parse_long_option PARAMS ((const char *)); #define tc_frob_label(sym) mips_define_label (sym) -extern void mips_define_label PARAMS ((struct symbol *)); +extern void mips_define_label PARAMS ((symbolS *)); #define tc_frob_file_before_adjust() mips_frob_file_before_adjust () extern void mips_frob_file_before_adjust PARAMS ((void)); diff --git a/gas/config/tc-mn10200.c b/gas/config/tc-mn10200.c index 2380915..264f7bf 100644 --- a/gas/config/tc-mn10200.c +++ b/gas/config/tc-mn10200.c @@ -1,6 +1,5 @@ /* tc-mn10200.c -- Assembler code for the Matsushita 10200 - - Copyright (C) 1996, 1997, 1998 Free Software Foundation. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -1252,7 +1251,8 @@ tc_gen_reloc (seg, fixp) } else { - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->addend = fixp->fx_offset; } return reloc; diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index 3f9e9ce..4f146d1 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -1,6 +1,5 @@ /* tc-mn10300.c -- Assembler code for the Matsushita 10300 - - Copyright (C) 1996, 1997, 1998 Free Software Foundation. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -1445,7 +1444,8 @@ tc_gen_reloc (seg, fixp) } else { - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof( asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->addend = fixp->fx_offset; } return reloc; diff --git a/gas/config/tc-ns32k.c b/gas/config/tc-ns32k.c index 42dc528..59f1467 100644 --- a/gas/config/tc-ns32k.c +++ b/gas/config/tc-ns32k.c @@ -1,5 +1,6 @@ /* ns32k.c -- Assemble on the National Semiconductor 32k series - Copyright (C) 1987, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -1970,7 +1971,7 @@ md_convert_frag (abfd, sec, fragP) /* The displacement of the address, from current location. */ disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address; #ifdef BFD_ASSEMBLER - disp += fragP->fr_symbol->sy_frag->fr_address; + disp += symbol_get_frag (fragP->fr_symbol)->fr_address; #endif disp += md_pcrel_adjust(fragP); @@ -2264,7 +2265,8 @@ tc_gen_reloc (section, fixp) code = reloc(fixp->fx_size, fixp->fx_pcrel, fix_im_disp(fixp)); rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = &fixp->fx_addsy->bsym; + rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; if (fixp->fx_pcrel) rel->addend = fixp->fx_addnumber; diff --git a/gas/config/tc-ns32k.h b/gas/config/tc-ns32k.h index 4b038eb..69c86ec 100644 --- a/gas/config/tc-ns32k.h +++ b/gas/config/tc-ns32k.h @@ -1,5 +1,5 @@ /* tc-ns32k.h -- Opcode table for National Semi 32k processor - Copyright (C) 1987, 92, 93, 94, 95, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 92, 93, 94, 95, 97, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -76,7 +76,7 @@ extern void fix_new_ns32k_exp PARAMS((fragS *frag, extern void fix_new_ns32k PARAMS ((fragS *frag, int where, int size, - struct symbol *add_symbol, + symbolS *add_symbol, long offset, int pcrel, int im_disp, diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 8c31ba6..56c2a48 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -1,5 +1,5 @@ /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000) - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GAS, the GNU Assembler. @@ -766,6 +766,11 @@ md_parse_option (c, arg) ppc_cpu = PPC_OPCODE_PPC; ppc_size = PPC_OPCODE_64; } + else if (strcmp (arg, "ppc64bridge") == 0) + { + ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE; + ppc_size = PPC_OPCODE_64; + } /* -mcom means assemble for the common intersection between Power and PowerPC. At present, we just allow the union, rather than the intersection. */ @@ -872,6 +877,7 @@ PowerPC options:\n\ -mppc, -mppc32, -m403, -m603, -m604\n\ generate code for Motorola PowerPC 603/604\n\ -mppc64, -m620 generate code for Motorola PowerPC 620\n\ +-mppc64bridge generate code for PowerPC 64, including bridge insns\n\ -mcom generate code Power/PowerPC common instructions\n\ -many generate code for any architecture (PWR/PWRX/PPC)\n\ -mregnames Allow symbolic names for registers\n\ @@ -972,7 +978,8 @@ md_begin () if ((op->flags & ppc_cpu) != 0 && ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0 - || (op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == ppc_size)) + || (op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == ppc_size + || (ppc_cpu & PPC_OPCODE_64_BRIDGE) != 0)) { const char *retval; @@ -1026,9 +1033,9 @@ md_begin () text csects to precede the data csects. These symbols will not be output. */ ppc_text_csects = symbol_make ("dummy\001"); - ppc_text_csects->sy_tc.within = ppc_text_csects; + symbol_get_tc (ppc_text_csects)->within = ppc_text_csects; ppc_data_csects = symbol_make ("dummy\001"); - ppc_data_csects->sy_tc.within = ppc_data_csects; + symbol_get_tc (ppc_data_csects)->within = ppc_data_csects; #endif #ifdef TE_PE @@ -1056,8 +1063,7 @@ ppc_insert_operand (insn, operand, val, file, line) if ((operand->flags & PPC_OPERAND_SIGNED) != 0) { - if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0 - && ppc_size == PPC_OPCODE_32) + if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0) max = (1 << operand->bits) - 1; else max = (1 << (operand->bits - 1)) - 1; @@ -1399,8 +1405,8 @@ ppc_elf_lcomm(xxx) if (align2) frag_align (align2, 0, 0); if (S_GET_SEGMENT (symbolP) == bss_section) - symbolP->sy_frag->fr_symbol = 0; - symbolP->sy_frag = frag_now; + symbol_get_frag (symbolP)->fr_symbol = 0; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size, (char *) 0); *pfrag = 0; @@ -1777,7 +1783,8 @@ md_assemble (str) if (ex.X_op == O_symbol) { assert (ex.X_add_symbol != NULL); - if (ex.X_add_symbol->bsym->section != tocdata_section) + if (symbol_get_bfdsym (ex.X_add_symbol)->section + != tocdata_section) { as_bad(_("[tocv] symbol is not a toc symbol")); } @@ -2120,29 +2127,25 @@ ppc_section_letter (letter, ptr_msg) } int -ppc_section_word (ptr_str) - char **ptr_str; +ppc_section_word (str, len) + char *str; + size_t len; { - if (strncmp (*ptr_str, "exclude", sizeof ("exclude")-1) == 0) - { - *ptr_str += sizeof ("exclude")-1; - return SHF_EXCLUDE; - } + if (len == 7 && strncmp (str, "exclude", 7) == 0) + return SHF_EXCLUDE; - return 0; + return -1; } int -ppc_section_type (ptr_str) - char **ptr_str; +ppc_section_type (str, len) + char *str; + size_t len; { - if (strncmp (*ptr_str, "ordered", sizeof ("ordered")-1) == 0) - { - *ptr_str += sizeof ("ordered")-1; - return SHT_ORDERED; - } + if (len == 7 && strncmp (str, "ordered", 7) == 0) + return SHT_ORDERED; - return 0; + return -1; } int @@ -2325,7 +2328,7 @@ ppc_comm (lcomm) } else { - lcomm_sym->sy_tc.output = 1; + symbol_get_tc (lcomm_sym)->output = 1; def_sym = lcomm_sym; def_size = 0; } @@ -2333,30 +2336,30 @@ ppc_comm (lcomm) subseg_set (bss_section, 1); frag_align (align, 0, 0); - def_sym->sy_frag = frag_now; + symbol_set_frag (def_sym, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym, def_size, (char *) NULL); *pfrag = 0; S_SET_SEGMENT (def_sym, bss_section); - def_sym->sy_tc.align = align; + symbol_get_tc (def_sym)->align = align; } else if (lcomm) { /* Align the size of lcomm_sym. */ - lcomm_sym->sy_frag->fr_offset = - ((lcomm_sym->sy_frag->fr_offset + (1 << align) - 1) + symbol_get_frag (lcomm_sym)->fr_offset = + ((symbol_get_frag (lcomm_sym)->fr_offset + (1 << align) - 1) &~ ((1 << align) - 1)); - if (align > lcomm_sym->sy_tc.align) - lcomm_sym->sy_tc.align = align; + if (align > symbol_get_tc (lcomm_sym)->align) + symbol_get_tc (lcomm_sym)->align = align; } if (lcomm) { /* Make sym an offset from lcomm_sym. */ S_SET_SEGMENT (sym, bss_section); - sym->sy_frag = lcomm_sym->sy_frag; - S_SET_VALUE (sym, lcomm_sym->sy_frag->fr_offset); - lcomm_sym->sy_frag->fr_offset += size; + symbol_set_frag (sym, symbol_get_frag (lcomm_sym)); + S_SET_VALUE (sym, symbol_get_frag (lcomm_sym)->fr_offset); + symbol_get_frag (lcomm_sym)->fr_offset += size; } subseg_set (current_seg, current_subseg); @@ -2388,7 +2391,7 @@ ppc_csect (ignore) if (S_GET_NAME (sym)[0] == '\0') { /* An unnamed csect is assumed to be [PR]. */ - sym->sy_tc.class = XMC_PR; + symbol_get_tc (sym)->class = XMC_PR; } ppc_change_csect (sym); @@ -2396,7 +2399,7 @@ ppc_csect (ignore) if (*input_line_pointer == ',') { ++input_line_pointer; - sym->sy_tc.align = get_absolute_expression (); + symbol_get_tc (sym)->align = get_absolute_expression (); } demand_empty_rest_of_line (); @@ -2409,7 +2412,7 @@ ppc_change_csect (sym) symbolS *sym; { if (S_IS_DEFINED (sym)) - subseg_set (S_GET_SEGMENT (sym), sym->sy_tc.subseg); + subseg_set (S_GET_SEGMENT (sym), symbol_get_tc (sym)->subseg); else { symbolS **list_ptr; @@ -2421,7 +2424,7 @@ ppc_change_csect (sym) figure out whether it should go in the text section or the data section. */ after_toc = 0; - switch (sym->sy_tc.class) + switch (symbol_get_tc (sym)->class) { case XMC_PR: case XMC_RO: @@ -2432,7 +2435,7 @@ ppc_change_csect (sym) case XMC_TI: case XMC_TB: S_SET_SEGMENT (sym, text_section); - sym->sy_tc.subseg = ppc_text_subsegment; + symbol_get_tc (sym)->subseg = ppc_text_subsegment; ++ppc_text_subsegment; list_ptr = &ppc_text_csects; break; @@ -2444,10 +2447,11 @@ ppc_change_csect (sym) case XMC_BS: case XMC_UC: if (ppc_toc_csect != NULL - && ppc_toc_csect->sy_tc.subseg + 1 == ppc_data_subsegment) + && (symbol_get_tc (ppc_toc_csect)->subseg + 1 + == ppc_data_subsegment)) after_toc = 1; S_SET_SEGMENT (sym, data_section); - sym->sy_tc.subseg = ppc_data_subsegment; + symbol_get_tc (sym)->subseg = ppc_data_subsegment; ++ppc_data_subsegment; list_ptr = &ppc_data_csects; break; @@ -2461,28 +2465,30 @@ ppc_change_csect (sym) hold_chunksize = chunksize; chunksize = 64; - subseg_new (segment_name (S_GET_SEGMENT (sym)), sym->sy_tc.subseg); + subseg_new (segment_name (S_GET_SEGMENT (sym)), + symbol_get_tc (sym)->subseg); chunksize = hold_chunksize; if (after_toc) ppc_after_toc_frag = frag_now; - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, (valueT) frag_now_fix ()); - sym->sy_tc.align = 2; - sym->sy_tc.output = 1; - sym->sy_tc.within = sym; + symbol_get_tc (sym)->align = 2; + symbol_get_tc (sym)->output = 1; + symbol_get_tc (sym)->within = sym; for (list = *list_ptr; - list->sy_tc.next != (symbolS *) NULL; - list = list->sy_tc.next) + symbol_get_tc (list)->next != (symbolS *) NULL; + list = symbol_get_tc (list)->next) ; - list->sy_tc.next = sym; + symbol_get_tc (list)->next = sym; symbol_remove (sym, &symbol_rootP, &symbol_lastP); - symbol_append (sym, list->sy_tc.within, &symbol_rootP, &symbol_lastP); + symbol_append (sym, symbol_get_tc (list)->within, &symbol_rootP, + &symbol_lastP); } ppc_current_csect = sym; @@ -2586,7 +2592,7 @@ ppc_lglobl (ignore) *input_line_pointer = endc; - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; demand_empty_rest_of_line (); } @@ -2618,7 +2624,7 @@ ppc_rename (ignore) } ++input_line_pointer; - sym->sy_tc.real_name = demand_copy_C_string (&len); + symbol_get_tc (sym)->real_name = demand_copy_C_string (&len); demand_empty_rest_of_line (); } @@ -2652,7 +2658,7 @@ ppc_stabx (ignore) sym = symbol_make (name); ppc_stab_symbol = false; - sym->sy_tc.real_name = name; + symbol_get_tc (sym)->real_name = name; (void) expression (&exp); @@ -2666,17 +2672,17 @@ ppc_stabx (ignore) /* Fall through. */ case O_constant: S_SET_VALUE (sym, (valueT) exp.X_add_number); - sym->sy_frag = &zero_address_frag; + symbol_set_frag (sym, &zero_address_frag); break; case O_symbol: if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section) - sym->sy_value = exp; + symbol_set_value_expression (sym, &exp); else { S_SET_VALUE (sym, exp.X_add_number + S_GET_VALUE (exp.X_add_symbol)); - sym->sy_frag = exp.X_add_symbol->sy_frag; + symbol_set_frag (sym, symbol_get_frag (exp.X_add_symbol)); } break; @@ -2684,12 +2690,12 @@ ppc_stabx (ignore) /* The value is some complex expression. This will probably fail at some later point, but this is probably the right thing to do here. */ - sym->sy_value = exp; + symbol_set_value_expression (sym, &exp); break; } S_SET_SEGMENT (sym, ppc_coff_debug_section); - sym->bsym->flags |= BSF_DEBUGGING; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; if (*input_line_pointer != ',') { @@ -2709,10 +2715,10 @@ ppc_stabx (ignore) S_SET_DATA_TYPE (sym, get_absolute_expression ()); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; if (S_GET_STORAGE_CLASS (sym) == C_STSYM) - sym->sy_tc.within = ppc_current_block; + symbol_get_tc (sym)->within = ppc_current_block; if (exp.X_op != O_symbol || ! S_IS_EXTERNAL (exp.X_add_symbol) @@ -2722,8 +2728,8 @@ ppc_stabx (ignore) { symbol_remove (sym, &symbol_rootP, &symbol_lastP); symbol_append (sym, exp.X_add_symbol, &symbol_rootP, &symbol_lastP); - if (ppc_current_csect->sy_tc.within == exp.X_add_symbol) - ppc_current_csect->sy_tc.within = sym; + if (symbol_get_tc (ppc_current_csect)->within == exp.X_add_symbol) + symbol_get_tc (ppc_current_csect)->within = sym; } demand_empty_rest_of_line (); @@ -2778,15 +2784,19 @@ ppc_function (ignore) if (ext_sym != lab_sym) { - ext_sym->sy_value.X_op = O_symbol; - ext_sym->sy_value.X_add_symbol = lab_sym; - ext_sym->sy_value.X_op_symbol = NULL; - ext_sym->sy_value.X_add_number = 0; + expressionS exp; + + exp.X_op = O_symbol; + exp.X_add_symbol = lab_sym; + exp.X_op_symbol = NULL; + exp.X_add_number = 0; + exp.X_unsigned = 0; + symbol_set_value_expression (ext_sym, &exp); } - if (ext_sym->sy_tc.class == -1) - ext_sym->sy_tc.class = XMC_PR; - ext_sym->sy_tc.output = 1; + if (symbol_get_tc (ext_sym)->class == -1) + symbol_get_tc (ext_sym)->class = XMC_PR; + symbol_get_tc (ext_sym)->output = 1; if (*input_line_pointer == ',') { @@ -2804,11 +2814,11 @@ ppc_function (ignore) { /* The fifth argument is the function size. */ ++input_line_pointer; - ext_sym->sy_tc.size = symbol_new ("L0\001", - absolute_section, - (valueT) 0, - &zero_address_frag); - pseudo_set (ext_sym->sy_tc.size); + symbol_get_tc (ext_sym)->size = symbol_new ("L0\001", + absolute_section, + (valueT) 0, + &zero_address_frag); + pseudo_set (symbol_get_tc (ext_sym)->size); } } } @@ -2832,7 +2842,7 @@ ppc_bf (ignore) sym = symbol_make (".bf"); S_SET_SEGMENT (sym, text_section); - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, frag_now_fix ()); S_SET_STORAGE_CLASS (sym, C_FCN); @@ -2841,7 +2851,7 @@ ppc_bf (ignore) S_SET_NUMBER_AUXILIARY (sym, 1); SA_SET_SYM_LNNO (sym, coff_line_base); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; ppc_frob_label (sym); @@ -2860,12 +2870,12 @@ ppc_ef (ignore) sym = symbol_make (".ef"); S_SET_SEGMENT (sym, text_section); - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, frag_now_fix ()); S_SET_STORAGE_CLASS (sym, C_FCN); S_SET_NUMBER_AUXILIARY (sym, 1); SA_SET_SYM_LNNO (sym, get_absolute_expression ()); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; ppc_frob_label (sym); @@ -2899,10 +2909,10 @@ ppc_biei (ei) .text section. */ S_SET_SEGMENT (sym, text_section); S_SET_VALUE (sym, coff_n_line_nos); - sym->bsym->flags |= BSF_DEBUGGING; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; S_SET_STORAGE_CLASS (sym, ei ? C_EINCL : C_BINCL); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; for (look = last_biei ? last_biei : symbol_rootP; (look != (symbolS *) NULL @@ -2947,10 +2957,10 @@ ppc_bs (ignore) sym = symbol_make (".bs"); S_SET_SEGMENT (sym, now_seg); S_SET_STORAGE_CLASS (sym, C_BSTAT); - sym->bsym->flags |= BSF_DEBUGGING; - sym->sy_tc.output = 1; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; + symbol_get_tc (sym)->output = 1; - sym->sy_tc.within = csect; + symbol_get_tc (sym)->within = csect; ppc_frob_label (sym); @@ -2973,8 +2983,8 @@ ppc_es (ignore) sym = symbol_make (".es"); S_SET_SEGMENT (sym, now_seg); S_SET_STORAGE_CLASS (sym, C_ESTAT); - sym->bsym->flags |= BSF_DEBUGGING; - sym->sy_tc.output = 1; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; + symbol_get_tc (sym)->output = 1; ppc_frob_label (sym); @@ -2994,14 +3004,14 @@ ppc_bb (ignore) sym = symbol_make (".bb"); S_SET_SEGMENT (sym, text_section); - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, frag_now_fix ()); S_SET_STORAGE_CLASS (sym, C_BLOCK); S_SET_NUMBER_AUXILIARY (sym, 1); SA_SET_SYM_LNNO (sym, get_absolute_expression ()); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; SF_SET_PROCESS (sym); @@ -3021,12 +3031,12 @@ ppc_eb (ignore) sym = symbol_make (".eb"); S_SET_SEGMENT (sym, text_section); - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, frag_now_fix ()); S_SET_STORAGE_CLASS (sym, C_BLOCK); S_SET_NUMBER_AUXILIARY (sym, 1); SA_SET_SYM_LNNO (sym, get_absolute_expression ()); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; SF_SET_PROCESS (sym); @@ -3049,10 +3059,10 @@ ppc_bc (ignore) name = demand_copy_C_string (&len); sym = symbol_make (name); S_SET_SEGMENT (sym, ppc_coff_debug_section); - sym->bsym->flags |= BSF_DEBUGGING; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; S_SET_STORAGE_CLASS (sym, C_BCOMM); S_SET_VALUE (sym, 0); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; ppc_frob_label (sym); @@ -3069,10 +3079,10 @@ ppc_ec (ignore) sym = symbol_make (".ec"); S_SET_SEGMENT (sym, ppc_coff_debug_section); - sym->bsym->flags |= BSF_DEBUGGING; + symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING; S_SET_STORAGE_CLASS (sym, C_ECOMM); S_SET_VALUE (sym, 0); - sym->sy_tc.output = 1; + symbol_get_tc (sym)->output = 1; ppc_frob_label (sym); @@ -3086,7 +3096,7 @@ ppc_toc (ignore) int ignore; { if (ppc_toc_csect != (symbolS *) NULL) - subseg_set (data_section, ppc_toc_csect->sy_tc.subseg); + subseg_set (data_section, symbol_get_tc (ppc_toc_csect)->subseg); else { subsegT subseg; @@ -3100,23 +3110,24 @@ ppc_toc (ignore) ppc_toc_frag = frag_now; sym = symbol_find_or_make ("TOC[TC0]"); - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_SEGMENT (sym, data_section); S_SET_VALUE (sym, (valueT) frag_now_fix ()); - sym->sy_tc.subseg = subseg; - sym->sy_tc.output = 1; - sym->sy_tc.within = sym; + symbol_get_tc (sym)->subseg = subseg; + symbol_get_tc (sym)->output = 1; + symbol_get_tc (sym)->within = sym; ppc_toc_csect = sym; for (list = ppc_data_csects; - list->sy_tc.next != (symbolS *) NULL; - list = list->sy_tc.next) + symbol_get_tc (list)->next != (symbolS *) NULL; + list = symbol_get_tc (list)->next) ; - list->sy_tc.next = sym; + symbol_get_tc (list)->next = sym; symbol_remove (sym, &symbol_rootP, &symbol_lastP); - symbol_append (sym, list->sy_tc.within, &symbol_rootP, &symbol_lastP); + symbol_append (sym, symbol_get_tc (list)->within, &symbol_rootP, + &symbol_lastP); } ppc_current_csect = ppc_toc_csect; @@ -3208,8 +3219,8 @@ ppc_tc (ignore) { symbolS *label; - label = ppc_current_csect->sy_tc.within; - if (label->sy_tc.class != XMC_TC0) + label = symbol_get_tc (ppc_current_csect)->within; + if (symbol_get_tc (label)->class != XMC_TC0) { as_bad (_(".tc with no label")); ignore_rest_of_line (); @@ -3217,7 +3228,7 @@ ppc_tc (ignore) } S_SET_SEGMENT (label, S_GET_SEGMENT (sym)); - label->sy_frag = sym->sy_frag; + symbol_set_frag (label, symbol_get_frag (sym)); S_SET_VALUE (label, S_GET_VALUE (sym)); while (! is_end_of_line[(unsigned char) *input_line_pointer]) @@ -3227,10 +3238,10 @@ ppc_tc (ignore) } S_SET_SEGMENT (sym, now_seg); - sym->sy_frag = frag_now; + symbol_set_frag (sym, frag_now); S_SET_VALUE (sym, (valueT) frag_now_fix ()); - sym->sy_tc.class = XMC_TC; - sym->sy_tc.output = 1; + symbol_get_tc (sym)->class = XMC_TC; + symbol_get_tc (sym)->output = 1; ppc_frob_label (sym); } @@ -3910,16 +3921,18 @@ void ppc_symbol_new_hook (sym) symbolS *sym; { + struct ppc_tc_sy *tc; const char *s; - sym->sy_tc.next = NULL; - sym->sy_tc.output = 0; - sym->sy_tc.class = -1; - sym->sy_tc.real_name = NULL; - sym->sy_tc.subseg = 0; - sym->sy_tc.align = 0; - sym->sy_tc.size = NULL; - sym->sy_tc.within = NULL; + tc = symbol_get_tc (sym); + tc->next = NULL; + tc->output = 0; + tc->class = -1; + tc->real_name = NULL; + tc->subseg = 0; + tc->align = 0; + tc->size = NULL; + tc->within = NULL; if (ppc_stab_symbol) return; @@ -3937,55 +3950,55 @@ ppc_symbol_new_hook (sym) { case 'B': if (strcmp (s, "BS]") == 0) - sym->sy_tc.class = XMC_BS; + tc->class = XMC_BS; break; case 'D': if (strcmp (s, "DB]") == 0) - sym->sy_tc.class = XMC_DB; + tc->class = XMC_DB; else if (strcmp (s, "DS]") == 0) - sym->sy_tc.class = XMC_DS; + tc->class = XMC_DS; break; case 'G': if (strcmp (s, "GL]") == 0) - sym->sy_tc.class = XMC_GL; + tc->class = XMC_GL; break; case 'P': if (strcmp (s, "PR]") == 0) - sym->sy_tc.class = XMC_PR; + tc->class = XMC_PR; break; case 'R': if (strcmp (s, "RO]") == 0) - sym->sy_tc.class = XMC_RO; + tc->class = XMC_RO; else if (strcmp (s, "RW]") == 0) - sym->sy_tc.class = XMC_RW; + tc->class = XMC_RW; break; case 'S': if (strcmp (s, "SV]") == 0) - sym->sy_tc.class = XMC_SV; + tc->class = XMC_SV; break; case 'T': if (strcmp (s, "TC]") == 0) - sym->sy_tc.class = XMC_TC; + tc->class = XMC_TC; else if (strcmp (s, "TI]") == 0) - sym->sy_tc.class = XMC_TI; + tc->class = XMC_TI; else if (strcmp (s, "TB]") == 0) - sym->sy_tc.class = XMC_TB; + tc->class = XMC_TB; else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0) - sym->sy_tc.class = XMC_TC0; + tc->class = XMC_TC0; break; case 'U': if (strcmp (s, "UA]") == 0) - sym->sy_tc.class = XMC_UA; + tc->class = XMC_UA; else if (strcmp (s, "UC]") == 0) - sym->sy_tc.class = XMC_UC; + tc->class = XMC_UC; break; case 'X': if (strcmp (s, "XO]") == 0) - sym->sy_tc.class = XMC_XO; + tc->class = XMC_XO; break; } - if (sym->sy_tc.class == -1) + if (tc->class == -1) as_bad (_("Unrecognized symbol suffix")); } @@ -3999,13 +4012,13 @@ ppc_frob_label (sym) { if (ppc_current_csect != (symbolS *) NULL) { - if (sym->sy_tc.class == -1) - sym->sy_tc.class = ppc_current_csect->sy_tc.class; + if (symbol_get_tc (sym)->class == -1) + symbol_get_tc (sym)->class = symbol_get_tc (ppc_current_csect)->class; symbol_remove (sym, &symbol_rootP, &symbol_lastP); - symbol_append (sym, ppc_current_csect->sy_tc.within, &symbol_rootP, - &symbol_lastP); - ppc_current_csect->sy_tc.within = sym; + symbol_append (sym, symbol_get_tc (ppc_current_csect)->within, + &symbol_rootP, &symbol_lastP); + symbol_get_tc (ppc_current_csect)->within = sym; } } @@ -4029,15 +4042,15 @@ ppc_frob_symbol (sym) /* Discard symbols that should not be included in the output symbol table. */ - if (! sym->sy_used_in_reloc - && ((sym->bsym->flags & BSF_SECTION_SYM) != 0 + if (! symbol_used_in_reloc_p (sym) + && ((symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0 || (! S_IS_EXTERNAL (sym) - && ! sym->sy_tc.output + && ! symbol_get_tc (sym)->output && S_GET_STORAGE_CLASS (sym) != C_FILE))) return 1; - if (sym->sy_tc.real_name != (char *) NULL) - S_SET_NAME (sym, sym->sy_tc.real_name); + if (symbol_get_tc (sym)->real_name != (char *) NULL) + S_SET_NAME (sym, symbol_get_tc (sym)->real_name); else { const char *name; @@ -4070,10 +4083,11 @@ ppc_frob_symbol (sym) if (ppc_last_function != (symbolS *) NULL) as_bad (_("two .function pseudo-ops with no intervening .ef")); ppc_last_function = sym; - if (sym->sy_tc.size != (symbolS *) NULL) + if (symbol_get_tc (sym)->size != (symbolS *) NULL) { - resolve_symbol_value (sym->sy_tc.size, 1); - SA_SET_SYM_FSIZE (sym, (long) S_GET_VALUE (sym->sy_tc.size)); + resolve_symbol_value (symbol_get_tc (sym)->size, 1); + SA_SET_SYM_FSIZE (sym, + (long) S_GET_VALUE (symbol_get_tc (sym)->size)); } } else if (S_GET_STORAGE_CLASS (sym) == C_FCN @@ -4093,7 +4107,7 @@ ppc_frob_symbol (sym) } if (! S_IS_EXTERNAL (sym) - && (sym->bsym->flags & BSF_SECTION_SYM) == 0 + && (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) == 0 && S_GET_STORAGE_CLASS (sym) != C_FILE && S_GET_STORAGE_CLASS (sym) != C_FCN && S_GET_STORAGE_CLASS (sym) != C_BLOCK @@ -4113,39 +4127,39 @@ ppc_frob_symbol (sym) /* Create a csect aux. */ i = S_GET_NUMBER_AUXILIARY (sym); S_SET_NUMBER_AUXILIARY (sym, i + 1); - a = &coffsymbol (sym->bsym)->native[i + 1].u.auxent; - if (sym->sy_tc.class == XMC_TC0) + a = &coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].u.auxent; + if (symbol_get_tc (sym)->class == XMC_TC0) { /* This is the TOC table. */ know (strcmp (S_GET_NAME (sym), "TOC") == 0); a->x_csect.x_scnlen.l = 0; a->x_csect.x_smtyp = (2 << 3) | XTY_SD; } - else if (sym->sy_tc.subseg != 0) + else if (symbol_get_tc (sym)->subseg != 0) { /* This is a csect symbol. x_scnlen is the size of the csect. */ - if (sym->sy_tc.next == (symbolS *) NULL) + if (symbol_get_tc (sym)->next == (symbolS *) NULL) a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput, S_GET_SEGMENT (sym)) - S_GET_VALUE (sym)); else { - resolve_symbol_value (sym->sy_tc.next, 1); - a->x_csect.x_scnlen.l = (S_GET_VALUE (sym->sy_tc.next) + resolve_symbol_value (symbol_get_tc (sym)->next, 1); + a->x_csect.x_scnlen.l = (S_GET_VALUE (symbol_get_tc (sym)->next) - S_GET_VALUE (sym)); } - a->x_csect.x_smtyp = (sym->sy_tc.align << 3) | XTY_SD; + a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_SD; } else if (S_GET_SEGMENT (sym) == bss_section) { /* This is a common symbol. */ - a->x_csect.x_scnlen.l = sym->sy_frag->fr_offset; - a->x_csect.x_smtyp = (sym->sy_tc.align << 3) | XTY_CM; + a->x_csect.x_scnlen.l = symbol_get_frag (sym)->fr_offset; + a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_CM; if (S_IS_EXTERNAL (sym)) - sym->sy_tc.class = XMC_RW; + symbol_get_tc (sym)->class = XMC_RW; else - sym->sy_tc.class = XMC_BS; + symbol_get_tc (sym)->class = XMC_BS; } else if (S_GET_SEGMENT (sym) == absolute_section) { @@ -4153,8 +4167,8 @@ ppc_frob_symbol (sym) ppc_adjust_symtab. */ ppc_saw_abs = true; a->x_csect.x_smtyp = XTY_LD; - if (sym->sy_tc.class == -1) - sym->sy_tc.class = XMC_XO; + if (symbol_get_tc (sym)->class == -1) + symbol_get_tc (sym)->class = XMC_XO; } else if (! S_IS_DEFINED (sym)) { @@ -4162,17 +4176,17 @@ ppc_frob_symbol (sym) a->x_csect.x_scnlen.l = 0; a->x_csect.x_smtyp = XTY_ER; } - else if (sym->sy_tc.class == XMC_TC) + else if (symbol_get_tc (sym)->class == XMC_TC) { symbolS *next; /* This is a TOC definition. x_scnlen is the size of the TOC entry. */ next = symbol_next (sym); - while (next->sy_tc.class == XMC_TC0) + while (symbol_get_tc (next)->class == XMC_TC0) next = symbol_next (next); if (next == (symbolS *) NULL - || next->sy_tc.class != XMC_TC) + || symbol_get_tc (next)->class != XMC_TC) { if (ppc_after_toc_frag == (fragS *) NULL) a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput, @@ -4204,7 +4218,7 @@ ppc_frob_symbol (sym) abort (); /* Skip the initial dummy symbol. */ - csect = csect->sy_tc.next; + csect = symbol_get_tc (csect)->next; if (csect == (symbolS *) NULL) { @@ -4213,31 +4227,34 @@ ppc_frob_symbol (sym) } else { - while (csect->sy_tc.next != (symbolS *) NULL) + while (symbol_get_tc (csect)->next != (symbolS *) NULL) { - resolve_symbol_value (csect->sy_tc.next, 1); - if (S_GET_VALUE (csect->sy_tc.next) > S_GET_VALUE (sym)) + resolve_symbol_value (symbol_get_tc (csect)->next, 1); + if (S_GET_VALUE (symbol_get_tc (csect)->next) + > S_GET_VALUE (sym)) break; - csect = csect->sy_tc.next; + csect = symbol_get_tc (csect)->next; } - a->x_csect.x_scnlen.p = coffsymbol (csect->bsym)->native; - coffsymbol (sym->bsym)->native[i + 1].fix_scnlen = 1; + a->x_csect.x_scnlen.p = + coffsymbol (symbol_get_bfdsym (csect))->native; + coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].fix_scnlen = + 1; } a->x_csect.x_smtyp = XTY_LD; } a->x_csect.x_parmhash = 0; a->x_csect.x_snhash = 0; - if (sym->sy_tc.class == -1) + if (symbol_get_tc (sym)->class == -1) a->x_csect.x_smclas = XMC_PR; else - a->x_csect.x_smclas = sym->sy_tc.class; + a->x_csect.x_smclas = symbol_get_tc (sym)->class; a->x_csect.x_stab = 0; a->x_csect.x_snstab = 0; /* Don't let the COFF backend resort these symbols. */ - sym->bsym->flags |= BSF_NOT_AT_END; + symbol_get_bfdsym (sym)->flags |= BSF_NOT_AT_END; } else if (S_GET_STORAGE_CLASS (sym) == C_BSTAT) { @@ -4245,8 +4262,10 @@ ppc_frob_symbol (sym) csect symbol. BFD will do that for us if we set the right flags. */ S_SET_VALUE (sym, - (valueT) coffsymbol (sym->sy_tc.within->bsym)->native); - coffsymbol (sym->bsym)->native->fix_value = 1; + ((valueT) + coffsymbol (symbol_get_bfdsym + (symbol_get_tc (sym)->within))->native)); + coffsymbol (symbol_get_bfdsym (sym))->native->fix_value = 1; } else if (S_GET_STORAGE_CLASS (sym) == C_STSYM) { @@ -4254,8 +4273,8 @@ ppc_frob_symbol (sym) symbolS *csect; /* The value is the offset from the enclosing csect. */ - block = sym->sy_tc.within; - csect = block->sy_tc.within; + block = symbol_get_tc (sym)->within; + csect = symbol_get_tc (block)->within; resolve_symbol_value (csect, 1); S_SET_VALUE (sym, S_GET_VALUE (sym) - S_GET_VALUE (csect)); } @@ -4265,7 +4284,7 @@ ppc_frob_symbol (sym) /* We want the value to be a file offset into the line numbers. BFD will do that for us if we set the right flags. We have already set the value correctly. */ - coffsymbol (sym->bsym)->native->fix_line = 1; + coffsymbol (symbol_get_bfdsym (sym))->native->fix_line = 1; } return 0; @@ -4293,11 +4312,11 @@ ppc_adjust_symtab () csect = symbol_create (".abs[XO]", absolute_section, S_GET_VALUE (sym), &zero_address_frag); - csect->bsym->value = S_GET_VALUE (sym); + symbol_get_bfdsym (csect)->value = S_GET_VALUE (sym); S_SET_STORAGE_CLASS (csect, C_HIDEXT); i = S_GET_NUMBER_AUXILIARY (csect); S_SET_NUMBER_AUXILIARY (csect, i + 1); - a = &coffsymbol (csect->bsym)->native[i + 1].u.auxent; + a = &coffsymbol (symbol_get_bfdsym (csect))->native[i + 1].u.auxent; a->x_csect.x_scnlen.l = 0; a->x_csect.x_smtyp = XTY_SD; a->x_csect.x_parmhash = 0; @@ -4309,9 +4328,9 @@ ppc_adjust_symtab () symbol_insert (csect, sym, &symbol_rootP, &symbol_lastP); i = S_GET_NUMBER_AUXILIARY (sym); - a = &coffsymbol (sym->bsym)->native[i].u.auxent; - a->x_csect.x_scnlen.p = coffsymbol (csect->bsym)->native; - coffsymbol (sym->bsym)->native[i].fix_scnlen = 1; + a = &coffsymbol (symbol_get_bfdsym (sym))->native[i].u.auxent; + a->x_csect.x_scnlen.p = coffsymbol (symbol_get_bfdsym (csect))->native; + coffsymbol (symbol_get_bfdsym (sym))->native[i].fix_scnlen = 1; } ppc_saw_abs = false; @@ -4490,9 +4509,9 @@ ppc_fix_adjustable (fix) sy != (symbolS *) NULL; sy = symbol_next (sy)) { - if (sy->sy_tc.class == XMC_TC0) + if (symbol_get_tc (sy)->class == XMC_TC0) continue; - if (sy->sy_tc.class != XMC_TC) + if (symbol_get_tc (sy)->class != XMC_TC) break; resolve_symbol_value (sy, 1); if (val == S_GET_VALUE (sy)) @@ -4509,9 +4528,9 @@ ppc_fix_adjustable (fix) /* Possibly adjust the reloc to be against the csect. */ if (fix->fx_addsy != (symbolS *) NULL - && fix->fx_addsy->sy_tc.subseg == 0 - && fix->fx_addsy->sy_tc.class != XMC_TC0 - && fix->fx_addsy->sy_tc.class != XMC_TC + && symbol_get_tc (fix->fx_addsy)->subseg == 0 + && symbol_get_tc (fix->fx_addsy)->class != XMC_TC0 + && symbol_get_tc (fix->fx_addsy)->class != XMC_TC && S_GET_SEGMENT (fix->fx_addsy) != bss_section /* Don't adjust if this is a reloc in the toc section. */ && (S_GET_SEGMENT (fix->fx_addsy) != data_section @@ -4530,29 +4549,29 @@ ppc_fix_adjustable (fix) abort (); /* Skip the initial dummy symbol. */ - csect = csect->sy_tc.next; + csect = symbol_get_tc (csect)->next; if (csect != (symbolS *) NULL) { - while (csect->sy_tc.next != (symbolS *) NULL - && (csect->sy_tc.next->sy_frag->fr_address - <= fix->fx_addsy->sy_frag->fr_address)) + while (symbol_get_tc (csect)->next != (symbolS *) NULL + && (symbol_get_frag (symbol_get_tc (csect)->next)->fr_address + <= symbol_get_frag (fix->fx_addsy)->fr_address)) { /* If the csect address equals the symbol value, then we have to look through the full symbol table to see whether this is the csect we want. Note that we will only get here if the csect has zero length. */ - if ((csect->sy_frag->fr_address - == fix->fx_addsy->sy_frag->fr_address) + if ((symbol_get_frag (csect)->fr_address + == symbol_get_frag (fix->fx_addsy)->fr_address) && S_GET_VALUE (csect) == S_GET_VALUE (fix->fx_addsy)) { symbolS *scan; - for (scan = csect->sy_next; + for (scan = symbol_next (csect); scan != NULL; - scan = scan->sy_next) + scan = symbol_next (scan)) { - if (scan->sy_tc.subseg != 0) + if (symbol_get_tc (scan)->subseg != 0) break; if (scan == fix->fx_addsy) break; @@ -4564,11 +4583,11 @@ ppc_fix_adjustable (fix) break; } - csect = csect->sy_tc.next; + csect = symbol_get_tc (csect)->next; } fix->fx_offset += (S_GET_VALUE (fix->fx_addsy) - - csect->sy_frag->fr_address); + - symbol_get_frag (csect)->fr_address); fix->fx_addsy = csect; } } @@ -4579,10 +4598,11 @@ ppc_fix_adjustable (fix) && S_GET_SEGMENT (fix->fx_addsy) == bss_section && ! S_IS_EXTERNAL (fix->fx_addsy)) { - resolve_symbol_value (fix->fx_addsy->sy_frag->fr_symbol, 1); - fix->fx_offset += (S_GET_VALUE (fix->fx_addsy) - - S_GET_VALUE (fix->fx_addsy->sy_frag->fr_symbol)); - fix->fx_addsy = fix->fx_addsy->sy_frag->fr_symbol; + resolve_symbol_value (symbol_get_frag (fix->fx_addsy)->fr_symbol, 1); + fix->fx_offset += + (S_GET_VALUE (fix->fx_addsy) + - S_GET_VALUE (symbol_get_frag (fix->fx_addsy)->fr_symbol)); + fix->fx_addsy = symbol_get_frag (fix->fx_addsy)->fr_symbol; } return 0; @@ -4602,10 +4622,11 @@ ppc_force_relocation (fix) we need to force the relocation. */ if (fix->fx_pcrel && fix->fx_addsy != NULL - && fix->fx_addsy->sy_tc.subseg != 0 - && (fix->fx_addsy->sy_frag->fr_address > fix->fx_frag->fr_address - || (fix->fx_addsy->sy_tc.next != NULL - && (fix->fx_addsy->sy_tc.next->sy_frag->fr_address + && symbol_get_tc (fix->fx_addsy)->subseg != 0 + && ((symbol_get_frag (fix->fx_addsy)->fr_address + > fix->fx_frag->fr_address) + || (symbol_get_tc (fix->fx_addsy)->next != NULL + && (symbol_get_frag (symbol_get_tc (fix->fx_addsy)->next)->fr_address <= fix->fx_frag->fr_address)))) return 1; @@ -4621,7 +4642,7 @@ ppc_is_toc_sym (sym) symbolS *sym; { #ifdef OBJ_XCOFF - return sym->sy_tc.class == XMC_TC; + return symbol_get_tc (sym)->class == XMC_TC; #else return strcmp (segment_name (S_GET_SEGMENT (sym)), ".got") == 0; #endif @@ -4650,7 +4671,7 @@ md_apply_fix3 (fixp, valuep, seg) { /* `*valuep' may contain the value of the symbol on which the reloc will be based; we have to remove it. */ - if (fixp->fx_addsy->sy_used_in_reloc + if (symbol_used_in_reloc_p (fixp->fx_addsy) && S_GET_SEGMENT (fixp->fx_addsy) != absolute_section && S_GET_SEGMENT (fixp->fx_addsy) != undefined_section && ! bfd_is_com_section (S_GET_SEGMENT (fixp->fx_addsy))) @@ -4725,9 +4746,9 @@ md_apply_fix3 (fixp, valuep, seg) && operand->shift == 0 && operand->insert == NULL && fixp->fx_addsy != NULL - && fixp->fx_addsy->sy_tc.subseg != 0 - && fixp->fx_addsy->sy_tc.class != XMC_TC - && fixp->fx_addsy->sy_tc.class != XMC_TC0 + && symbol_get_tc (fixp->fx_addsy)->subseg != 0 + && symbol_get_tc (fixp->fx_addsy)->class != XMC_TC + && symbol_get_tc (fixp->fx_addsy)->class != XMC_TC0 && S_GET_SEGMENT (fixp->fx_addsy) != bss_section) { value = fixp->fx_offset; @@ -4881,7 +4902,7 @@ md_apply_fix3 (fixp, valuep, seg) if (fixp->fx_pcrel) abort (); md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where, - value + 0x8000 >> 16, 2); + (value + 0x8000) >> 16, 2); break; /* Because SDA21 modifies the register field, the size is set to 4 @@ -4988,7 +5009,8 @@ tc_gen_reloc (seg, fixp) reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 0871d13..436b975 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -1,5 +1,5 @@ /* tc-ppc.h -- Header file for tc-ppc.c. - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GAS, the GNU Assembler. @@ -121,7 +121,7 @@ extern int ppc_pe_fix_adjustable PARAMS ((struct fix *)); struct ppc_tc_sy { /* We keep a few linked lists of symbols. */ - struct symbol *next; + symbolS *next; /* Non-zero if the symbol should be output. The RS/6000 assembler only outputs symbols that are external or are mentioned in a .globl or .lglobl statement. */ @@ -137,11 +137,11 @@ struct ppc_tc_sy int align; /* For a function symbol, a symbol whose value is the size. The field is NULL if there is no size. */ - struct symbol *size; + symbolS *size; /* For a csect symbol, the last symbol which has been defined in this csect, or NULL if none have been defined so far. For a .bs symbol, the referenced csect symbol. */ - struct symbol *within; + symbolS *within; }; #define TC_SYMFIELD_TYPE struct ppc_tc_sy @@ -158,11 +158,11 @@ extern char *ppc_canonicalize_symbol_name PARAMS ((char *)); /* Get the symbol class from the name. */ #define tc_symbol_new_hook(sym) ppc_symbol_new_hook (sym) -extern void ppc_symbol_new_hook PARAMS ((struct symbol *)); +extern void ppc_symbol_new_hook PARAMS ((symbolS *)); /* Set the symbol class of a label based on the csect. */ #define tc_frob_label(sym) ppc_frob_label (sym) -extern void ppc_frob_label PARAMS ((struct symbol *)); +extern void ppc_frob_label PARAMS ((symbolS *)); /* TOC relocs requires special handling. */ #define tc_fix_adjustable(fixp) ppc_fix_adjustable (fixp) @@ -178,7 +178,7 @@ extern void ppc_frob_section PARAMS ((asection *)); /* Finish up the symbol. */ #define tc_frob_symbol(sym, punt) punt = ppc_frob_symbol (sym) -extern int ppc_frob_symbol PARAMS ((struct symbol *)); +extern int ppc_frob_symbol PARAMS ((symbolS *)); /* Finish up the entire symtab. */ #define tc_adjust_symtab() ppc_adjust_symtab () @@ -203,18 +203,18 @@ extern void ppc_adjust_symtab PARAMS ((void)); #define TC_FORCE_RELOCATION_SECTION(FIXP,SEC) \ (TC_FORCE_RELOCATION (FIXP) \ - || ((FIXP)->fx_addsy && !(FIXP)->fx_subsy && (FIXP)->fx_addsy->bsym \ - && (FIXP)->fx_addsy->bsym->section != SEC)) + || ((FIXP)->fx_addsy && !(FIXP)->fx_subsy \ + && S_GET_SEGMENT ((FIXP)->fx_addsy) != SEC)) /* Support for SHF_EXCLUDE and SHT_ORDERED */ extern int ppc_section_letter PARAMS ((int, char **)); -extern int ppc_section_type PARAMS ((char **)); -extern int ppc_section_word PARAMS ((char **)); +extern int ppc_section_type PARAMS ((char *, size_t)); +extern int ppc_section_word PARAMS ((char *, size_t)); extern int ppc_section_flags PARAMS ((int, int, int)); #define md_elf_section_letter(LETTER, PTR_MSG) ppc_section_letter (LETTER, PTR_MSG) -#define md_elf_section_type(PTR_STR) ppc_section_type (PTR_STR) -#define md_elf_section_word(PTR_STR) ppc_section_word (PTR_STR) +#define md_elf_section_type(STR, LEN) ppc_section_type (STR, LEN) +#define md_elf_section_word(STR, LEN) ppc_section_word (STR, LEN) #define md_elf_section_flags(FLAGS, ATTR, TYPE) ppc_section_flags (FLAGS, ATTR, TYPE) /* Add extra PPC sections -- Note, for now, make .sbss2 and .PPC.EMB.sbss0 a @@ -247,8 +247,7 @@ extern const char *ppc_comment_chars; || ((FIX)->fx_subsy != NULL \ && (S_GET_SEGMENT ((FIX)->fx_subsy) \ == S_GET_SEGMENT ((FIX)->fx_addsy))) \ - || strchr (S_GET_NAME ((FIX)->fx_addsy), '\001') != NULL \ - || strchr (S_GET_NAME ((FIX)->fx_addsy), '\002') != NULL)) + || S_IS_LOCAL ((FIX)->fx_addsy))) /* We must never ever try to resolve references to externally visible symbols in the assembler, because the .o file might go into a shared diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index 6d8ca81..2752d03 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -1,5 +1,5 @@ /* tc-sh.c -- Assemble code for the Hitachi Super-H - Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation. + Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -1450,7 +1450,8 @@ sh_frob_section (abfd, sec, ignore) We have already adjusted the value of sym to include the fragment address, so we undo that adjustment here. */ subseg_change (sec, 0); - fix_new (sym->sy_frag, S_GET_VALUE (sym) - sym->sy_frag->fr_address, + fix_new (symbol_get_frag (sym), + S_GET_VALUE (sym) - symbol_get_frag (sym)->fr_address, 4, &abs_symbol, info.count, 0, BFD_RELOC_SH_COUNT); } } @@ -2056,7 +2057,11 @@ md_apply_fix (fixP, val) case BFD_RELOC_VTABLE_INHERIT: case BFD_RELOC_VTABLE_ENTRY: fixP->fx_done = 0; +#ifdef BFD_ASSEMBLER + return 0; +#else return; +#endif default: abort (); @@ -2187,12 +2192,7 @@ sh_do_align (n, fill, len, max) int max; { if (fill == NULL -#ifdef BFD_ASSEMBLER - && (now_seg->flags & SEC_CODE) != 0 -#else - && now_seg != data_section - && now_seg != bss_section -#endif + && subseg_text_p (now_seg) && n > 1) { static const unsigned char big_nop_pattern[] = { 0x00, 0x09 }; @@ -2377,7 +2377,8 @@ tc_gen_reloc (section, fixp) bfd_reloc_code_real_type r_type; rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = &fixp->fx_addsy->bsym; + rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; r_type = fixp->fx_r_type; diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h index cc02eab..f4278c2 100644 --- a/gas/config/tc-sh.h +++ b/gas/config/tc-sh.h @@ -1,5 +1,5 @@ /* This file is tc-sh.h - Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -56,6 +56,8 @@ extern int sh_force_relocation (); #ifdef OBJ_ELF #define obj_fix_adjustable(fixP) sh_fix_adjustable(fixP) +struct fix; +extern boolean sh_fix_adjustable PARAMS ((struct fix *)); #endif #define IGNORE_NONSTANDARD_ESCAPES diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 1518a8a..1bced29 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -1,5 +1,5 @@ /* tc-sparc.c -- Assemble for the SPARC - Copyright (C) 1989, 90-96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 90-96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify @@ -31,11 +31,14 @@ static struct sparc_arch *lookup_arch PARAMS ((char *)); static void init_default_arch PARAMS ((void)); -static void sparc_ip PARAMS ((char *, const struct sparc_opcode **)); +static int sparc_ip PARAMS ((char *, const struct sparc_opcode **)); static int in_signed_range PARAMS ((bfd_signed_vma, bfd_signed_vma)); static int in_unsigned_range PARAMS ((bfd_vma, bfd_vma)); static int in_bitfield_range PARAMS ((bfd_signed_vma, bfd_signed_vma)); static int sparc_ffs PARAMS ((unsigned int)); +static void synthetize_setuw PARAMS ((const struct sparc_opcode *)); +static void synthetize_setsw PARAMS ((const struct sparc_opcode *)); +static void synthetize_setx PARAMS ((const struct sparc_opcode *)); static bfd_vma BSR PARAMS ((bfd_vma, int)); static int cmp_reg_entry PARAMS ((const PTR, const PTR)); static int parse_keyword_arg PARAMS ((int (*) (const char *), char **, int *)); @@ -115,6 +118,7 @@ static void s_reserve PARAMS ((int)); static void s_common PARAMS ((int)); static void s_empty PARAMS ((int)); static void s_uacons PARAMS ((int)); +static void s_ncons PARAMS ((int)); const pseudo_typeS md_pseudo_table[] = { @@ -123,6 +127,7 @@ const pseudo_typeS md_pseudo_table[] = {"empty", s_empty, 0}, {"global", s_globl, 0}, {"half", cons, 2}, + {"nword", s_ncons, 0}, {"optim", s_ignore, 0}, {"proc", s_proc, 0}, {"reserve", s_reserve, 0}, @@ -135,8 +140,6 @@ const pseudo_typeS md_pseudo_table[] = {"uaxword", s_uacons, 8}, #ifdef OBJ_ELF /* these are specific to sparc/svr4 */ - {"pushsection", obj_elf_section, 0}, - {"popsection", obj_elf_previous, 0}, {"2byte", s_uacons, 2}, {"4byte", s_uacons, 4}, {"8byte", s_uacons, 8}, @@ -174,9 +177,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; changed in read.c. Ideally it shouldn't have to know about it at all, but nothing is ideal around here. */ -static unsigned char octal[256]; -#define isoctal(c) octal[(unsigned char) (c)] -static unsigned char toHex[256]; +#define isoctal(c) ((unsigned)((c) - '0') < '8') struct sparc_it { @@ -184,6 +185,7 @@ struct sparc_it unsigned long opcode; struct nlist *nlistp; expressionS exp; + expressionS exp2; int pcrel; bfd_reloc_code_real_type reloc; }; @@ -613,6 +615,27 @@ md_show_usage (stream) #endif } +/* native operand size opcode translation */ +struct + { + char *name; + char *name32; + char *name64; + } native_op_table[] = +{ + {"ldn", "ld", "ldx"}, + {"ldna", "lda", "ldxa"}, + {"stn", "st", "stx"}, + {"stna", "sta", "stxa"}, + {"slln", "sll", "sllx"}, + {"srln", "srl", "srlx"}, + {"sran", "sra", "srax"}, + {"casn", "cas", "casx"}, + {"casna", "casa", "casxa"}, + {"clrn", "clr", "clrx"}, + {NULL, NULL, NULL}, +}; + /* sparc64 priviledged registers */ struct priv_reg_entry @@ -693,16 +716,16 @@ md_begin () retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]); if (retval != NULL) { - fprintf (stderr, _("internal error: can't hash `%s': %s\n"), - sparc_opcodes[i].name, retval); + as_bad (_("Internal error: can't hash `%s': %s\n"), + sparc_opcodes[i].name, retval); lose = 1; } do { if (sparc_opcodes[i].match & sparc_opcodes[i].lose) { - fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"), - sparc_opcodes[i].name, sparc_opcodes[i].args); + as_bad (_("Internal error: losing opcode: `%s' \"%s\"\n"), + sparc_opcodes[i].name, sparc_opcodes[i].args); lose = 1; } ++i; @@ -711,18 +734,33 @@ md_begin () && !strcmp (sparc_opcodes[i].name, name)); } + for (i = 0; native_op_table[i].name; i++) + { + const struct sparc_opcode *insn; + char *name = sparc_arch_size == 32 ? native_op_table[i].name32 : + native_op_table[i].name64; + insn = (struct sparc_opcode *)hash_find (op_hash, name); + if (insn == NULL) + { + as_bad (_("Internal error: can't find opcode `%s' for `%s'\n"), + name, native_op_table[i].name); + lose = 1; + } + else + { + retval = hash_insert (op_hash, native_op_table[i].name, (PTR) insn); + if (retval != NULL) + { + as_bad (_("Internal error: can't hash `%s': %s\n"), + sparc_opcodes[i].name, retval); + lose = 1; + } + } + } + if (lose) as_fatal (_("Broken assembler. No assembly attempted.")); - for (i = '0'; i < '8'; ++i) - octal[i] = 1; - for (i = '0'; i <= '9'; ++i) - toHex[i] = i - '0'; - for (i = 'a'; i <= 'f'; ++i) - toHex[i] = i + 10 - 'a'; - for (i = 'A'; i <= 'F'; ++i) - toHex[i] = i + 10 - 'A'; - qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]), sizeof (priv_reg_table[0]), cmp_reg_entry); @@ -860,9 +898,6 @@ BSR (val, amount) /* For communication between sparc_ip and get_expression. */ static char *expr_end; -/* For communication between md_assemble and sparc_ip. */ -static int special_case; - /* Values for `special_case'. Instructions that require wierd handling because they're longer than 4 bytes. */ @@ -876,6 +911,7 @@ static int special_case; /* Bit masks of various insns. */ #define NOP_INSN 0x01000000 #define OR_INSN 0x80100000 +#define XOR_INSN 0x80180000 #define FMOVS_INSN 0x81A00020 #define SETHI_INSN 0x01000000 #define SLLX_INSN 0x81281000 @@ -886,6 +922,281 @@ static const struct sparc_opcode *last_insn; /* The assembled opcode of `last_insn'. */ static unsigned long last_opcode; +/* Handle the set and setuw synthetic instructions. */ +static void +synthetize_setuw (insn) + const struct sparc_opcode *insn; +{ + int need_hi22_p = 0; + int rd = (the_insn.opcode & RD (~0)) >> 25; + + if (the_insn.exp.X_op == O_constant) + { + if (SPARC_OPCODE_ARCH_V9_P (max_architecture)) + { + if (sizeof(offsetT) > 4 + && (the_insn.exp.X_add_number < 0 + || the_insn.exp.X_add_number > (offsetT) 0xffffffff)) + as_warn (_("set: number not in 0..4294967295 range")); + } + else + { + if (sizeof(offsetT) > 4 + && (the_insn.exp.X_add_number < -(offsetT) 0x80000000 + || the_insn.exp.X_add_number > (offsetT) 0xffffffff)) + as_warn (_("set: number not in -2147483648..4294967295 range")); + the_insn.exp.X_add_number = (int)the_insn.exp.X_add_number; + } + } + + /* See if operand is absolute and small; skip sethi if so. */ + if (the_insn.exp.X_op != O_constant + || the_insn.exp.X_add_number >= (1 << 12) + || the_insn.exp.X_add_number < -(1 << 12)) + { + the_insn.opcode = (SETHI_INSN | RD (rd) + | ((the_insn.exp.X_add_number >> 10) + & (the_insn.exp.X_op == O_constant ? 0x3fffff : 0))); + the_insn.reloc = (the_insn.exp.X_op != O_constant + ? BFD_RELOC_HI22 + : BFD_RELOC_NONE); + output_insn (insn, &the_insn); + need_hi22_p = 1; + } + + /* See if operand has no low-order bits; skip OR if so. */ + if (the_insn.exp.X_op != O_constant + || (need_hi22_p && (the_insn.exp.X_add_number & 0x3FF) != 0) + || ! need_hi22_p) + { + the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (rd) : 0) + | RD (rd) | IMMED + | (the_insn.exp.X_add_number + & (the_insn.exp.X_op != O_constant ? 0 : + need_hi22_p ? 0x3ff : 0x1fff))); + the_insn.reloc = (the_insn.exp.X_op != O_constant + ? BFD_RELOC_LO10 + : BFD_RELOC_NONE); + output_insn (insn, &the_insn); + } +} + +/* Handle the setsw synthetic instruction. */ +static void +synthetize_setsw (insn) + const struct sparc_opcode *insn; +{ + int low32, rd, opc; + + rd = (the_insn.opcode & RD (~0)) >> 25; + + if (the_insn.exp.X_op != O_constant) + { + synthetize_setuw (insn); + + /* Need to sign extend it. */ + the_insn.opcode = (SRA_INSN | RS1 (rd) | RD (rd)); + the_insn.reloc = BFD_RELOC_NONE; + output_insn (insn, &the_insn); + return; + } + + if (sizeof(offsetT) > 4 + && (the_insn.exp.X_add_number < -(offsetT) 0x80000000 + || the_insn.exp.X_add_number > (offsetT) 0xffffffff)) + as_warn (_("setsw: number not in -2147483648..4294967295 range")); + + low32 = the_insn.exp.X_add_number; + + if (low32 >= 0) + { + synthetize_setuw (insn); + return; + } + + opc = OR_INSN; + + the_insn.reloc = BFD_RELOC_NONE; + /* See if operand is absolute and small; skip sethi if so. */ + if (low32 < -(1 << 12)) + { + the_insn.opcode = (SETHI_INSN | RD (rd) + | (((~the_insn.exp.X_add_number) >> 10) & 0x3fffff)); + output_insn (insn, &the_insn); + low32 = 0x1c00 | (low32 & 0x3ff); + opc = RS1 (rd) | XOR_INSN; + } + + the_insn.opcode = (opc | RD (rd) | IMMED + | (low32 & 0x1fff)); + output_insn (insn, &the_insn); +} + +/* Handle the setsw synthetic instruction. */ +static void +synthetize_setx (insn) + const struct sparc_opcode *insn; +{ + int upper32, lower32; + int tmpreg = (the_insn.opcode & RS1 (~0)) >> 14; + int dstreg = (the_insn.opcode & RD (~0)) >> 25; + int upper_dstreg; + int need_hh22_p = 0, need_hm10_p = 0, need_hi22_p = 0, need_lo10_p = 0; + int need_xor10_p = 0; + +#define SIGNEXT32(x) ((((x) & 0xffffffff) ^ 0x80000000) - 0x80000000) + lower32 = SIGNEXT32 (the_insn.exp.X_add_number); + upper32 = SIGNEXT32 (BSR (the_insn.exp.X_add_number, 32)); +#undef SIGNEXT32 + + upper_dstreg = tmpreg; + /* The tmp reg should not be the dst reg. */ + if (tmpreg == dstreg) + as_warn (_("setx: temporary register same as destination register")); + + /* ??? Obviously there are other optimizations we can do + (e.g. sethi+shift for 0x1f0000000) and perhaps we shouldn't be + doing some of these. Later. If you do change things, try to + change all of this to be table driven as well. */ + /* What to output depends on the number if it's constant. + Compute that first, then output what we've decided upon. */ + if (the_insn.exp.X_op != O_constant) + { + if (sparc_arch_size == 32) + { + /* When arch size is 32, we want setx to be equivalent + to setuw for anything but constants. */ + the_insn.exp.X_add_number &= 0xffffffff; + synthetize_setuw (insn); + return; + } + need_hh22_p = need_hm10_p = need_hi22_p = need_lo10_p = 1; + lower32 = 0; upper32 = 0; + } + else + { + /* Reset X_add_number, we've extracted it as upper32/lower32. + Otherwise fixup_segment will complain about not being able to + write an 8 byte number in a 4 byte field. */ + the_insn.exp.X_add_number = 0; + + /* Only need hh22 if `or' insn can't handle constant. */ + if (upper32 < -(1 << 12) || upper32 >= (1 << 12)) + need_hh22_p = 1; + + /* Does bottom part (after sethi) have bits? */ + if ((need_hh22_p && (upper32 & 0x3ff) != 0) + /* No hh22, but does upper32 still have bits we can't set + from lower32? */ + || (! need_hh22_p && upper32 != 0 && upper32 != -1)) + need_hm10_p = 1; + + /* If the lower half is all zero, we build the upper half directly + into the dst reg. */ + if (lower32 != 0 + /* Need lower half if number is zero or 0xffffffff00000000. */ + || (! need_hh22_p && ! need_hm10_p)) + { + /* No need for sethi if `or' insn can handle constant. */ + if (lower32 < -(1 << 12) || lower32 >= (1 << 12) + /* Note that we can't use a negative constant in the `or' + insn unless the upper 32 bits are all ones. */ + || (lower32 < 0 && upper32 != -1) + || (lower32 >= 0 && upper32 == -1)) + need_hi22_p = 1; + + if (need_hi22_p && upper32 == -1) + need_xor10_p = 1; + + /* Does bottom part (after sethi) have bits? */ + else if ((need_hi22_p && (lower32 & 0x3ff) != 0) + /* No sethi. */ + || (! need_hi22_p && (lower32 & 0x1fff) != 0) + /* Need `or' if we didn't set anything else. */ + || (! need_hi22_p && ! need_hh22_p && ! need_hm10_p)) + need_lo10_p = 1; + } + else + /* Output directly to dst reg if lower 32 bits are all zero. */ + upper_dstreg = dstreg; + } + + if (!upper_dstreg && dstreg) + as_warn (_("setx: illegal temporary register g0")); + + if (need_hh22_p) + { + the_insn.opcode = (SETHI_INSN | RD (upper_dstreg) + | ((upper32 >> 10) & 0x3fffff)); + the_insn.reloc = (the_insn.exp.X_op != O_constant + ? BFD_RELOC_SPARC_HH22 : BFD_RELOC_NONE); + output_insn (insn, &the_insn); + } + + if (need_hi22_p) + { + the_insn.opcode = (SETHI_INSN | RD (dstreg) + | (((need_xor10_p ? ~lower32 : lower32) + >> 10) & 0x3fffff)); + the_insn.reloc = (the_insn.exp.X_op != O_constant + ? BFD_RELOC_SPARC_LM22 : BFD_RELOC_NONE); + output_insn (insn, &the_insn); + } + + if (need_hm10_p) + { + the_insn.opcode = (OR_INSN + | (need_hh22_p ? RS1 (upper_dstreg) : 0) + | RD (upper_dstreg) + | IMMED + | (upper32 & (need_hh22_p ? 0x3ff : 0x1fff))); + the_insn.reloc = (the_insn.exp.X_op != O_constant + ? BFD_RELOC_SPARC_HM10 : BFD_RELOC_NONE); + output_insn (insn, &the_insn); + } + + if (need_lo10_p) + { + /* FIXME: One nice optimization to do here is to OR the low part + with the highpart if hi22 isn't needed and the low part is + positive. */ + the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (dstreg) : 0) + | RD (dstreg) + | IMMED + | (lower32 & (need_hi22_p ? 0x3ff : 0x1fff))); + the_insn.reloc = (the_insn.exp.X_op != O_constant + ? BFD_RELOC_LO10 : BFD_RELOC_NONE); + output_insn (insn, &the_insn); + } + + /* If we needed to build the upper part, shift it into place. */ + if (need_hh22_p || need_hm10_p) + { + the_insn.opcode = (SLLX_INSN | RS1 (upper_dstreg) | RD (upper_dstreg) + | IMMED | 32); + the_insn.reloc = BFD_RELOC_NONE; + output_insn (insn, &the_insn); + } + + /* To get -1 in upper32, we do sethi %hi(~x), r; xor r, -0x400 | x, r. */ + if (need_xor10_p) + { + the_insn.opcode = (XOR_INSN | RS1 (dstreg) | RD (dstreg) | IMMED + | 0x1c00 | (lower32 & 0x3ff)); + the_insn.reloc = BFD_RELOC_NONE; + output_insn (insn, &the_insn); + } + + /* If we needed to build both upper and lower parts, OR them together. */ + else if ((need_hh22_p || need_hm10_p) && (need_hi22_p || need_lo10_p)) + { + the_insn.opcode = (OR_INSN | RS1 (dstreg) | RS2 (upper_dstreg) + | RD (dstreg)); + the_insn.reloc = BFD_RELOC_NONE; + output_insn (insn, &the_insn); + } +} + /* Main entry point to assemble one instruction. */ void @@ -893,10 +1204,10 @@ md_assemble (str) char *str; { const struct sparc_opcode *insn; + int special_case; know (str); - special_case = SPECIAL_CASE_NONE; - sparc_ip (str, &insn); + special_case = sparc_ip (str, &insn); /* We warn about attempts to put a floating point branch in a delay slot, unless the delay slot has been annulled. */ @@ -934,202 +1245,24 @@ md_assemble (str) output_insn (insn, &the_insn); break; - case SPECIAL_CASE_SET: - { - int need_hi22_p = 0; - - /* "set" is not defined for negative numbers in v9: it doesn't yield - what you expect it to. */ - if (SPARC_OPCODE_ARCH_V9_P (max_architecture) - && the_insn.exp.X_op == O_constant) - { - if (the_insn.exp.X_add_number < 0) - as_warn (_("set: used with negative number")); - else if (the_insn.exp.X_add_number > (offsetT) 0xffffffff) - as_warn (_("set: number larger than 4294967295")); - } - - /* See if operand is absolute and small; skip sethi if so. */ - if (the_insn.exp.X_op != O_constant - || the_insn.exp.X_add_number >= (1 << 12) - || the_insn.exp.X_add_number < -(1 << 12)) - { - output_insn (insn, &the_insn); - need_hi22_p = 1; - } - /* See if operand has no low-order bits; skip OR if so. */ - if (the_insn.exp.X_op != O_constant - || (need_hi22_p && (the_insn.exp.X_add_number & 0x3FF) != 0) - || ! need_hi22_p) - { - int rd = (the_insn.opcode & RD (~0)) >> 25; - the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (rd) : 0) - | RD (rd) - | IMMED - | (the_insn.exp.X_add_number - & (need_hi22_p ? 0x3ff : 0x1fff))); - the_insn.reloc = (the_insn.exp.X_op != O_constant - ? BFD_RELOC_LO10 - : BFD_RELOC_NONE); - output_insn (insn, &the_insn); - } - break; - } - case SPECIAL_CASE_SETSW: - { - /* FIXME: Not finished. */ - break; - } + synthetize_setsw (insn); + break; + + case SPECIAL_CASE_SET: + synthetize_setuw (insn); + break; case SPECIAL_CASE_SETX: - { -#define SIGNEXT32(x) ((((x) & 0xffffffff) ^ 0x80000000) - 0x80000000) - int upper32 = SIGNEXT32 (BSR (the_insn.exp.X_add_number, 32)); - int lower32 = SIGNEXT32 (the_insn.exp.X_add_number); -#undef SIGNEXT32 - int tmpreg = (the_insn.opcode & RS1 (~0)) >> 14; - int dstreg = (the_insn.opcode & RD (~0)) >> 25; - /* Output directly to dst reg if lower 32 bits are all zero. */ - int upper_dstreg = (the_insn.exp.X_op == O_constant - && lower32 == 0) ? dstreg : tmpreg; - int need_hh22_p = 0, need_hm10_p = 0, need_hi22_p = 0, need_lo10_p = 0; - - /* The tmp reg should not be the dst reg. */ - if (tmpreg == dstreg) - as_warn (_("setx: temporary register same as destination register")); - - /* Reset X_add_number, we've extracted it as upper32/lower32. - Otherwise fixup_segment will complain about not being able to - write an 8 byte number in a 4 byte field. */ - the_insn.exp.X_add_number = 0; - - /* ??? Obviously there are other optimizations we can do - (e.g. sethi+shift for 0x1f0000000) and perhaps we shouldn't be - doing some of these. Later. If you do change things, try to - change all of this to be table driven as well. */ - - /* What to output depends on the number if it's constant. - Compute that first, then output what we've decided upon. */ - if (the_insn.exp.X_op != O_constant) - need_hh22_p = need_hm10_p = need_hi22_p = need_lo10_p = 1; - else - { - /* Only need hh22 if `or' insn can't handle constant. */ - if (upper32 < -(1 << 12) || upper32 >= (1 << 12)) - need_hh22_p = 1; - - /* Does bottom part (after sethi) have bits? */ - if ((need_hh22_p && (upper32 & 0x3ff) != 0) - /* No hh22, but does upper32 still have bits we can't set - from lower32? */ - || (! need_hh22_p - && upper32 != 0 - && (upper32 != -1 || lower32 >= 0))) - need_hm10_p = 1; - - /* If the lower half is all zero, we build the upper half directly - into the dst reg. */ - if (lower32 != 0 - /* Need lower half if number is zero. */ - || (! need_hh22_p && ! need_hm10_p)) - { - /* No need for sethi if `or' insn can handle constant. */ - if (lower32 < -(1 << 12) || lower32 >= (1 << 12) - /* Note that we can't use a negative constant in the `or' - insn unless the upper 32 bits are all ones. */ - || (lower32 < 0 && upper32 != -1)) - need_hi22_p = 1; - - /* Does bottom part (after sethi) have bits? */ - if ((need_hi22_p && (lower32 & 0x3ff) != 0) - /* No sethi. */ - || (! need_hi22_p && (lower32 & 0x1fff) != 0) - /* Need `or' if we didn't set anything else. */ - || (! need_hi22_p && ! need_hh22_p && ! need_hm10_p)) - need_lo10_p = 1; - } - } - - if (need_hh22_p) - { - the_insn.opcode = (SETHI_INSN | RD (upper_dstreg) - | ((upper32 >> 10) & 0x3fffff)); - the_insn.reloc = (the_insn.exp.X_op != O_constant - ? BFD_RELOC_SPARC_HH22 : BFD_RELOC_NONE); - output_insn (insn, &the_insn); - } - - if (need_hm10_p) - { - the_insn.opcode = (OR_INSN - | (need_hh22_p ? RS1 (upper_dstreg) : 0) - | RD (upper_dstreg) - | IMMED - | (upper32 - & (need_hh22_p ? 0x3ff : 0x1fff))); - the_insn.reloc = (the_insn.exp.X_op != O_constant - ? BFD_RELOC_SPARC_HM10 : BFD_RELOC_NONE); - output_insn (insn, &the_insn); - } - - if (need_hi22_p) - { - the_insn.opcode = (SETHI_INSN | RD (dstreg) - | ((lower32 >> 10) & 0x3fffff)); - the_insn.reloc = BFD_RELOC_HI22; - output_insn (insn, &the_insn); - } - - if (need_lo10_p) - { - /* FIXME: One nice optimization to do here is to OR the low part - with the highpart if hi22 isn't needed and the low part is - positive. */ - the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (dstreg) : 0) - | RD (dstreg) - | IMMED - | (lower32 - & (need_hi22_p ? 0x3ff : 0x1fff))); - the_insn.reloc = BFD_RELOC_LO10; - output_insn (insn, &the_insn); - } - - /* If we needed to build the upper part, shift it into place. */ - if (need_hh22_p || need_hm10_p) - { - the_insn.opcode = (SLLX_INSN | RS1 (upper_dstreg) | RD (upper_dstreg) - | IMMED | 32); - the_insn.reloc = BFD_RELOC_NONE; - output_insn (insn, &the_insn); - } - - /* If we needed to build both upper and lower parts, OR them together. */ - if ((need_hh22_p || need_hm10_p) - && (need_hi22_p || need_lo10_p)) - { - the_insn.opcode = (OR_INSN | RS1 (dstreg) | RS2 (upper_dstreg) - | RD (dstreg)); - the_insn.reloc = BFD_RELOC_NONE; - output_insn (insn, &the_insn); - } - /* We didn't need both regs, but we may have to sign extend lower32. */ - else if (need_hi22_p && upper32 == -1) - { - the_insn.opcode = (SRA_INSN | RS1 (dstreg) | RD (dstreg) - | IMMED | 0); - the_insn.reloc = BFD_RELOC_NONE; - output_insn (insn, &the_insn); - } - break; - } - + synthetize_setx (insn); + break; + case SPECIAL_CASE_FDIV: { int rd = (the_insn.opcode >> 25) & 0x1f; - + output_insn (insn, &the_insn); - + /* According to information leaked from Sun, the "fdiv" instructions on early SPARC machines would produce incorrect results sometimes. The workaround is to add an fmovs of the destination register to @@ -1138,9 +1271,9 @@ md_assemble (str) assert (the_insn.reloc == BFD_RELOC_NONE); the_insn.opcode = FMOVS_INSN | rd | RD (rd); output_insn (insn, &the_insn); - break; + return; } - + default: as_fatal (_("failed special case insn sanity check")); } @@ -1148,7 +1281,7 @@ md_assemble (str) /* Subroutine of md_assemble to do the actual parsing. */ -static void +static int sparc_ip (str, pinsn) char *str; const struct sparc_opcode **pinsn; @@ -1164,6 +1297,7 @@ sparc_ip (str, pinsn) int match = 0; int comma = 0; int v9_arg_p; + int special_case = SPECIAL_CASE_NONE; s = str; if (islower ((unsigned char) *s)) @@ -1195,7 +1329,7 @@ sparc_ip (str, pinsn) if (insn == NULL) { as_bad (_("Unknown opcode: `%s'"), str); - return; + return special_case; } if (comma) { @@ -1654,7 +1788,8 @@ sparc_ip (str, pinsn) goto error; case 'g': /* global register */ - if (isoctal (c = *s++)) + c = *s++; + if (isoctal (c)) { mask = c - '0'; break; @@ -1662,7 +1797,8 @@ sparc_ip (str, pinsn) goto error; case 'i': /* in register */ - if (isoctal (c = *s++)) + c = *s++; + if (isoctal (c)) { mask = c - '0' + 24; break; @@ -1670,7 +1806,8 @@ sparc_ip (str, pinsn) goto error; case 'l': /* local register */ - if (isoctal (c = *s++)) + c = *s++; + if (isoctal (c)) { mask = (c - '0' + 16); break; @@ -1678,7 +1815,8 @@ sparc_ip (str, pinsn) goto error; case 'o': /* out register */ - if (isoctal (c = *s++)) + c = *s++; + if (isoctal (c)) { mask = (c - '0' + 8); break; @@ -1854,14 +1992,10 @@ sparc_ip (str, pinsn) } break; - case '0': /* 64 bit immediate (setx insn) */ + case '0': /* 64 bit immediate (set, setsw, setx insn) */ the_insn.reloc = BFD_RELOC_NONE; /* reloc handled elsewhere */ goto immediate; - case 'h': /* high 22 bits */ - the_insn.reloc = BFD_RELOC_HI22; - goto immediate; - case 'l': /* 22 bit PC relative immediate */ the_insn.reloc = BFD_RELOC_SPARC_WDISP22; the_insn.pcrel = 1; @@ -1872,6 +2006,7 @@ sparc_ip (str, pinsn) the_insn.pcrel = 1; goto immediate; + case 'h': case 'n': /* 22 bit immediate */ the_insn.reloc = BFD_RELOC_SPARC22; goto immediate; @@ -1885,89 +2020,224 @@ sparc_ip (str, pinsn) if (*s == ' ') s++; - /* Check for %hi, etc. */ - if (*s == '%') - { - static struct ops { - /* The name as it appears in assembler. */ - char *name; - /* strlen (name), precomputed for speed */ - int len; - /* The reloc this pseudo-op translates to. */ - int reloc; - /* Non-zero if for v9 only. */ - int v9_p; - /* Non-zero if can be used in pc-relative contexts. */ - int pcrel_p;/*FIXME:wip*/ - } ops[] = { - /* hix/lox must appear before hi/lo so %hix won't be - mistaken for %hi. */ - { "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 }, - { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 }, - { "hi", 2, BFD_RELOC_HI22, 0, 1 }, - { "lo", 2, BFD_RELOC_LO10, 0, 1 }, - { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 }, - { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 }, - { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 }, - { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 }, - { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 }, - { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 }, - { "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 }, - { "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 }, - { NULL } - }; - struct ops *o; - - for (o = ops; o->name; o++) - if (strncmp (s + 1, o->name, o->len) == 0) + { + char *s1; + char *op_arg = NULL; + expressionS op_exp; + bfd_reloc_code_real_type old_reloc = the_insn.reloc; + + /* Check for %hi, etc. */ + if (*s == '%') + { + static const struct ops { + /* The name as it appears in assembler. */ + char *name; + /* strlen (name), precomputed for speed */ + int len; + /* The reloc this pseudo-op translates to. */ + int reloc; + /* Non-zero if for v9 only. */ + int v9_p; + /* Non-zero if can be used in pc-relative contexts. */ + int pcrel_p;/*FIXME:wip*/ + } ops[] = { + /* hix/lox must appear before hi/lo so %hix won't be + mistaken for %hi. */ + { "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 }, + { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 }, + { "hi", 2, BFD_RELOC_HI22, 0, 1 }, + { "lo", 2, BFD_RELOC_LO10, 0, 1 }, + { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 }, + { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 }, + { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 }, + { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 }, + { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 }, + { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 }, + { "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 }, + { "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 }, + { NULL } + }; + const struct ops *o; + + for (o = ops; o->name; o++) + if (strncmp (s + 1, o->name, o->len) == 0) + break; + if (o->name == NULL) break; - if (o->name == NULL) - break; + + if (s[o->len + 1] != '(') + { + as_bad (_("Illegal operands: %%%s requires arguments in ()"), o->name); + return special_case; + } - the_insn.reloc = o->reloc; - s += o->len + 1; - v9_arg_p = o->v9_p; - } + op_arg = o->name; + the_insn.reloc = o->reloc; + s += o->len + 2; + v9_arg_p = o->v9_p; + } + + /* Note that if the get_expression() fails, we will still + have created U entries in the symbol table for the + 'symbols' in the input string. Try not to create U + symbols for registers, etc. */ - /* Note that if the get_expression() fails, we will still - have created U entries in the symbol table for the - 'symbols' in the input string. Try not to create U - symbols for registers, etc. */ - { /* This stuff checks to see if the expression ends in +%reg. If it does, it removes the register from the expression, and re-sets 's' to point to the right place. */ - char *s1; + if (op_arg) + { + int npar = 0; + + for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) + if (*s1 == '(') + npar++; + else if (*s1 == ')') + { + if (!npar) + break; + npar--; + } + + if (*s1 != ')') + { + as_bad (_("Illegal operands: %%%s requires arguments in ()"), op_arg); + return special_case; + } + + *s1 = '\0'; + (void) get_expression (s); + *s1 = ')'; + s = s1 + 1; + if (*s == ',' || *s == ']' || !*s) + continue; + if (*s != '+' && *s != '-') + { + as_bad (_("Illegal operands: Can't do arithmetics other than + and - involving %%%s()"), op_arg); + return special_case; + } + *s1 = '0'; + s = s1; + op_exp = the_insn.exp; + memset (&the_insn.exp, 0, sizeof(the_insn.exp)); + } for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ; if (s1 != s && isdigit ((unsigned char) s1[-1])) { if (s1[-2] == '%' && s1[-3] == '+') + s1 -= 3; + else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') + s1 -= 4; + else + s1 = NULL; + if (s1) { - s1 -= 3; *s1 = '\0'; (void) get_expression (s); *s1 = '+'; + if (op_arg) + *s = ')'; s = s1; - continue; } - else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') + } + else + s1 = NULL; + + if (!s1) + { + (void) get_expression (s); + if (op_arg) + *s = ')'; + s = expr_end; + } + + if (op_arg) + { + the_insn.exp2 = the_insn.exp; + the_insn.exp = op_exp; + if (the_insn.exp2.X_op == O_absent) + the_insn.exp2.X_op = O_illegal; + else if (the_insn.exp.X_op == O_absent) { - s1 -= 4; - *s1 = '\0'; - (void) get_expression (s); - *s1 = '+'; - s = s1; - continue; + the_insn.exp = the_insn.exp2; + the_insn.exp2.X_op = O_illegal; + } + else if (the_insn.exp.X_op == O_constant) + { + valueT val = the_insn.exp.X_add_number; + switch (the_insn.reloc) + { + default: + break; + + case BFD_RELOC_SPARC_HH22: + val = BSR (val, 32); + /* intentional fallthrough */ + + case BFD_RELOC_SPARC_LM22: + case BFD_RELOC_HI22: + val = (val >> 10) & 0x3fffff; + break; + + case BFD_RELOC_SPARC_HM10: + val = BSR (val, 32); + /* intentional fallthrough */ + + case BFD_RELOC_LO10: + val &= 0x3ff; + break; + + case BFD_RELOC_SPARC_H44: + val >>= 22; + val &= 0x3fffff; + break; + + case BFD_RELOC_SPARC_M44: + val >>= 12; + val &= 0x3ff; + break; + + case BFD_RELOC_SPARC_L44: + val &= 0xfff; + break; + + case BFD_RELOC_SPARC_HIX22: + val = ~ val; + val = (val >> 10) & 0x3fffff; + break; + + case BFD_RELOC_SPARC_LOX10: + val = (val & 0x3ff) | 0x1c00; + break; + } + the_insn.exp = the_insn.exp2; + the_insn.exp.X_add_number += val; + the_insn.exp2.X_op = O_illegal; + the_insn.reloc = old_reloc; + } + else if (the_insn.exp2.X_op != O_constant) + { + as_bad (_("Illegal operands: Can't add non-constant expression to %%%s()"), op_arg); + return special_case; + } + else + { + if (old_reloc != BFD_RELOC_SPARC13 + || the_insn.reloc != BFD_RELOC_LO10 + || sparc_arch_size != 64 + || sparc_pic_code) + { + as_bad (_("Illegal operands: Can't do arithmetics involving %%%s() of a relocatable symbol"), op_arg); + return special_case; + } + the_insn.reloc = BFD_RELOC_SPARC_OLO10; } } } - (void) get_expression (s); - s = expr_end; - /* Check for constants that don't require emitting a reloc. */ if (the_insn.exp.X_op == O_constant && the_insn.exp.X_add_symbol == 0 @@ -2176,7 +2446,7 @@ sparc_ip (str, pinsn) else { as_bad (_("Illegal operands%s"), error_message); - return; + return special_case; } } else @@ -2244,7 +2514,7 @@ sparc_ip (str, pinsn) as_tsktsk (_(" (Requires %s; requested architecture is %s.)"), required_archs, sparc_opcode_archs[max_architecture].name); - return; + return special_case; } } /* if no match */ @@ -2252,6 +2522,7 @@ sparc_ip (str, pinsn) } /* forever looking for a match */ the_insn.opcode = opcode; + return special_case; } /* Parse an argument that can be expressed as a keyword. @@ -2374,6 +2645,8 @@ output_insn (insn, the_insn) the insn size is 4 and fixup_segment will signal an overflow for large 8 byte quantities. */ fixP->fx_no_overflow = 1; + if (the_insn->reloc == BFD_RELOC_SPARC_OLO10) + fixP->tc_fix_data = the_insn->exp2.X_add_number; } last_insn = insn; @@ -2504,7 +2777,7 @@ md_apply_fix3 (fixP, value, segment) don't want to include the value of an externally visible symbol. */ if (fixP->fx_addsy != NULL) { - if (fixP->fx_addsy->sy_used_in_reloc + if (symbol_used_in_reloc_p (fixP->fx_addsy) && (S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy) || (sparc_pic_code && ! fixP->fx_pcrel) @@ -2549,7 +2822,7 @@ md_apply_fix3 (fixP, value, segment) && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy != NULL && ! S_IS_COMMON (fixP->fx_addsy) - && (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0) + && symbol_section_p (fixP->fx_addsy)) fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy); /* When generating PIC code, we need to fiddle to get @@ -2606,7 +2879,7 @@ md_apply_fix3 (fixP, value, segment) being done! */ if (! sparc_pic_code || fixP->fx_addsy == NULL - || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0) + || symbol_section_p (fixP->fx_addsy)) ++val; insn |= val & 0x3fffffff; break; @@ -2708,6 +2981,11 @@ md_apply_fix3 (fixP, value, segment) } break; + case BFD_RELOC_SPARC_OLO10: + val &= 0x3ff; + val += fixP->tc_fix_data; + /* intentional fallthrough */ + case BFD_RELOC_SPARC13: if (! in_signed_range (val, 0x1fff)) as_bad_where (fixP->fx_file, fixP->fx_line, @@ -2777,17 +3055,20 @@ md_apply_fix3 (fixP, value, segment) /* Translate internal representation of relocation info to BFD target format. */ -arelent * +arelent ** tc_gen_reloc (section, fixp) asection *section; fixS *fixp; { + static arelent *relocs[3]; arelent *reloc; bfd_reloc_code_real_type code; - reloc = (arelent *) xmalloc (sizeof (arelent)); + relocs[0] = reloc = (arelent *) xmalloc (sizeof (arelent)); + relocs[1] = NULL; - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; switch (fixp->fx_r_type) @@ -2798,6 +3079,7 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_LO10: case BFD_RELOC_32_PCREL_S2: case BFD_RELOC_SPARC13: + case BFD_RELOC_SPARC22: case BFD_RELOC_SPARC_BASE13: case BFD_RELOC_SPARC_WDISP16: case BFD_RELOC_SPARC_WDISP19: @@ -2820,6 +3102,7 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_SPARC_HIX22: case BFD_RELOC_SPARC_LOX10: case BFD_RELOC_SPARC_REV32: + case BFD_RELOC_SPARC_OLO10: case BFD_RELOC_VTABLE_ENTRY: case BFD_RELOC_VTABLE_INHERIT: code = fixp->fx_r_type; @@ -2873,13 +3156,18 @@ tc_gen_reloc (section, fixp) } #endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */ - reloc->howto = bfd_reloc_type_lookup (stdoutput, code); + if (code == BFD_RELOC_SPARC_OLO10) + reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO10); + else + reloc->howto = bfd_reloc_type_lookup (stdoutput, code); if (reloc->howto == 0) { as_bad_where (fixp->fx_file, fixp->fx_line, _("internal error: can't export reloc type %d (`%s')"), fixp->fx_r_type, bfd_get_reloc_code_name (code)); - return 0; + xfree (reloc); + relocs[0] = NULL; + return relocs; } /* @@ Why fx_addnumber sometimes and fx_offset other times? */ @@ -2906,7 +3194,7 @@ tc_gen_reloc (section, fixp) || code == BFD_RELOC_SPARC_PC10 || code == BFD_RELOC_SPARC_PC22) reloc->addend = fixp->fx_addnumber; - else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0) + else if (symbol_section_p (fixp->fx_addsy)) reloc->addend = (section->vma + fixp->fx_addnumber + md_pcrel_from (fixp)); @@ -2914,7 +3202,21 @@ tc_gen_reloc (section, fixp) reloc->addend = fixp->fx_offset; #endif - return reloc; + /* We expand R_SPARC_OLO10 to R_SPARC_LO10 and R_SPARC_13 + on the same location. */ + if (code == BFD_RELOC_SPARC_OLO10) + { + relocs[1] = reloc = (arelent *) xmalloc (sizeof (arelent)); + relocs[2] = NULL; + + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (section_symbol (absolute_section)); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_SPARC13); + reloc->addend = fixp->tc_fix_data; + } + + return relocs; } /* We have no need to default values of symbols. */ @@ -2961,7 +3263,7 @@ md_pcrel_from (fixP) ret = fixP->fx_where + fixP->fx_frag->fr_address; if (! sparc_pic_code || fixP->fx_addsy == NULL - || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0) + || symbol_section_p (fixP->fx_addsy)) ret += fixP->fx_size; return ret; } @@ -3110,9 +3412,9 @@ s_reserve (ignore) /* detach from old frag */ if (S_GET_SEGMENT(symbolP) == bss_section) - symbolP->sy_frag->fr_symbol = NULL; + symbol_get_frag (symbolP)->fr_symbol = NULL; - symbolP->sy_frag = frag_now; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, (offsetT) size, (char *)0); *pfrag = 0; @@ -3189,7 +3491,7 @@ s_common (ignore) S_SET_EXTERNAL (symbolP); #endif } - know (symbolP->sy_frag == &zero_address_frag); + know (symbol_get_frag (symbolP) == &zero_address_frag); if (*input_line_pointer != ',') { as_bad (_("Expected comma after common length")); @@ -3218,7 +3520,7 @@ s_common (ignore) } #ifdef OBJ_ELF - if (symbolP->local) + if (symbol_get_obj (symbolP)->local) { segT old_sec; int old_subsec; @@ -3245,8 +3547,8 @@ s_common (ignore) if (align) frag_align (align, 0, 0); if (S_GET_SEGMENT (symbolP) == bss_section) - symbolP->sy_frag->fr_symbol = 0; - symbolP->sy_frag = frag_now; + symbol_get_frag (symbolP)->fr_symbol = 0; + symbol_set_frag (symbolP, frag_now); p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) size, (char *) 0); *p = 0; @@ -3289,7 +3591,7 @@ s_common (ignore) } #ifdef BFD_ASSEMBLER - symbolP->bsym->flags |= BSF_OBJECT; + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; #endif demand_empty_rest_of_line (); @@ -3394,6 +3696,17 @@ s_uacons (bytes) cons (bytes); } +/* This handles the native word allocation pseudo-op .nword. + For sparc_arch_size 32 it is equivalent to .word, for + sparc_arch_size 64 it is equivalent to .xword. */ + +static void +s_ncons (bytes) + int bytes; +{ + cons (sparc_arch_size == 32 ? 4 : 8); +} + /* If the --enforce-aligned-data option is used, we require .word, et. al., to be aligned correctly. We do it by setting up an rs_align_code frag, and checking in HANDLE_ALIGN to make sure that diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index 2a05764..40ab02c8 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -35,6 +35,9 @@ struct frag; extern const char *sparc_target_format PARAMS ((void)); #define TARGET_FORMAT sparc_target_format () +#define RELOC_EXPANSION_POSSIBLE +#define MAX_RELOC_EXPANSION 2 + #if 0 #ifdef TE_SPARCAOUT /* Bi-endian support may eventually be unconditional, but until things are @@ -57,7 +60,7 @@ extern int sparc_pic_code; #define md_do_align(n, fill, len, max, around) \ if ((n) && (n) <= 10 && !need_pass_2 && !(fill) \ - && now_seg != data_section && now_seg != bss_section) \ + && subseg_text_p (now_seg)) \ { \ char *p; \ p = frag_var (rs_align_code, 1 << n, 1, (relax_substateT) 1024, \ @@ -129,8 +132,7 @@ extern int elf32_sparc_force_relocation PARAMS ((struct fix *)); || ((FIX)->fx_subsy != NULL \ && (S_GET_SEGMENT ((FIX)->fx_subsy) \ == S_GET_SEGMENT ((FIX)->fx_addsy))) \ - || strchr (S_GET_NAME ((FIX)->fx_addsy), '\001') != NULL \ - || strchr (S_GET_NAME ((FIX)->fx_addsy), '\002') != NULL)) + || S_IS_LOCAL ((FIX)->fx_addsy))) #endif #ifdef OBJ_AOUT @@ -161,4 +163,21 @@ extern void sparc_md_end PARAMS ((void)); extern void cons_fix_new_sparc PARAMS ((struct frag *, int, unsigned int, struct expressionS *)); +#define TC_FIX_TYPE valueT + +#define TC_INIT_FIX_DATA(X) \ + do \ + { \ + (X)->tc_fix_data = 0; \ + } \ + while(0) + +#define TC_FIX_DATA_PRINT(FILE, FIXP) \ + do \ + { \ + fprintf((FILE), "addend2=%ld\n", \ + (unsigned long) (FIXP)->tc_fix_data); \ + } \ + while(0) + /* end of tc-sparc.h */ diff --git a/gas/config/tc-tahoe.c b/gas/config/tc-tahoe.c index 2bd63ca..26a7524 100644 --- a/gas/config/tc-tahoe.c +++ b/gas/config/tc-tahoe.c @@ -1611,7 +1611,7 @@ md_assemble (instruction_string) segT to_seg; /* Target segment of the address. */ register valueT this_add_number; - register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */ + register symbolS *this_add_symbol; /* +ve (minuend) symbol. */ /* tahoe_opcodeT opcode_as_number; fixme: remove this line *//* The opcode as a number. */ char *opcodeP; /* Where it is in a frag. */ diff --git a/gas/config/tc-tic30.c b/gas/config/tc-tic30.c index 61ed905..255c06a 100644 --- a/gas/config/tc-tic30.c +++ b/gas/config/tc-tic30.c @@ -1,5 +1,5 @@ /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30 - Copyright (C) 1998 Free Software Foundation. + Copyright (C) 1998, 1999 Free Software Foundation. Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au) This file is part of GAS, the GNU Assembler. @@ -1842,7 +1842,8 @@ tc_gen_reloc (section, fixP) rel = (arelent *) xmalloc (sizeof (arelent)); assert (rel != 0); - rel->sym_ptr_ptr = &fixP->fx_addsy->bsym; + rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); rel->address = fixP->fx_frag->fr_address + fixP->fx_where; if (fixP->fx_pcrel) rel->addend = fixP->fx_addnumber; diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c index c8ab145..c8d308c 100644 --- a/gas/config/tc-v850.c +++ b/gas/config/tc-v850.c @@ -1,5 +1,5 @@ /* tc-v850.c -- Assembler code for the NEC V850 - Copyright (C) 1996, 1997, 1998 Free Software Foundation. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -297,7 +297,7 @@ v850_comm (area) } } - know (symbolP->sy_frag == & zero_address_frag); + know (symbol_get_frag (symbolP) == & zero_address_frag); if (*input_line_pointer != ',') have_align = 0; @@ -323,7 +323,7 @@ v850_comm (area) } } - if (symbolP->local) + if (symbol_get_obj (symbolP)->local) { segT old_sec; int old_subsec; @@ -421,24 +421,24 @@ v850_comm (area) { case AREA_SDA: if (S_GET_SEGMENT (symbolP) == sbss_section) - symbolP->sy_frag->fr_symbol = 0; + symbol_get_frag (symbolP)->fr_symbol = 0; break; case AREA_ZDA: if (S_GET_SEGMENT (symbolP) == zbss_section) - symbolP->sy_frag->fr_symbol = 0; + symbol_get_frag (symbolP)->fr_symbol = 0; break; case AREA_TDA: if (S_GET_SEGMENT (symbolP) == tbss_section) - symbolP->sy_frag->fr_symbol = 0; + symbol_get_frag (symbolP)->fr_symbol = 0; break; default: - abort(); + abort (); } - symbolP->sy_frag = frag_now; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) size, (char *) 0); *pfrag = 0; @@ -548,7 +548,7 @@ v850_comm (area) goto allocate_common; } - symbolP->bsym->flags |= BSF_OBJECT; + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; demand_empty_rest_of_line (); return; @@ -726,9 +726,9 @@ reg_name_search (regs, regcount, name, accept_numbers) { /* If the symbol is an alias for another name then use that. If the symbol is an alias for a number, then return the number. */ - if (symbolP->sy_value.X_op == O_symbol) + if (symbol_equated_p (symbolP)) { - name = S_GET_NAME (symbolP->sy_value.X_add_symbol); + name = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol); } else if (accept_numbers) { @@ -2243,7 +2243,8 @@ tc_gen_reloc (seg, fixp) arelent * reloc; reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = & fixp->fx_addsy->bsym; + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr= symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 24e4a9b..f425ccc 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -1,5 +1,6 @@ /* tc-vax.c - vax-specific - - Copyright (C) 1987, 91, 92, 93, 94, 95, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 91, 92, 93, 94, 95, 98, 1999 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -335,7 +336,7 @@ md_assemble (instruction_string) segT to_seg; valueT this_add_number; /* Positive (minuend) symbol. */ - struct symbol *this_add_symbol; + symbolS *this_add_symbol; /* As a number. */ long opcode_as_number; /* Least significant byte 1st. */ diff --git a/gas/config/tc-w65.c b/gas/config/tc-w65.c index 72201e7..e57eb0f 100644 --- a/gas/config/tc-w65.c +++ b/gas/config/tc-w65.c @@ -1081,7 +1081,7 @@ md_pcrel_from (fixP) void tc_coff_symbol_emit_hook (x) - struct symbol *x; + symbolS *x; { } diff --git a/gas/config/tc-z8k.c b/gas/config/tc-z8k.c index 1611341..f89b14b 100644 --- a/gas/config/tc-z8k.c +++ b/gas/config/tc-z8k.c @@ -1,5 +1,5 @@ /* tc-z8k.c -- Assemble code for the Zilog Z800n - Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation. + Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -1520,7 +1520,7 @@ md_pcrel_from (fixP) void tc_coff_symbol_emit_hook (s) - struct symbol *s; + symbolS *s; { } |