From: Ian Lance Taylor Date: Wed, 14 Jul 1993 19:35:45 +0000 (+0000) Subject: * Changes to keep a full expression as the value of a symbol, not X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=85051959f4b156350cb8fcb4c08db004950f3ea1;p=binutils-gdb.git * Changes to keep a full expression as the value of a symbol, not just a longword: * struc-symbol.h: New field sy_value. * as.h: Include expr.h before struc-symbol.h. * expr.h: Use struct symbol rather than symbolS. * symbols.c (S_GET_VALUE, S_SET_VALUE): Rewrote to retrieve value of sy_value field; compile unconditionally, not just if BFD_ASSEMBLER. * symbols.h: Compile S_{SG}ET_VALUE prototypes unconditionally. * write.c (write_object_file): Set BFD symbol value to gas symbol value. * config/obj-aout.h, config/obj-bout.h, config/obj-coff.h, config/obj-coffbfd.h, config/obj-generic.h, config/obj-vms.h (S_GET_VALUE, S_SET_VALUE): Removed macro definitions. * config/obj-ieee.c (S_GET_VALUE, S_SET_VALUE): Removed. * config/obj-coff.h, obj-coffbfd.h: Rewrote several macros to use S_GET_VALUE rather than ost_entry.n_value. * config/obj-aout.c (obj_symbol_to_chars), config/obj-bout.c (obj_symbol_to_chars), config/obj-coff.c (obj_symbol_to_chars), config/obj-coffbfd.c (symbol_to_chars): Get value to write out using S_GET_VALUE--don't assume it is already set. * config/obj-ieee.c (do_symbols): Set BFD symbol value to gas symbol value. * config/obj-vms.c (various): Don't assign directly to S_GET_VALUE; use S_SET_VALUE instead. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 685447d5c1b..6027904b7ba 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,31 @@ +Wed Jul 14 15:09:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * Changes to keep a full expression as the value of a symbol, not + just a longword: + * struc-symbol.h: New field sy_value. + * as.h: Include expr.h before struc-symbol.h. + * expr.h: Use struct symbol rather than symbolS. + * symbols.c (S_GET_VALUE, S_SET_VALUE): Rewrote to retrieve value + of sy_value field; compile unconditionally, not just if + BFD_ASSEMBLER. + * symbols.h: Compile S_{SG}ET_VALUE prototypes unconditionally. + * write.c (write_object_file): Set BFD symbol value to gas symbol + value. + * config/obj-aout.h, config/obj-bout.h, config/obj-coff.h, + config/obj-coffbfd.h, config/obj-generic.h, config/obj-vms.h + (S_GET_VALUE, S_SET_VALUE): Removed macro definitions. + * config/obj-ieee.c (S_GET_VALUE, S_SET_VALUE): Removed. + * config/obj-coff.h, obj-coffbfd.h: Rewrote several macros to use + S_GET_VALUE rather than ost_entry.n_value. + * config/obj-aout.c (obj_symbol_to_chars), config/obj-bout.c + (obj_symbol_to_chars), config/obj-coff.c (obj_symbol_to_chars), + config/obj-coffbfd.c (symbol_to_chars): Get value to write out + using S_GET_VALUE--don't assume it is already set. + * config/obj-ieee.c (do_symbols): Set BFD symbol value to gas + symbol value. + * config/obj-vms.c (various): Don't assign directly to + S_GET_VALUE; use S_SET_VALUE instead. + Wed Jul 14 09:35:23 1993 Doug Evans (dje@canuck.cygnus.com) * configure.in: Recognize h8300h. diff --git a/gas/as.h b/gas/as.h index b6992c84508..1b2561f1da2 100644 --- a/gas/as.h +++ b/gas/as.h @@ -464,11 +464,9 @@ void subseg_new PARAMS ((segT seg, subsegT subseg)); /* this one starts the chain of target dependant headers */ #include "targ-env.h" -/* these define types needed by the interfaces */ +#include "expr.h" #include "struc-symbol.h" - #include "write.h" -#include "expr.h" #include "frags.h" #include "hash.h" #include "read.h" diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c index db3c3ec5296..c074df2cd58 100644 --- a/gas/config/obj-aout.c +++ b/gas/config/obj-aout.c @@ -1,113 +1,150 @@ /* a.out object file format - Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, - or (at your option) any later version. - - GAS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - the GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with GAS; see the file COPYING. If not, write - to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. + +This file is part of GAS, the GNU Assembler. + +GAS is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2, +or (at your option) any later version. + +GAS is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +the GNU General Public License for more details. + +You should have received a copy of the GNU General Public +License along with GAS; see the file COPYING. If not, write +to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "as.h" #include "aout/stab_gnu.h" #include "obstack.h" +#ifndef BFD_ASSEMBLER /* in: segT out: N_TYPE bits */ -const short seg_N_TYPE[] = { - N_ABS, - N_TEXT, - N_DATA, - N_BSS, - N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ - N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ - N_UNDF, /* debug */ - N_UNDF, /* ntv */ - N_UNDF, /* ptv */ - N_REGISTER, /* register */ +const short seg_N_TYPE[] = +{ + N_ABS, + N_TEXT, + N_DATA, + N_BSS, + N_UNDF, /* unknown */ + N_UNDF, /* absent */ + N_UNDF, /* pass1 */ + N_UNDF, /* error */ + N_UNDF, /* bignum/flonum */ + N_UNDF, /* difference */ + N_UNDF, /* debug */ + N_UNDF, /* ntv */ + N_UNDF, /* ptv */ + N_REGISTER, /* register */ }; -const segT N_TYPE_seg [N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ - SEG_UNKNOWN, /* N_UNDF == 0 */ - SEG_GOOF, - SEG_ABSOLUTE, /* N_ABS == 2 */ - SEG_GOOF, - SEG_TEXT, /* N_TEXT == 4 */ - SEG_GOOF, - SEG_DATA, /* N_DATA == 6 */ - SEG_GOOF, - SEG_BSS, /* N_BSS == 8 */ - SEG_GOOF, - SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, - SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, - SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, - SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */ - SEG_GOOF, +const segT N_TYPE_seg[N_TYPE + 2] = +{ /* N_TYPE == 0x1E = 32-2 */ + SEG_UNKNOWN, /* N_UNDF == 0 */ + SEG_GOOF, + SEG_ABSOLUTE, /* N_ABS == 2 */ + SEG_GOOF, + SEG_TEXT, /* N_TEXT == 4 */ + SEG_GOOF, + SEG_DATA, /* N_DATA == 6 */ + SEG_GOOF, + SEG_BSS, /* N_BSS == 8 */ + SEG_GOOF, + SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, + SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, + SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, + SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */ + SEG_GOOF, }; +#endif + +static void obj_aout_stab PARAMS ((int what)); +static void obj_aout_line PARAMS ((void)); +static void obj_aout_desc PARAMS ((void)); -#if __STDC__ == 1 -static void obj_aout_stab(int what); -static void obj_aout_line(void); -static void obj_aout_desc(void); -#else /* not __STDC__ */ -static void obj_aout_desc(); -static void obj_aout_stab(); -static void obj_aout_line(); -#endif /* not __STDC__ */ - -const pseudo_typeS obj_pseudo_table[] = { -#ifndef IGNORE_DEBUG - /* stabs debug info */ - { "line", obj_aout_line, 0 }, /* source code line number */ - { "ln", obj_aout_line, 0 }, /* coff line number that we use anyway */ - { "desc", obj_aout_desc, 0 }, /* desc */ - { "stabd", obj_aout_stab, 'd' }, /* stabs */ - { "stabn", obj_aout_stab, 'n' }, /* stabs */ - { "stabs", obj_aout_stab, 's' }, /* stabs */ -#else /* IGNORE_DEBUG */ - { "line", obj_aout_line, 0 }, /* source code line number */ - { "ln", obj_aout_line, 0 }, /* coff line number that we use anyway */ - { "desc", obj_aout_desc, 0 }, /* desc */ - { "stabd", obj_aout_stab, 'd' }, /* stabs */ - { "stabn", obj_aout_stab, 'n' }, /* stabs */ - { "stabs", obj_aout_stab, 's' }, /* stabs */ -#endif /* IGNORE_DEBUG */ - - /* coff debug pseudos (ignored) */ - { "def", s_ignore, 0 }, - { "dim", s_ignore, 0 }, - { "endef", s_ignore, 0 }, - { "ident", s_ignore, 0 }, - { "line", s_ignore, 0 }, - { "ln", s_ignore, 0 }, - { "scl", s_ignore, 0 }, - { "size", s_ignore, 0 }, - { "tag", s_ignore, 0 }, - { "type", s_ignore, 0 }, - { "val", s_ignore, 0 }, - { "version", s_ignore, 0 }, - - /* stabs-in-coff (?) debug pseudos (ignored) */ - { "optim", s_ignore, 0 }, /* For sun386i cc (?) */ - - /* other stuff */ - { "ABORT", s_abort, 0 }, - - { NULL} /* end sentinel */ -}; /* obj_pseudo_table */ +const pseudo_typeS obj_pseudo_table[] = +{ + /* stabs debug info */ + {"line", obj_aout_line, 0}, /* source code line number */ + {"ln", obj_aout_line, 0}, /* coff line number that we use anyway */ + {"desc", obj_aout_desc, 0}, /* desc */ + {"stabd", obj_aout_stab, 'd'},/* stabs */ + {"stabn", obj_aout_stab, 'n'},/* stabs */ + {"stabs", obj_aout_stab, 's'},/* stabs */ + /* coff debug pseudos (ignored) */ + {"def", s_ignore, 0}, + {"dim", s_ignore, 0}, + {"endef", s_ignore, 0}, + {"ident", s_ignore, 0}, + {"line", s_ignore, 0}, + {"ln", s_ignore, 0}, + {"scl", s_ignore, 0}, + {"size", s_ignore, 0}, + {"tag", s_ignore, 0}, + {"type", s_ignore, 0}, + {"val", s_ignore, 0}, + {"version", s_ignore, 0}, + + /* stabs-in-coff (?) debug pseudos (ignored) */ + {"optim", s_ignore, 0}, /* For sun386i cc (?) */ + + /* other stuff */ + {"ABORT", s_abort, 0}, + + {NULL} /* end sentinel */ +}; /* obj_pseudo_table */ + + +#ifdef BFD_ASSEMBLER + +void +obj_aout_frob_symbol (sym, punt) + symbolS *sym; + int *punt; +{ + flagword flags; + asection *sec; + int desc, type, other; + + /* Is this part format-dependent? */ + if (sym->sy_forward) + { + S_SET_VALUE (sym, + S_GET_VALUE (sym) + + S_GET_VALUE (sym->sy_forward) + + sym->sy_forward->sy_frag->fr_address + ); + sym->sy_forward = 0; + } + + flags = sym->bsym->flags; + desc = S_GET_DESC (sym); + type = S_GET_TYPE (sym); + other = S_GET_OTHER (sym); + sec = sym->bsym->section; + + /* Only frob simple symbols this way right now. */ + if (! (type & ~0x1f)) + { + if (sec == &bfd_abs_section + || sec == &bfd_und_section) + return; + if (flags & BSF_EXPORT) + type |= 1; + } + else + { + sym->bsym->flags |= BSF_DEBUGGING; + } + + S_SET_TYPE (sym, type); +} + +#else /* Relocation. */ @@ -116,108 +153,104 @@ const pseudo_typeS obj_pseudo_table[] = { * * Crawl along a fixS chain. Emit the segment's relocations. */ -void obj_emit_relocations(where, fixP, segment_address_in_file) -char **where; -fixS *fixP; /* Fixup chain for this segment. */ -relax_addressT segment_address_in_file; +void +obj_emit_relocations (where, fixP, segment_address_in_file) + char **where; + fixS *fixP; /* Fixup chain for this segment. */ + relax_addressT segment_address_in_file; { - for (; fixP; fixP = fixP->fx_next) { - if (fixP->fx_addsy != NULL) { - tc_aout_fix_to_chars(*where, fixP, segment_address_in_file); - *where += md_reloc_size; - } /* if there is an add symbol */ - } /* for each fix */ - - return; -} /* obj_emit_relocations() */ + for (; fixP; fixP = fixP->fx_next) + if (fixP->fx_addsy != NULL) + { + tc_aout_fix_to_chars (*where, fixP, segment_address_in_file); + *where += md_reloc_size; + } +} +#ifndef obj_header_append /* Aout file generation & utilities */ -void obj_header_append(where, headers) -char **where; -object_headers *headers; +void +obj_header_append (where, headers) + char **where; + object_headers *headers; { - tc_headers_hook(headers); - + tc_headers_hook (headers); + #ifdef CROSS_COMPILE - md_number_to_chars(*where, headers->header.a_info, sizeof(headers->header.a_info)); - *where += sizeof(headers->header.a_info); - md_number_to_chars(*where, headers->header.a_text, sizeof(headers->header.a_text)); - *where += sizeof(headers->header.a_text); - md_number_to_chars(*where, headers->header.a_data, sizeof(headers->header.a_data)); - *where += sizeof(headers->header.a_data); - md_number_to_chars(*where, headers->header.a_bss, sizeof(headers->header.a_bss)); - *where += sizeof(headers->header.a_bss); - md_number_to_chars(*where, headers->header.a_syms, sizeof(headers->header.a_syms)); - *where += sizeof(headers->header.a_syms); - md_number_to_chars(*where, headers->header.a_entry, sizeof(headers->header.a_entry)); - *where += sizeof(headers->header.a_entry); - md_number_to_chars(*where, headers->header.a_trsize, sizeof(headers->header.a_trsize)); - *where += sizeof(headers->header.a_trsize); - md_number_to_chars(*where, headers->header.a_drsize, sizeof(headers->header.a_drsize)); - *where += sizeof(headers->header.a_drsize); - + md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info)); + *where += sizeof (headers->header.a_info); + md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text)); + *where += sizeof (headers->header.a_text); + md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data)); + *where += sizeof (headers->header.a_data); + md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss)); + *where += sizeof (headers->header.a_bss); + md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms)); + *where += sizeof (headers->header.a_syms); + md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry)); + *where += sizeof (headers->header.a_entry); + md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize)); + *where += sizeof (headers->header.a_trsize); + md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize)); + *where += sizeof (headers->header.a_drsize); + #else /* CROSS_COMPILE */ - - append(where, (char *) &headers->header, sizeof(headers->header)); + + append (where, (char *) &headers->header, sizeof (headers->header)); #endif /* CROSS_COMPILE */ - - return; -} /* obj_append_header() */ -void obj_symbol_to_chars(where, symbolP) -char **where; -symbolS *symbolP; -{ - md_number_to_chars((char *)&(S_GET_OFFSET(symbolP)), S_GET_OFFSET(symbolP), sizeof(S_GET_OFFSET(symbolP))); - md_number_to_chars((char *)&(S_GET_DESC(symbolP)), S_GET_DESC(symbolP), sizeof(S_GET_DESC(symbolP))); - md_number_to_chars((char *)&(S_GET_VALUE(symbolP)), S_GET_VALUE(symbolP), sizeof(S_GET_VALUE(symbolP))); - - append(where, (char *)&symbolP->sy_symbol, sizeof(obj_symbol_type)); -} /* obj_symbol_to_chars() */ - -void obj_emit_symbols(where, symbol_rootP) -char **where; -symbolS *symbol_rootP; +} +#endif + +void +obj_symbol_to_chars (where, symbolP) + char **where; + symbolS *symbolP; { - symbolS * symbolP; - - /* - * Emit all symbols left in the symbol chain. - */ - for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - /* Used to save the offset of the name. It is used to point - to the string in memory but must be a file offset. */ - register char *temp; - - temp = S_GET_NAME(symbolP); - S_SET_OFFSET(symbolP, symbolP->sy_name_offset); - - /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ - if (!S_IS_DEBUG(symbolP) && !S_IS_DEFINED(symbolP)) S_SET_EXTERNAL(symbolP); - - obj_symbol_to_chars(where, symbolP); - S_SET_NAME(symbolP,temp); - } -} /* emit_symbols() */ + md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP))); + md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP))); + md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value)); + + append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type)); +} -#if comment -/* uneeded if symbol is born zeroed. */ -void obj_symbol_new_hook(symbolP) -symbolS *symbolP; +void +obj_emit_symbols (where, symbol_rootP) + char **where; + symbolS *symbol_rootP; { - S_SET_OTHER(symbolP, 0); - S_SET_DESC(symbolP, 0); - return; -} /* obj_symbol_new_hook() */ -#endif /* comment */ + symbolS *symbolP; + + /* Emit all symbols left in the symbol chain. */ + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { + /* Used to save the offset of the name. It is used to point + to the string in memory but must be a file offset. */ + register char *temp; + + temp = S_GET_NAME (symbolP); + S_SET_OFFSET (symbolP, symbolP->sy_name_offset); -static void obj_aout_line() { - /* Assume delimiter is part of expression. */ - /* BSD4.2 as fails with delightful bug, so we */ - /* are not being incompatible here. */ - new_logical_line((char *)NULL, (int)(get_absolute_expression())); - demand_empty_rest_of_line(); -} /* obj_aout_line() */ + /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ + if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP)) + S_SET_EXTERNAL (symbolP); + + obj_symbol_to_chars (where, symbolP); + S_SET_NAME (symbolP, temp); + } +} + +#endif /* ! BFD_ASSEMBLER */ + +static void +obj_aout_line () +{ + /* Assume delimiter is part of expression. + BSD4.2 as fails with delightful bug, so we + are not being incompatible here. */ + new_logical_line ((char *) NULL, (int) (get_absolute_expression ())); + demand_empty_rest_of_line (); +} /* obj_aout_line() */ /* * stab() @@ -238,276 +271,366 @@ static void obj_aout_line() { * .stabX directives always make a symbol table entry. It may be junk if * the rest of your .stabX directive is malformed. */ -static void obj_aout_stab(what) -int what; +static void +obj_aout_stab (what) + int what; { - extern int listing; - - register symbolS * symbolP = 0; - register char * string; - int saved_type = 0; - int length; - int goof; /* TRUE if we have aborted. */ - long longint; - - /* - * Enter with input_line_pointer pointing past .stabX and any following - * whitespace. - */ - goof = 0; /* JF who forgot this?? */ - if (what == 's') { - string = demand_copy_C_string(& length); - SKIP_WHITESPACE(); - if (* input_line_pointer == ',') - input_line_pointer ++; - else { - as_bad("I need a comma after symbol's name"); - goof = 1; - } - } else - string = ""; - - /* - * Input_line_pointer->after ','. String->symbol name. - */ - if (! goof) { - symbolP = symbol_new(string, - SEG_UNKNOWN, - 0, - (struct frag *)0); - switch (what) { - case 'd': - S_SET_NAME(symbolP, NULL); /* .stabd feature. */ - S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal); - symbolP->sy_frag = frag_now; - break; - - case 'n': - symbolP->sy_frag = &zero_address_frag; - break; - - case 's': - symbolP->sy_frag = & zero_address_frag; - break; - - default: - BAD_CASE(what); - break; - } - - if (get_absolute_expression_and_terminator(&longint) == ',') - symbolP->sy_symbol.n_type = saved_type = longint; - else { - as_bad("I want a comma after the n_type expression"); - goof = 1; - input_line_pointer --; /* Backup over a non-',' char. */ - } + extern int listing; + + register symbolS *symbolP = 0; + register char *string; + int saved_type = 0; + int length; + int goof; /* TRUE if we have aborted. */ + long longint; + + /* + * Enter with input_line_pointer pointing past .stabX and any following + * whitespace. + */ + goof = 0; /* JF who forgot this?? */ + if (what == 's') + { + string = demand_copy_C_string (&length); + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + input_line_pointer++; + else + { + as_bad ("I need a comma after symbol's name"); + goof = 1; } - - if (!goof) { - if (get_absolute_expression_and_terminator(&longint) == ',') - S_SET_OTHER(symbolP, longint); - else { - as_bad("I want a comma after the n_other expression"); - goof = 1; - input_line_pointer--; /* Backup over a non-',' char. */ - } + } + else + string = ""; + + /* + * Input_line_pointer->after ','. String->symbol name. + */ + if (!goof) + { + symbolP = symbol_new (string, undefined_section, 0, (struct frag *) 0); + switch (what) + { + case 'd': + S_SET_NAME (symbolP, NULL); /* .stabd feature. */ + S_SET_VALUE (symbolP, (char*) obstack_next_free (&frags) - frag_now->fr_literal); + symbolP->sy_frag = frag_now; + break; + + case 'n': + symbolP->sy_frag = &zero_address_frag; + break; + + case 's': + symbolP->sy_frag = &zero_address_frag; + break; + + default: + BAD_CASE (what); + break; } - - if (!goof) { - S_SET_DESC(symbolP, get_absolute_expression()); - if (what == 's' || what == 'n') { - if (*input_line_pointer != ',') { - as_bad("I want a comma after the n_desc expression"); - goof = 1; - } else { - input_line_pointer++; - } - } + + if (get_absolute_expression_and_terminator (&longint) == ',') + { + saved_type = longint; + S_SET_TYPE (symbolP, saved_type); } - - if ((!goof) && (what=='s' || what=='n')) { - pseudo_set(symbolP); - symbolP->sy_symbol.n_type = saved_type; + else + { + as_bad ("I want a comma after the n_type expression"); + goof = 1; + input_line_pointer--; /* Backup over a non-',' char. */ } -#ifndef NO_LISTING - if (listing && !goof) + } + + if (!goof) + { + if (get_absolute_expression_and_terminator (&longint) == ',') + S_SET_OTHER (symbolP, longint); + else + { + as_bad ("I want a comma after the n_other expression"); + goof = 1; + input_line_pointer--; /* Backup over a non-',' char. */ + } + } + + if (!goof) + { + S_SET_DESC (symbolP, get_absolute_expression ()); + if (what == 's' || what == 'n') + { + if (*input_line_pointer != ',') { - if (symbolP->sy_symbol.n_type == N_SLINE) - { - - listing_source_line(symbolP->sy_symbol.n_desc); - } - else if (symbolP->sy_symbol.n_type == N_SO - || symbolP->sy_symbol.n_type == N_SOL) - { - listing_source_file(string); - } + as_bad ("I want a comma after the n_desc expression"); + goof = 1; + } + else + { + input_line_pointer++; } -#endif - - if (goof) - ignore_rest_of_line(); - else - demand_empty_rest_of_line (); -} /* obj_aout_stab() */ - -static void obj_aout_desc() { - register char *name; - register char c; - register char *p; - register symbolS *symbolP; - register int temp; - - /* - * Frob invented at RMS' request. Set the n_desc of a symbol. - */ - name = input_line_pointer; - c = get_symbol_end(); - p = input_line_pointer; - * p = c; - SKIP_WHITESPACE(); - if (*input_line_pointer != ',') { - *p = 0; - as_bad("Expected comma after name \"%s\"", name); - *p = c; - ignore_rest_of_line(); - } else { - input_line_pointer ++; - temp = get_absolute_expression(); - *p = 0; - symbolP = symbol_find_or_make(name); - *p = c; - S_SET_DESC(symbolP,temp); } - demand_empty_rest_of_line(); -} /* obj_aout_desc() */ + } -void obj_read_begin_hook() { - return; -} /* obj_read_begin_hook() */ + if ((!goof) && (what == 's' || what == 'n')) + { + pseudo_set (symbolP); + S_SET_TYPE (symbolP, saved_type); + } +#ifndef NO_LISTING + if (listing && !goof) + { + if (S_GET_TYPE (symbolP) == N_SLINE) + { + listing_source_line (S_GET_DESC (symbolP)); + } + else if (S_GET_TYPE (symbolP) == N_SO || S_GET_TYPE (symbolP) == N_SOL) + { + listing_source_file (string); + } + } +#endif + + if (goof) + ignore_rest_of_line (); + else + demand_empty_rest_of_line (); +} /* obj_aout_stab() */ + +static void +obj_aout_desc () +{ + register char *name; + register char c; + register char *p; + register symbolS *symbolP; + register int temp; + + /* + * Frob invented at RMS' request. Set the n_desc of a symbol. + */ + name = input_line_pointer; + c = get_symbol_end (); + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + *p = 0; + as_bad ("Expected comma after name \"%s\"", name); + *p = c; + ignore_rest_of_line (); + } + else + { + input_line_pointer++; + temp = get_absolute_expression (); + *p = 0; + symbolP = symbol_find_or_make (name); + *p = c; + S_SET_DESC (symbolP, temp); + } + demand_empty_rest_of_line (); +} /* obj_aout_desc() */ + +void +obj_read_begin_hook () +{ + return; +} /* obj_read_begin_hook() */ + +#ifndef BFD_ASSEMBLER -void obj_crawl_symbol_chain(headers) -object_headers *headers; +void +obj_crawl_symbol_chain (headers) + object_headers *headers; { - symbolS *symbolP; - symbolS **symbolPP; - int symbol_number = 0; - - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - if (symbolP->sy_forward) { - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) - + S_GET_VALUE(symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address); - - symbolP->sy_forward=0; - } /* if it has a forward reference */ - } /* walk the symbol chain */ - - tc_crawl_symbol_chain(headers); - - symbolPP = &symbol_rootP; /*->last symbol chain link. */ - while ((symbolP = *symbolPP) != NULL) { - if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) { - S_SET_SEGMENT(symbolP, SEG_TEXT); - } /* if pusing data into text */ - - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); - - /* OK, here is how we decide which symbols go out into the - brave new symtab. Symbols that do are: - - * symbols with no name (stabd's?) - * symbols with debug info in their N_TYPE - - Symbols that don't are: - * symbols that are registers - * symbols with \1 as their 3rd character (numeric labels) - * "local labels" as defined by S_LOCAL_NAME(name) - if the -L switch was passed to gas. - - All other symbols are output. We complain if a deleted - symbol was marked external. */ - - - if (!S_IS_REGISTER(symbolP) - && (!S_GET_NAME(symbolP) - || S_IS_DEBUG(symbolP) + symbolS *symbolP; + symbolS **symbolPP; + int symbol_number = 0; + + /* JF deal with forward references first... */ + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { + if (symbolP->sy_forward) + { + S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + + S_GET_VALUE (symbolP->sy_forward) + + symbolP->sy_forward->sy_frag->fr_address); + + symbolP->sy_forward = 0; + } /* if it has a forward reference */ + } /* walk the symbol chain */ + + tc_crawl_symbol_chain (headers); + + symbolPP = &symbol_rootP; /*->last symbol chain link. */ + while ((symbolP = *symbolPP) != NULL) + { + if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_DATA)) + { + S_SET_SEGMENT (symbolP, SEG_TEXT); + } /* if pusing data into text */ + + S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address); + + /* OK, here is how we decide which symbols go out into the brave + new symtab. Symbols that do are: + + * symbols with no name (stabd's?) + * symbols with debug info in their N_TYPE + + Symbols that don't are: + * symbols that are registers + * symbols with \1 as their 3rd character (numeric labels) + * "local labels" as defined by S_LOCAL_NAME(name) if the -L + switch was passed to gas. + + All other symbols are output. We complain if a deleted + symbol was marked external. */ + + + if (!S_IS_REGISTER (symbolP) + && (!S_GET_NAME (symbolP) + || S_IS_DEBUG (symbolP) #ifdef TC_I960 - /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ - || !S_IS_DEFINED(symbolP) - || S_IS_EXTERNAL(symbolP) + /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ + || !S_IS_DEFINED (symbolP) + || S_IS_EXTERNAL (symbolP) #endif /* TC_I960 */ - || (S_GET_NAME(symbolP)[0] != '\001' && (flagseen ['L'] || ! S_LOCAL_NAME(symbolP))))) { - symbolP->sy_number = symbol_number++; - - /* The + 1 after strlen account for the \0 at the + || (S_GET_NAME (symbolP)[0] != '\001' && (flagseen['L'] || !S_LOCAL_NAME (symbolP))))) + { + symbolP->sy_number = symbol_number++; + + /* The + 1 after strlen account for the \0 at the end of each string */ - if (!S_IS_STABD(symbolP)) { - /* Ordinary case. */ - symbolP->sy_name_offset = string_byte_count; - string_byte_count += strlen(S_GET_NAME(symbolP)) + 1; - } - else /* .Stabd case. */ - symbolP->sy_name_offset = 0; - symbolPP = &(symbol_next(symbolP)); - } else { - if (S_IS_EXTERNAL(symbolP) || !S_IS_DEFINED(symbolP)) { - as_bad("Local symbol %s never defined.", decode_local_label_name(S_GET_NAME(symbolP))); - } /* oops. */ - - /* Unhook it from the chain */ - *symbolPP = symbol_next(symbolP); - } /* if this symbol should be in the output */ - } /* for each symbol */ - - H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number); - - return; -} /* obj_crawl_symbol_chain() */ + if (!S_IS_STABD (symbolP)) + { + /* Ordinary case. */ + symbolP->sy_name_offset = string_byte_count; + string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; + } + else /* .Stabd case. */ + symbolP->sy_name_offset = 0; + symbolPP = &(symbol_next (symbolP)); + } + else + { + if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) + { + as_bad ("Local symbol %s never defined.", decode_local_label_name (S_GET_NAME (symbolP))); + } /* oops. */ + + /* Unhook it from the chain */ + *symbolPP = symbol_next (symbolP); + } /* if this symbol should be in the output */ + } /* for each symbol */ + + H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); + + return; +} /* obj_crawl_symbol_chain() */ /* * Find strings by crawling along symbol table chain. */ -void obj_emit_strings(where) -char **where; +void +obj_emit_strings (where) + char **where; { - symbolS *symbolP; - + symbolS *symbolP; + #ifdef CROSS_COMPILE - /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ - md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count)); - *where += sizeof(string_byte_count); + /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ + md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count)); + *where += sizeof (string_byte_count); #else /* CROSS_COMPILE */ - append (where, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); + append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count)); #endif /* CROSS_COMPILE */ - - for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - if(S_GET_NAME(symbolP)) - append(&next_object_file_charP, S_GET_NAME(symbolP), - (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1)); - } /* walk symbol chain */ - - return; -} /* obj_emit_strings() */ -void obj_pre_write_hook(headers) -object_headers *headers; + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { + if (S_GET_NAME (symbolP)) + append (&next_object_file_charP, S_GET_NAME (symbolP), + (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); + } /* walk symbol chain */ + + return; +} /* obj_emit_strings() */ + +#ifndef AOUT_VERSION +#define AOUT_VERSION 0 +#endif + +void +obj_pre_write_hook (headers) + object_headers *headers; { - H_SET_DYNAMIC(headers, 0); - H_SET_VERSION(headers, 0); - H_SET_MACHTYPE(headers, AOUT_MACHTYPE); - tc_aout_pre_write_hook(headers); - return; -} /* obj_pre_write_hook() */ + H_SET_DYNAMIC (headers, 0); + H_SET_VERSION (headers, AOUT_VERSION); + H_SET_MACHTYPE (headers, AOUT_MACHTYPE); + tc_aout_pre_write_hook (headers); + return; +} /* obj_pre_write_hook() */ -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ +void +DEFUN_VOID (s_sect) +{ + /* Strip out the section name */ + char *section_name; + char *section_name_end; + char c; + + unsigned int len; + unsigned int exp; + char *save; + + section_name = input_line_pointer; + c = get_symbol_end (); + section_name_end = input_line_pointer; + + len = section_name_end - section_name; + input_line_pointer++; + save = input_line_pointer; + + SKIP_WHITESPACE (); + if (c == ',') + { + exp = get_absolute_expression (); + } + else if (*input_line_pointer == ',') + { + input_line_pointer++; + exp = get_absolute_expression (); + } + else + { + input_line_pointer = save; + exp = 0; + } + if (exp >= 1000) + { + as_bad ("subsegment index too high"); + } + + if (strcmp (section_name, ".text") == 0) + { + subseg_new (SEG_TEXT, (subsegT) exp); + } + + if (strcmp (section_name, ".data") == 0) + { + if (flagseen['R']) + subseg_new (SEG_TEXT, (subsegT) exp + 1000); + else + subseg_new (SEG_DATA, (subsegT) exp); + } + + *section_name_end = c; +} + +#endif /* ! BFD_ASSEMBLER */ /* end of obj-aout.c */ diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c index 1b23b28220a..3ef289db281 100644 --- a/gas/config/obj-bout.c +++ b/gas/config/obj-bout.c @@ -183,7 +183,7 @@ obj_symbol_to_chars (where, symbolP) { md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP))); md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP))); - md_number_to_chars ((char *) &(S_GET_VALUE (symbolP)), S_GET_VALUE (symbolP), sizeof (S_GET_VALUE (symbolP))); + md_number_to_chars ((char *) &symbolP->sy_symbol.n_value, S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value)); append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type)); } /* obj_symbol_to_chars() */ diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h index 155b27ed324..2fa6f6e009d 100644 --- a/gas/config/obj-bout.h +++ b/gas/config/obj-bout.h @@ -199,8 +199,6 @@ struct relocation_info #define S_IS_STABD(s) (S_GET_NAME(s) == NULL) /* Accessors */ -/* The value of the symbol */ -#define S_GET_VALUE(s) ((s)->sy_symbol.n_value) /* The name of the symbol */ #define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name) /* The pointer to the string table */ @@ -215,8 +213,6 @@ struct relocation_info #define S_GET_DESC(s) ((s)->sy_symbol.n_desc) /* Modifiers */ -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ /* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 881402ae933..3bf0e754cab 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -21,6 +21,7 @@ #include "obstack.h" +#ifndef BFD_ASSEMBLER lineno *lineno_rootP; const short seg_N_TYPE[] = @@ -59,6 +60,7 @@ const segT N_TYPE_seg[32] = SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF }; +#endif char *s_get_name PARAMS ((symbolS * s)); static symbolS *tag_find_or_make PARAMS ((char *name)); @@ -72,7 +74,7 @@ static void obj_coff_def PARAMS ((int what)); static void obj_coff_dim PARAMS ((void)); static void obj_coff_endef PARAMS ((void)); static void obj_coff_line PARAMS ((void)); -static void obj_coff_ln PARAMS ((void)); +static void obj_coff_ln PARAMS ((int)); static void obj_coff_scl PARAMS ((void)); static void obj_coff_size PARAMS ((void)); static void obj_coff_stab PARAMS ((int what)); @@ -82,6 +84,11 @@ static void obj_coff_val PARAMS ((void)); static void tag_init PARAMS ((void)); static void tag_insert PARAMS ((char *name, symbolS * symbolP)); +#ifdef BFD_ASSEMBLER +static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *)); +static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *)); +#endif + int line_base; static struct hash_control *tag_hash; @@ -95,6 +102,7 @@ const pseudo_typeS obj_pseudo_table[] = {"endef", obj_coff_endef, 0}, {"line", obj_coff_line, 0}, {"ln", obj_coff_ln, 0}, + {"appline", obj_coff_ln, 1}, {"scl", obj_coff_scl, 0}, {"size", obj_coff_size, 0}, {"tag", obj_coff_tag, 0}, @@ -116,25 +124,35 @@ const pseudo_typeS obj_pseudo_table[] = {"ident", s_ignore, 0}, /* we don't yet handle this. */ -/* stabs aka a.out aka b.out directives for debug symbols. - Currently ignored silently. Except for .line at which - we guess from context. */ + /* stabs aka a.out aka b.out directives for debug symbols. + Currently ignored silently. Except for .line at which + we guess from context. */ {"desc", s_ignore, 0}, /* def */ -/* { "line", s_ignore, 0 }, *//* source code line number */ {"stabd", obj_coff_stab, 'd'},/* stabs */ {"stabn", obj_coff_stab, 'n'},/* stabs */ {"stabs", obj_coff_stab, 's'},/* stabs */ -/* stabs-in-coff (?) debug pseudos (ignored) */ + /* stabs-in-coff (?) debug pseudos (ignored) */ {"optim", s_ignore, 0}, /* For sun386i cc (?) */ -/* other stuff */ + /* other stuff */ {"ABORT", s_abort, 0}, {NULL} /* end sentinel */ }; /* obj_pseudo_table */ +#ifdef BFD_ASSEMBLER +struct line_no { + struct line_no *next; + fragS *frag; + alent l; +}; +#endif + +#define GET_FILENAME_STRING(X) \ +((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1]) /* obj dependant output values */ +#ifndef BFD_ASSEMBLER #ifdef BFD_HEADERS static struct internal_scnhdr bss_section_header; struct internal_scnhdr data_section_header; @@ -144,6 +162,53 @@ static SCNHDR bss_section_header; SCNHDR data_section_header; SCNHDR text_section_header; #endif +#endif + +#ifdef BFD_ASSEMBLER + +/* @@ Ick. */ +static segT +fetch_coff_debug_section () +{ + static segT debug_section; + if (!debug_section) + { + CONST asymbol *s; + s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0); + assert (s != 0); + debug_section = s->section; + } + return debug_section; +} + +static void +SA_SET_SYM_ENDNDX (sym, val) + symbolS *sym; + symbolS *val; +{ + combined_entry_type *entry, *p; + + entry = &coffsymbol (sym->bsym)->native[1]; + p = coffsymbol (val->bsym)->native; + entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p; + entry->fix_end = 1; +} + +static void +SA_SET_SYM_TAGNDX (sym, val) + symbolS *sym; + symbolS *val; +{ + combined_entry_type *entry, *p; + + entry = &coffsymbol (sym->bsym)->native[1]; + p = coffsymbol (val->bsym)->native; + entry->u.auxent.x_sym.x_tagndx.p = p; + entry->fix_tag = 1; +} + +#else /* ! BFD_ASSEMBLER */ + /* Relocation. */ static int @@ -205,6 +270,7 @@ obj_emit_relocations (where, fixP, segment_address_in_file) { if (symbolP = fixP->fx_addsy) { + int rtype_ok = 0; #if defined(TC_M68K) ri_table[i].r_type = (fixP->fx_pcrel ? (fixP->fx_size == 1 ? R_PCRBYTE : @@ -213,7 +279,9 @@ obj_emit_relocations (where, fixP, segment_address_in_file) (fixP->fx_size == 1 ? R_RELBYTE : fixP->fx_size == 2 ? R_RELWORD : R_RELLONG)); -#elif defined(TC_I386) + rtype_ok = 1; +#endif +#if defined(TC_I386) /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly untested. */ ri_table[i].r_type = (fixP->fx_pcrel ? @@ -223,39 +291,43 @@ obj_emit_relocations (where, fixP, segment_address_in_file) (fixP->fx_size == 1 ? R_OFF8 : fixP->fx_size == 2 ? R_DIR16 : R_DIR32)); -#elif defined(TC_I960) + rtype_ok = 1; +#endif +#if defined(TC_I960) ri_table[i].r_type = (fixP->fx_pcrel ? R_IPRMED : R_RELLONG); callj_table[i] = fixP->fx_callj ? 1 : 0; -#elif defined(TC_A29K) + rtype_ok = 1; +#endif +#if defined(TC_A29K) ri_table[i].r_type = tc_coff_fix2rtype (fixP); - -#else -#error you lose -#endif /* TC_M68K || TC_I386 */ + rtype_ok = 1; +#endif + if (!rtype_ok) + abort (); ri_table[i].r_vaddr = (fixP->fx_frag->fr_address + fixP->fx_where); /* If symbol associated to relocation entry is a bss symbol - or undefined symbol just remember the index of the symbol. - Otherwise store the index of the symbol describing the - section the symbol belong to. This heuristic speeds up ld. - */ + or undefined symbol just remember the index of the symbol. + Otherwise store the index of the symbol describing the + section the symbol belong to. This heuristic speeds up ld. + */ /* Local symbols can generate relocation information. In case - of structure return for instance. But they have no symbol - number because they won't be emitted in the final object. - In the case where they are in the BSS section, this leads - to an incorrect r_symndx. - Under bsd the loader do not care if the symbol reference - is incorrect. But the SYS V ld complains about this. To - avoid this we associate the symbol to the associated - section, *even* if it is the BSS section. */ + of structure return for instance. But they have no symbol + number because they won't be emitted in the final object. + In the case where they are in the BSS section, this leads + to an incorrect r_symndx. + Under bsd the loader do not care if the symbol reference + is incorrect. But the SYS V ld complains about this. To + avoid this we associate the symbol to the associated + section, *even* if it is the BSS section. */ /* If someone can tell me why the other symbols of the bss - section are not associated with the .bss section entry, - I'd be gratefull. I guess that it has to do with the special - nature of the .bss section. Or maybe this is because the - bss symbols are declared in the common section and can - be resized later. Can it break code some where ? */ + section are not associated with the .bss section entry, + I'd be gratefull. I guess that it has to do with the special + nature of the .bss section. Or maybe this is because the + bss symbols are declared in the common section and can + be resized later. Can it break code some where ? */ ri_table[i].r_symndx = (S_GET_SEGMENT (symbolP) == SEG_TEXT ? dot_text_symbol->sy_number : (S_GET_SEGMENT (symbolP) == SEG_DATA @@ -270,10 +342,8 @@ obj_emit_relocations (where, fixP, segment_address_in_file) } /* if there's a symbol */ } /* for each fixP */ - /* - * AIX ld prefer to have the reloc table with r_vaddr sorted. - * But sorting it should not hurt any other ld. - */ + /* AIX ld prefer to have the reloc table with r_vaddr sorted. + But sorting it should not hurt any other ld. */ qsort (ri_table, count, sizeof (*ri_table), reloc_compare); for (i = 0; i < count; i++) @@ -282,9 +352,9 @@ obj_emit_relocations (where, fixP, segment_address_in_file) *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], *where); # ifdef TC_A29K /* The 29k has a special kludge for the high 16 bit reloc. - Two relocations are emmited, R_IHIHALF, and R_IHCONST. - The second one doesn't contain a symbol, but uses the - value for offset */ + Two relocations are emmited, R_IHIHALF, and R_IHCONST. + The second one doesn't contain a symbol, but uses the + value for offset */ if (ri_table[i].r_type == R_IHIHALF) { /* now emit the second bit */ @@ -337,10 +407,9 @@ obj_header_append (where, headers) obj_coff_section_header_append (where, &text_section_header); obj_coff_section_header_append (where, &data_section_header); obj_coff_section_header_append (where, &bss_section_header); - } -#else +#else /* ! BFD_HEADERS */ void obj_header_append (where, headers) @@ -405,12 +474,16 @@ obj_header_append (where, headers) return; } /* obj_header_append() */ -#endif +#endif /* ! BFD_HEADERS */ + void obj_symbol_to_chars (where, symbolP) char **where; symbolS *symbolP; { + /* Move the value into the COFF symbol itself. */ + symbolP->sy_symbol.ost_entry.n_value = S_GET_VALUE (symbolP); + #ifdef BFD_HEADERS unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; unsigned int i; @@ -454,7 +527,8 @@ obj_symbol_to_chars (where, symbolP) append (where, (char *) syment, sizeof (*syment)); #endif /* CROSS_COMPILE */ - /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */ + /* Should do the following: + if (.file entry) MD(..)... else if (static entry) MD(..) */ if (numaux > OBJ_COFF_MAX_AUXENTRIES) { as_bad ("Internal error? too many auxents for symbol"); @@ -615,6 +689,8 @@ obj_emit_symbols (where, symbol_rootP) } } /* obj_emit_symbols() */ +#endif /* ! BFD_ASSEMBLER */ + /* Merge a debug symbol containing debug information into a normal symbol. */ void @@ -626,35 +702,70 @@ c_symbol_merge (debug, normal) S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug)); if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal)) - { - S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); - } /* take the most we have */ + /* take the most we have */ + S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); if (S_GET_NUMBER_AUXILIARY (debug) > 0) { - memcpy ((char *) &normal->sy_symbol.ost_auxent[0], (char *) &debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY (debug) * AUXESZ); - } /* Move all the auxiliary information */ + /* Move all the auxiliary information. */ +#ifdef BFD_ASSEMBLER + /* @@ How many fields do we want to preserve? Would it make more + sense to pick and choose those we want to copy? Should look + into this further.... [raeburn:19920512.2209EST] */ + alent *linenos; + linenos = coffsymbol (normal->bsym)->lineno; + memcpy ((char *) &coffsymbol (normal->bsym)->native, + (char *) &coffsymbol (debug->bsym)->native, + S_GET_NUMBER_AUXILIARY(debug) * AUXESZ); + coffsymbol (normal->bsym)->lineno = linenos; +#else + memcpy ((char *) &normal->sy_symbol.ost_auxent[0], + (char *) &debug->sy_symbol.ost_auxent[0], + S_GET_NUMBER_AUXILIARY (debug) * AUXESZ); +#endif + } /* Move the debug flags. */ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); } /* c_symbol_merge() */ -static symbolS *previous_file_symbol = NULL; - +static symbolS *previous_file_symbol; void c_dot_file_symbol (filename) char *filename; { symbolS *symbolP; +#ifdef BFD_ASSEMBLER + symbolP = symbol_new (filename, &bfd_abs_section, 0, + &zero_address_frag); +#else symbolP = symbol_new (".file", SEG_DEBUG, 0, &zero_address_frag); +#endif S_SET_STORAGE_CLASS (symbolP, C_FILE); S_SET_NUMBER_AUXILIARY (symbolP, 1); - SA_SET_FILE_FNAME (symbolP, filename); + +#ifdef BFD_ASSEMBLER + symbolP->bsym->flags = BSF_DEBUGGING; +#else + if (strlen(filename) > 14) + { + /* This won't fit into a 14 char space, it will go into the string + table. */ + symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes = 0; + (&(symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset))[0] = string_byte_count; + (&(symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1] = (int)filename; + } + else + { + SA_SET_FILE_FNAME (symbolP, filename); + } + SF_SET_DEBUG (symbolP); +#endif #ifndef NO_LISTING { @@ -666,7 +777,6 @@ c_dot_file_symbol (filename) } #endif - SF_SET_DEBUG (symbolP); S_SET_VALUE (symbolP, (long) previous_file_symbol); previous_file_symbol = symbolP; @@ -683,8 +793,7 @@ c_dot_file_symbol (filename) symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); symbol_rootP = symbolP; } /* if not first on the list */ - -} /* c_dot_file_symbol() */ +} /* * Build a 'section static' symbol. @@ -702,10 +811,10 @@ c_section_symbol (name, value, length, nreloc, nlnno) symbolP = symbol_new (name, (name[1] == 't' - ? SEG_TEXT - : (name[1] == 'd' - ? SEG_DATA - : SEG_BSS)), + ? text_section + : name[1] == 'd' + ? data_section + : bss_section), value, &zero_address_frag); @@ -767,26 +876,37 @@ c_section_header (header, header->s_flags = STYP_REG | (name[1] == 't' ? STYP_TEXT - : (name[1] == 'd' - ? STYP_DATA - : (name[1] == 'b' - ? STYP_BSS - : STYP_INFO))); - return; -} /* c_section_header() */ + : name[1] == 'd' + ? STYP_DATA + : name[1] == 'b' + ? STYP_BSS + : STYP_INFO); +} /* Line number handling */ -int function_lineoff = -1; /* Offset in line#s where the last function - started (the odd entry for line #0) */ -int text_lineno_number = 0; -int our_lineno_number = 0; /* we use this to build pointers from .bf's - into the linetable. It should match - exactly the values that are later - assigned in text_lineno_number by - write.c. */ -lineno *lineno_lastP = (lineno *) 0; +#ifdef BFD_ASSEMBLER + +/* Symbol of last function, which we should hang line#s off of. */ +symbolS *function_lineoff; + +#else + +/* Offset in line#s where the last function started (the odd entry for + line #0). */ +int function_lineoff = -1; + +int text_lineno_number; + +/* We use this to build pointers from .bf's into the linetable. It + should match exactly the values that are later assigned in + text_lineno_number by write.c. */ +int our_lineno_number; +lineno *lineno_lastP; +#endif + +#ifndef BFD_ASSEMBLER int c_line_new (paddr, line_number, frag) long paddr; @@ -807,13 +927,17 @@ c_line_new (paddr, line_number, frag) lineno_lastP = new_line; return LINESZ * our_lineno_number++; } +#endif void obj_emit_lineno (where, line, file_start) char **where; +#ifndef BFD_ASSEMBLER /* sigh */ lineno *line; +#endif char *file_start; { +#ifndef BFD_ASSEMBLER #ifdef BFD_HEADERS struct bfd_internal_lineno *line_entry; #else @@ -823,16 +947,15 @@ obj_emit_lineno (where, line, file_start) { line_entry = &line->line; - /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in - write_object_file() but their symbols need a fileptr to the lnno, so - I moved this resolution check here. xoxorich. */ + /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be + done in write_object_file() but their symbols need a fileptr to the + lnno, so I moved this resolution check here. xoxorich. */ if (line_entry->l_lnno == 0) { /* There is a good chance that the symbol pointed to - is not the one that will be emitted and that the - sy_number is not accurate. */ - /* char *name; */ + is not the one that will be emitted and that the + sy_number is not accurate. */ symbolS *symbolP; symbolP = (symbolS *) line_entry->l_addr.l_symndx; @@ -845,7 +968,7 @@ obj_emit_lineno (where, line, file_start) *where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where); #else /* No matter which member of the union we process, they are - both long. */ + both long. */ #ifdef CROSS_COMPILE md_number_to_chars (*where, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr)); *where += sizeof (line_entry->l_addr.l_paddr); @@ -865,9 +988,10 @@ obj_emit_lineno (where, line, file_start) #endif /* CROSS_COMPILE */ #endif /* BFD_HEADERS */ } /* for each line number */ - - return; -} /* obj_emit_lineno() */ +#else /* BFD_ASSEMBLER */ + abort (); +#endif /* BFD_ASSEMBLER */ +} void obj_symbol_new_hook (symbolP) @@ -875,35 +999,41 @@ obj_symbol_new_hook (symbolP) { char underscore = 0; /* Symbol has leading _ */ +#ifdef BFD_ASSEMBLER + { + long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type); + char *s = (char *) bfd_alloc_by_size_t (stdoutput, sz); + memset (s, 0, sz); + coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s; + } +#else /* Effective symbol */ /* Store the pointer in the offset. */ S_SET_ZEROES (symbolP, 0L); - S_SET_DATA_TYPE (symbolP, T_NULL); - S_SET_STORAGE_CLASS (symbolP, 0); - S_SET_NUMBER_AUXILIARY (symbolP, 0); /* Additional information */ symbolP->sy_symbol.ost_flags = 0; /* Auxiliary entries */ memset ((char *) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ); +#endif + S_SET_DATA_TYPE (symbolP, T_NULL); + S_SET_STORAGE_CLASS (symbolP, 0); + S_SET_NUMBER_AUXILIARY (symbolP, 0); #ifdef STRIP_UNDERSCORE /* Remove leading underscore at the beginning of the symbol. - * This is to be compatible with the standard librairies. - */ + This is to be compatible with the standard librairies. */ if (*S_GET_NAME (symbolP) == '_') { underscore = 1; S_SET_NAME (symbolP, S_GET_NAME (symbolP) + 1); - } /* strip underscore */ + } #endif /* STRIP_UNDERSCORE */ if (S_IS_STRING (symbolP)) SF_SET_STRING (symbolP); if (!underscore && S_IS_LOCAL (symbolP)) SF_SET_LOCAL (symbolP); - - return; -} /* obj_symbol_new_hook() */ +} /* stack stuff */ stack * @@ -913,19 +1043,21 @@ stack_init (chunk_size, element_size) { stack *st; - if ((st = (stack *) malloc (sizeof (stack))) == (stack *) 0) - return (stack *) 0; - if ((st->data = malloc (chunk_size)) == (char *) 0) + st = (stack *) malloc (sizeof (stack)); + if (!st) + return 0; + st->data = malloc (chunk_size); + if (!st->data) { free (st); - return (stack *) 0; + return 0; } st->pointer = 0; st->size = chunk_size; st->chunk_size = chunk_size; st->element_size = element_size; return st; -} /* stack_init() */ +} void stack_delete (st) @@ -975,20 +1107,62 @@ stack_top (st) * Handle .ln directives. */ +#ifdef BFD_ASSEMBLER +static symbolS *current_lineno_sym; +static struct line_no *line_nos; + +static void +add_lineno (frag, offset, num) + fragS *frag; + int offset; + int num; +{ + struct line_no *new_line = (struct line_no *) bfd_alloc_by_size_t (stdoutput, + sizeof (struct line_no)); + if (!current_lineno_sym) + { + abort (); + } + new_line->next = line_nos; + new_line->frag = frag; + new_line->l.line_number = num; + new_line->l.u.offset = offset; + line_nos = new_line; +} + +static void +add_linesym (sym) + symbolS *sym; +{ + if (line_nos) + { + add_lineno (0, 0, 0); + coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos; + line_nos = 0; + } + current_lineno_sym = sym; +} +#endif + static void -obj_coff_ln () +obj_coff_ln (appline) + int appline; { int l; - if (def_symbol_in_progress != NULL) + + if (! appline && def_symbol_in_progress != NULL) { as_warn (".ln pseudo-op inside .def/.endef: ignored."); demand_empty_rest_of_line (); return; - } /* wrong context */ + } - c_line_new (obstack_next_free (&frags) - frag_now->fr_literal, - l = get_absolute_expression (), - frag_now); + l = get_absolute_expression (); +#ifdef BFD_ASSEMBLER + add_lineno (frag_now, frag_now_fix (), l); +#else + c_line_new (frag_now_fix (), l, frag_now); +#endif #ifndef NO_LISTING { @@ -996,13 +1170,14 @@ obj_coff_ln () if (listing) { - listing_source_line (l + line_base - 1); + if (! appline) + l += line_base - 1; + listing_source_line (l); } } #endif demand_empty_rest_of_line (); - return; } /* obj_coff_ln() */ /* @@ -1032,9 +1207,6 @@ obj_coff_def (what) char *symbol_name; /* Name of the debug symbol */ char *symbol_name_copy; /* Temporary copy of the name */ unsigned int symbol_name_length; - /*$char* directiveP;$ *//* Name of the pseudo opcode */ - /*$char directive[MAX_DIRECTIVE];$ *//* Backup of the directive */ - /*$char end = 0;$ *//* If 1, stop parsing */ if (def_symbol_in_progress != NULL) { @@ -1045,38 +1217,38 @@ obj_coff_def (what) SKIP_WHITESPACES (); - def_symbol_in_progress = (symbolS *) obstack_alloc (¬es, sizeof (*def_symbol_in_progress)); - memset (def_symbol_in_progress, '\0', sizeof (*def_symbol_in_progress)); - symbol_name = input_line_pointer; +#ifdef STRIP_UNDERSCORE + if (symbol_name[0] == '_' && symbol_name[1] != 0) + symbol_name++; +#endif /* STRIP_UNDERSCORE */ + name_end = get_symbol_end (); symbol_name_length = strlen (symbol_name); symbol_name_copy = xmalloc (symbol_name_length + 1); strcpy (symbol_name_copy, symbol_name); /* Initialize the new symbol */ -#ifdef STRIP_UNDERSCORE - S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_' - ? symbol_name_copy + 1 - : symbol_name_copy)); -#else /* STRIP_UNDERSCORE */ +#ifdef BFD_ASSEMBLER + def_symbol_in_progress = symbol_make (symbol_name_copy); +#else + def_symbol_in_progress = (symbolS *) obstack_alloc (¬es, sizeof (*def_symbol_in_progress)); + memset (def_symbol_in_progress, '\0', sizeof (*def_symbol_in_progress)); + S_SET_NAME (def_symbol_in_progress, symbol_name_copy); -#endif /* STRIP_UNDERSCORE */ - /* free(symbol_name_copy); */ def_symbol_in_progress->sy_name_offset = ~0; def_symbol_in_progress->sy_number = ~0; +#endif + def_symbol_in_progress->sy_frag = &zero_address_frag; if (S_IS_STRING (def_symbol_in_progress)) - { - SF_SET_STRING (def_symbol_in_progress); - } /* "long" name */ + SF_SET_STRING (def_symbol_in_progress); *input_line_pointer = name_end; demand_empty_rest_of_line (); - return; -} /* obj_coff_def() */ +} unsigned int dim_index; static void @@ -1103,7 +1275,11 @@ obj_coff_endef () case C_FILE: case C_TPDEF: SF_SET_DEBUG (def_symbol_in_progress); +#ifdef BFD_ASSEMBLER + S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ()); +#else S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG); +#endif break; case C_EFCN: @@ -1113,20 +1289,33 @@ obj_coff_endef () SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */ /* intentional fallthrough */ case C_FCN: - S_SET_SEGMENT (def_symbol_in_progress, SEG_TEXT); + { + CONST char *name; + S_SET_SEGMENT (def_symbol_in_progress, text_section); - if (def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][1] == 'b' - && def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][2] == 'f') - { - if (function_lineoff < 0) - { - as_warn ("`.bf' symbol without preceding function"); - } - SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff; - /* Will need relocating */ - SF_SET_PROCESS (def_symbol_in_progress); - function_lineoff = -1; - } +#ifdef BFD_ASSEMBLER + name = bfd_asymbol_name (def_symbol_in_progress->bsym); +#else + name = def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1]; +#endif + if (name[1] == 'b' && name[2] == 'f') + { + if (function_lineoff < 0) + as_warn ("`%s' symbol without preceding function", name); +#ifdef BFD_ASSEMBLER + abort (); +#else + SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff; +#endif + /* Will need relocating */ + SF_SET_PROCESS (def_symbol_in_progress); +#ifdef BFD_ASSEMBLER + function_lineoff = 0; +#else + function_lineoff = -1; +#endif + } + } break; #ifdef C_AUTOARG @@ -1142,7 +1331,7 @@ obj_coff_endef () case C_FIELD: case C_EOS: SF_SET_DEBUG (def_symbol_in_progress); - S_SET_SEGMENT (def_symbol_in_progress, SEG_ABSOLUTE); + S_SET_SEGMENT (def_symbol_in_progress, absolute_section); break; case C_EXT: @@ -1154,52 +1343,59 @@ obj_coff_endef () case C_USTATIC: case C_EXTDEF: case C_ULABEL: - as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress)); + as_warn ("unexpected storage class %d", + S_GET_STORAGE_CLASS (def_symbol_in_progress)); break; } /* switch on storage class */ - /* Now that we have built a debug symbol, try to - find if we should merge with an existing symbol - or not. If a symbol is C_EFCN or SEG_ABSOLUTE or - untagged SEG_DEBUG it never merges. */ - - /* Two cases for functions. Either debug followed - by definition or definition followed by debug. - For definition first, we will merge the debug - symbol into the definition. For debug first, the - lineno entry MUST point to the definition - function or else it will point off into space - when obj_crawl_symbol_chain() merges the debug - symbol into the real symbol. Therefor, let's - presume the debug symbol is a real function - reference. */ - - /* FIXME-SOON If for some reason the definition - label/symbol is never seen, this will probably - leave an undefined symbol at link time. */ + /* Now that we have built a debug symbol, try to find if we should + merge with an existing symbol or not. If a symbol is C_EFCN or + SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */ + + /* Two cases for functions. Either debug followed by definition or + definition followed by debug. For definition first, we will + merge the debug symbol into the definition. For debug first, the + lineno entry MUST point to the definition function or else it + will point off into space when obj_crawl_symbol_chain() merges + the debug symbol into the real symbol. Therefor, let's presume + the debug symbol is a real function reference. */ + + /* FIXME-SOON If for some reason the definition label/symbol is + never seen, this will probably leave an undefined symbol at link + time. */ if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN +#ifdef BFD_ASSEMBLER + || (!strcmp (bfd_get_section_name (stdoutput, + S_GET_SEGMENT (def_symbol_in_progress)), + "*DEBUG*") + && !SF_GET_TAG (def_symbol_in_progress)) +#else || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG && !SF_GET_TAG (def_symbol_in_progress)) - || S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE +#endif + || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL) { - - symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - +#ifdef BFD_ASSEMBLER + if (def_symbol_in_progress != symbol_lastP) + symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, + &symbol_lastP); +#else + symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, + &symbol_lastP); +#endif } else { - /* This symbol already exists, merge the - newly created symbol into the old one. - This is not mandatory. The linker can - handle duplicate symbols correctly. But I - guess that it save a *lot* of space if - the assembly file defines a lot of - symbols. [loic] */ + /* This symbol already exists, merge the newly created symbol + into the old one. This is not mandatory. The linker can + handle duplicate symbols correctly. But I guess that it save + a *lot* of space if the assembly file defines a lot of + symbols. [loic] */ - /* The debug entry (def_symbol_in_progress) - is merged into the previous definition. */ + /* The debug entry (def_symbol_in_progress) is merged into the + previous definition. */ c_symbol_merge (def_symbol_in_progress, symbolP); /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */ @@ -1208,33 +1404,40 @@ obj_coff_endef () if (SF_GET_FUNCTION (def_symbol_in_progress) || SF_GET_TAG (def_symbol_in_progress)) { - /* For functions, and tags, the symbol *must* be where the debug symbol - appears. Move the existing symbol to the current place. */ + /* For functions, and tags, the symbol *must* be where the + debug symbol appears. Move the existing symbol to the + current place. */ /* If it already is at the end of the symbol list, do nothing */ if (def_symbol_in_progress != symbol_lastP) { symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - } /* if not already in place */ - } /* if function */ - } /* normal or mergable */ + } + } + } if (SF_GET_TAG (def_symbol_in_progress) && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL) { tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress); - } /* If symbol is a {structure,union} tag, associate symbol to its name. */ + } if (SF_GET_FUNCTION (def_symbol_in_progress)) { know (sizeof (def_symbol_in_progress) <= sizeof (long)); - function_lineoff = c_line_new ((long) def_symbol_in_progress, 0, &zero_address_frag); +#ifdef BFD_ASSEMBLER + function_lineoff = def_symbol_in_progress; + add_linesym (def_symbol_in_progress); +#else + function_lineoff = c_line_new ((long) def_symbol_in_progress, 0, + &zero_address_frag); +#endif SF_SET_PROCESS (def_symbol_in_progress); if (symbolP == NULL) { - /* That is, if this is the first - time we've seen the function... */ + /* That is, if this is the first time we've seen the + function... */ symbol_table_insert (def_symbol_in_progress); } /* definition follows debug */ } /* Create the line number entry pointing to the function being defined */ @@ -1242,7 +1445,7 @@ obj_coff_endef () def_symbol_in_progress = NULL; demand_empty_rest_of_line (); return; -} /* obj_coff_endef() */ +} static void obj_coff_dim () @@ -1291,7 +1494,7 @@ obj_coff_line () if (def_symbol_in_progress == NULL) { - obj_coff_ln (); + obj_coff_ln (0); return; } /* if it looks like a stabs style line */ @@ -1359,7 +1562,8 @@ obj_coff_tag () /* Assume that the symbol referred to by .tag is always defined. */ /* This was a bad assumption. I've added find_or_make. xoxorich. */ - SA_SET_SYM_TAGNDX (def_symbol_in_progress, (long) tag_find_or_make (symbol_name)); + SA_SET_SYM_TAGNDX (def_symbol_in_progress, + (long) tag_find_or_make (symbol_name)); if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) { as_warn ("tag not found for .tag %s", symbol_name); @@ -1369,7 +1573,6 @@ obj_coff_tag () *input_line_pointer = name_end; demand_empty_rest_of_line (); - return; } /* obj_coff_tag() */ static void @@ -1449,7 +1652,7 @@ tag_init () static void tag_insert (name, symbolP) - char *name; + CONST char *name; symbolS *symbolP; { register char *error_string; @@ -1470,10 +1673,8 @@ tag_find_or_make (name) if ((symbolP = tag_find (name)) == NULL) { - symbolP = symbol_new (name, - SEG_UNKNOWN, - 0, - &zero_address_frag); + symbolP = symbol_new (name, undefined_section, + 0, &zero_address_frag); tag_insert (S_GET_NAME (symbolP), symbolP); symbol_table_insert (symbolP); @@ -1502,9 +1703,7 @@ obj_read_begin_hook () know (SYMESZ == AUXESZ); #endif tag_init (); - - return; -} /* obj_read_begin_hook() */ +} void obj_crawl_symbol_chain (headers) @@ -1749,6 +1948,15 @@ obj_crawl_symbol_chain (headers) } else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE) { + if (symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes == 0) + { + symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset = string_byte_count; + string_byte_count += + strlen(GET_FILENAME_STRING(symbolP)) + 1; + + + } + if (S_GET_VALUE (symbolP)) { S_SET_VALUE ((symbolS *) S_GET_VALUE (symbolP), symbol_number); @@ -1757,16 +1965,15 @@ obj_crawl_symbol_chain (headers) } /* if debug or tag or eos or file */ /* We must put the external symbols apart. The loader - does not bomb if we do not. But the references in - the endndx field for a .bb symbol are not corrected - if an external symbol is removed between .bb and .be. - I.e in the following case : - [20] .bb endndx = 22 - [21] foo external - [22] .be - ld will move the symbol 21 to the end of the list but - endndx will still be 22 instead of 21. */ - + does not bomb if we do not. But the references in + the endndx field for a .bb symbol are not corrected + if an external symbol is removed between .bb and .be. + I.e in the following case : + [20] .bb endndx = 22 + [21] foo external + [22] .be + ld will move the symbol 21 to the end of the list but + endndx will still be 22 instead of 21. */ if (SF_GET_LOCAL (symbolP)) { @@ -1777,11 +1984,14 @@ obj_crawl_symbol_chain (headers) } else if ( #ifdef TE_I386AIX - S_GET_STORAGE_CLASS (symbolP) == C_EXT && !SF_GET_FUNCTION (symbolP) + S_GET_STORAGE_CLASS (symbolP) == C_EXT + && !SF_GET_FUNCTION (symbolP) #else /* not TE_I386AIX */ - !S_IS_DEFINED (symbolP) && !S_IS_DEBUG (symbolP) && !SF_GET_STATICS (symbolP) + !S_IS_DEFINED (symbolP) + && !S_IS_DEBUG (symbolP) + && !SF_GET_STATICS (symbolP) #endif /* not TE_I386AIX */ - ) + ) { /* if external, Remove from the list */ symbolS *hold = symbol_previous (symbolP); @@ -1831,27 +2041,27 @@ obj_crawl_symbol_chain (headers) symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp); } /* append the entire extern chain */ - /* When a tag reference preceeds the tag definition, - the definition will not have a number at the time - we process the reference during the first - traversal. Thus, a second traversal. */ + /* When a tag reference preceeds the tag definition, the definition + will not have a number at the time we process the reference + during the first traversal. Thus, a second traversal. */ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) { if (SF_GET_TAGGED (symbolP)) { SA_SET_SYM_TAGNDX (symbolP, ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number); - } /* If the symbol has a tagndx entry, resolve it */ - } /* second traversal */ + } + } know (symbol_externP == NULL); know (symbol_extern_lastP == NULL); - /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section - headers, and I'm resolving the addresses since I'm not sure how to - do it later. I am NOT resolving the linno's representing functions. - Their symbols need a fileptr pointing to this linno when emitted. - Thus, I resolve them on emit. xoxorich. */ + /* FIXME-SOMEDAY I'm counting line no's here so we know what to put + in the section headers, and I'm resolving the addresses since I'm + not sure how to do it later. I am NOT resolving the linno's + representing functions. Their symbols need a fileptr pointing to + this linno when emitted. Thus, I resolve them on emit. + xoxorich. */ for (lineP = lineno_rootP; lineP; lineP = lineP->next) { @@ -1869,7 +2079,7 @@ obj_crawl_symbol_chain (headers) H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); return; -} /* obj_crawl_symbol_chain() */ +} /* * Find strings by crawling along symbol table chain. @@ -1891,14 +2101,23 @@ obj_emit_strings (where) for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) { + if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) + { + /* May need special treatment for this auxent */ + if (symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes == 0) + { + char *p = GET_FILENAME_STRING(symbolP); + append + (where,p, strlen(p)+1); + } + } if (SF_GET_STRING (symbolP)) { - append (where, S_GET_NAME (symbolP), (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); + append (where, S_GET_NAME (symbolP), + (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); } /* if it has a string */ } /* walk the symbol chain */ - - return; -} /* obj_emit_strings() */ +} void obj_pre_write_hook (headers) @@ -1908,9 +2127,8 @@ obj_pre_write_hook (headers) register int data_relocation_number = 0; register fixS *fixP; - /* FIXME-SOMEDAY this should be done at - fixup_segment time but I'm going to wait until I - do multiple segments. xoxorich. */ + /* FIXME-SOMEDAY this should be done at fixup_segment time but I'm + going to wait until I do multiple segments. xoxorich. */ /* Count the number of relocation entries for text and data */ for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) { @@ -2056,9 +2274,7 @@ obj_pre_write_hook (headers) 0, /* No relocation information */ 0, /* No line number information */ section_alignment[(int) SEG_BSS]); - - return; -} /* obj_pre_write_hook() */ +} /* This is a copy from aout. All I do is neglect to actually build the symbol. */ @@ -2143,9 +2359,182 @@ obj_coff_stab (what) } /* on error */ } /* obj_coff_stab() */ +#ifdef BFD_ASSEMBLER +static +unsigned long +align (val, exp) +{ + int n = (1 << exp) - 1; + printf ("align (%x, %x)\n", val, exp); + val = (val + n) & ~n; + return val; +} + +void +coff_check_file_symbols (symp, punt) + symbolS *symp; + int *punt; +{ + static symbolS *last_functionP, *last_tagP; + static stack *block_stack; + + if (!block_stack) + block_stack = stack_init (512, sizeof (symbolS*)); + +#if 1 + if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT) + S_SET_STORAGE_CLASS (symp, C_EXT); +#endif + + if (!SF_GET_DEBUG (symp)) + { + symbolS *real; + if (!SF_GET_LOCAL (symp) + && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP)) + && real != symp) + { + c_symbol_merge (symp, real); + *punt = 1; + } + if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp)) + { + assert (S_GET_VALUE (symp) == 0); + S_SET_EXTERNAL (symp); + } + else if (S_GET_STORAGE_CLASS (symp) == C_NULL) + { + if (S_GET_SEGMENT (symp) == text_section) + S_SET_STORAGE_CLASS (symp, C_LABEL); + else + S_SET_STORAGE_CLASS (symp, C_STAT); + } + if (SF_GET_PROCESS (symp)) + { + if (S_GET_STORAGE_CLASS (symp) == C_BLOCK) + { + if (!strcmp (S_GET_NAME (symp), ".bb")) + stack_push (block_stack, (char *) &symp); + else + { + symbolS *begin; + begin = *(symbolS **) stack_pop (block_stack); + if (begin == 0) + as_warn ("mismatched .eb"); + else + SA_SET_SYM_ENDNDX (begin, begin); + } + } + if (last_functionP == 0 && SF_GET_FUNCTION (symp)) + { + union internal_auxent *auxp; + last_functionP = symp; + if (S_GET_NUMBER_AUXILIARY (symp) < 1) + S_SET_NUMBER_AUXILIARY (symp, 1); + auxp = &coffsymbol (symp->bsym)->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)); + } + if (S_GET_STORAGE_CLASS (symp) == C_EFCN) + { + if (last_functionP == 0) + as_fatal ("C_EFCN symbol out of scope"); + SA_SET_SYM_FSIZE (last_functionP, + (long) (S_GET_VALUE (symp) + - S_GET_VALUE (last_functionP))); + SA_SET_SYM_ENDNDX (last_functionP, symp); + last_functionP = 0; + } + } + else if (SF_GET_TAG (symp)) + last_tagP = symp; + else if (S_GET_STORAGE_CLASS (symp) == C_EOS) + SA_SET_SYM_ENDNDX (last_tagP, symp); + else if (S_GET_STORAGE_CLASS (symp) == C_FILE) + { + if (S_GET_VALUE (symp)) + { + S_SET_VALUE ((symbolS *) S_GET_VALUE (symp), 0xdeadbeef); + S_SET_VALUE (symp, 0); + } + } + if (SF_GET_LOCAL (symp)) + *punt = 1; + /* more ... */ + } + if (coffsymbol (symp->bsym)->lineno) + { + int i, n; + struct line_no *lptr; + alent *l; + + lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; + for (i = 0; lptr; lptr = lptr->next) + i++; + n = i + 1; + lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; + l = (alent *) bfd_alloc_by_size_t (stdoutput, n * sizeof (alent)); + coffsymbol (symp->bsym)->lineno = l; + for (i = n - 1; i > 0; i--) + { + if (lptr->frag) + lptr->l.u.offset += lptr->frag->fr_address; + l[i] = lptr->l; + lptr = lptr->next; + } + } +} + +void +DEFUN_VOID(obj_coff_section) +{ + /* Strip out the section name */ + char *section_name ; + char *section_name_end; + char c; + + unsigned int len; + unsigned int exp; + + section_name = input_line_pointer; + c = get_symbol_end(); + section_name_end = input_line_pointer; + + len = section_name_end - section_name ; + input_line_pointer++; + SKIP_WHITESPACE(); + if (c == ',') + exp = get_absolute_expression(); + else if (*input_line_pointer == ',') + { + input_line_pointer++; + exp = get_absolute_expression(); + } + else + { + exp = 0; + } + + printf ("change_to_section(`%s',%d,%x)\n", section_name, len,exp); + *section_name_end = c; +} + +void +coff_frob_file () +{ + if (symbol_rootP == NULL + || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) + { + assert (previous_file_symbol == 0); + c_dot_file_symbol ("fake"); + } + if (current_lineno_sym) + add_linesym ((symbolS *) 0); +} +#endif /* BFD_ASSEMBLER */ + #ifdef DEBUG /* for debugging */ -char * +CONST char * s_get_name (s) symbolS *s; { @@ -2159,6 +2548,14 @@ symbol_dump () for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) { +#ifdef BFD_ASSEMBLER + printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n", + (unsigned long) symbolP, + S_GET_NAME(symbolP), + (long) S_GET_DATA_TYPE(symbolP), + S_GET_STORAGE_CLASS(symbolP), + (int) S_GET_SEGMENT(symbolP)); +#else printf ("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n", symbolP->sy_number, (unsigned long) symbolP, @@ -2166,19 +2563,10 @@ symbol_dump () (long) S_GET_DATA_TYPE (symbolP), S_GET_STORAGE_CLASS (symbolP), (int) S_GET_SEGMENT (symbolP)); - } /* traverse symbols */ - - return; -} /* symbol_dump() */ +#endif + } +} #endif /* DEBUG */ - -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ - /* end of obj-coff.c */ diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index d6838ab6f69..480527dfc4c 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -21,19 +21,23 @@ #include "targ-cpu.h" +#if defined (BFD_HEADERS) || defined (BFD_ASSEMBLER) +/* This internal_lineno crap is to stop namespace pollution from the + bfd internal coff headerfile. */ -#ifdef BFD_HEADERS -#ifdef TC_A29K #include "bfd.h" -#include "coff/a29k.h" - -/* This internal_lineno crap is to stop namespace pollution from the bfd internal - coff headerfile. */ - #define internal_lineno bfd_internal_lineno #include "coff/internal.h" #undef internal_lineno + +#ifdef BFD_ASSEMBLER +#include "../bfd/libcoff.h" +#endif + +#ifdef TC_A29K +#include "coff/a29k.h" + /* #undef RELOC #undef SYMENT @@ -57,17 +61,23 @@ extern bfd *stdoutput; #endif /* TC_A29K */ +#ifdef TC_I960 +#include "coff/i960.h" +#define TARGET_FORMAT "coff-i960-big" +#endif + #ifdef TC_I386 -# include "bfd.h" # include "coff/i386.h" -# define internal_lineno bfd_internal_lineno -# include "coff/internal.h" -# undef internal_lineno # define TARGET_FORMAT "coff-i386" extern bfd *stdoutput; #endif /* TC_I386 */ +#ifdef TC_M68K +# include "coff/m68k.h" +# define TARGET_FORMAT "coff-m68k" +#endif /* TC_M68K */ + #else /* not BFD_HEADERS */ #ifdef USE_NATIVE_HEADERS @@ -85,7 +95,9 @@ extern bfd *stdoutput; #endif /* not BFD_HEADERS */ -/* Define some processor dependent values according to the processor we are on. */ +#ifndef BFD_ASSEMBLER +/* Define some processor dependent values according to the processor + we are on. */ #ifdef TC_M68K #define BYTE_ORDERING F_AR32W /* See filehdr.h for more info. */ @@ -140,6 +152,9 @@ extern const segT N_TYPE_seg[]; #define AOUTHDRSZ sizeof(AOUTHDR) #endif +#endif /* not BFD_ASSEMBLER */ + + /* SYMBOL TABLE */ /* targets may also set this */ @@ -147,6 +162,22 @@ extern const segT N_TYPE_seg[]; #define SYMBOLS_NEED_BACKPOINTERS 1 #endif /* SYMBOLS_NEED_BACKPOINTERS */ +#ifdef BFD_ASSEMBLER + +#ifdef TC_I960 +#define I960_SYM_FIELDS struct symbol *bal; +#else +#define I960_SYM_FIELDS +#endif + +#define TARGET_SYMBOL_FIELDS unsigned long sy_flags; I960_SYM_FIELDS + +#ifndef OBJ_COFF_MAX_AUXENTRIES +#define OBJ_COFF_MAX_AUXENTRIES 1 +#endif + +#else + /* Symbol table entry data type */ typedef struct @@ -160,12 +191,20 @@ typedef struct #endif unsigned int ost_flags; /* obj_coff internal use only flags */ } - obj_symbol_type; +#endif /* ! BFD_ASSEMBLER */ + +#ifdef BFD_ASSEMBLER +#define SYM_AUXENT(S) (&coffsymbol ((S)->bsym)->native[1].u.auxent) +#else +#define SYM_AUXENT(S) (&(S)->sy_symbol.ost_auxent[0]) +#endif #define DO_NOT_STRIP 0 #define DO_STRIP 1 +#ifndef BFD_ASSEMBLER + /* Symbol table macros and constants */ /* Possible and usefull section number in symbol table @@ -196,7 +235,7 @@ obj_symbol_type; section == 0 and value > 0 (external bss symbol) */ #define S_IS_DEFINED(s) ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \ - (s)->sy_symbol.ost_entry.n_value > 0)) + S_GET_VALUE(s) > 0)) /* True if a debug special symbol entry */ #define S_IS_DEBUG(s) ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION) /* True if a symbol is local symbol name */ @@ -205,12 +244,14 @@ obj_symbol_type; (s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION || \ (S_LOCAL_NAME(s) && !flagseen['L'])) /* True if a symbol is not defined in this file */ -#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value == 0) +#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ + && S_GET_VALUE (s) == 0) /* * True if a symbol can be multiply defined (bss symbols have this def * though it is bad practice) */ -#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value != 0) +#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 + && S_GET_VALUE (s) != 0) /* 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) @@ -221,8 +262,6 @@ obj_symbol_type; #define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset) /* The zeroes if symbol name is longer than 8 chars */ #define S_GET_ZEROES(s) ((s)->sy_symbol.ost_entry.n_zeroes) -/* The value of the symbol */ -#define S_GET_VALUE(s) ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) /* The numeric value of the segment */ #define S_GET_SEGMENT(s) (N_TYPE_seg[(s)->sy_symbol.ost_entry.n_scnum+4]) /* The data type */ @@ -239,8 +278,6 @@ obj_symbol_type; #define S_SET_OFFSET(s,v) ((s)->sy_symbol.ost_entry.n_offset = (v)) /* The zeroes if symbol name is longer than 8 chars */ #define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v)) -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.ost_entry.n_value = (v)) /* The numeric value of the segment */ #define S_SET_SEGMENT(s,v) ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v)) /* The data type */ @@ -254,49 +291,71 @@ obj_symbol_type; /* The symbol is external (does not mean undefined) */ #define S_SET_EXTERNAL(s) { S_SET_STORAGE_CLASS(s, C_EXT) ; SF_CLEAR_LOCAL(s); } +#else /* BFD_ASSEMBLER */ + +/* The data type */ +#define S_GET_DATA_TYPE(s) (coffsymbol ((s)->bsym)->native->u.syment.n_type) +/* The storage class */ +#define S_GET_STORAGE_CLASS(s) (coffsymbol((s)->bsym)->native->u.syment.n_sclass) +/* The number of auxiliary entries */ +#define S_GET_NUMBER_AUXILIARY(s) (coffsymbol((s)->bsym)->native->u.syment.n_numaux) +/* The data type */ +#define S_SET_DATA_TYPE(s,v) (S_GET_DATA_TYPE (s) = (v)) +/* The storage class */ +#define S_SET_STORAGE_CLASS(s,v) (S_GET_STORAGE_CLASS (s) = (v)) +/* 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) + + +#endif /* ! BFD_ASSEMBLER */ + /* Auxiliary entry macros. SA_ stands for symbol auxiliary */ /* Omit the tv related fields */ /* Accessors */ + #ifdef BFD_HEADERS -#define SA_GET_SYM_TAGNDX(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx.l) +#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx.l) #else -#define SA_GET_SYM_TAGNDX(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx) +#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx) #endif -#define SA_GET_SYM_LNNO(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_lnno) -#define SA_GET_SYM_SIZE(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_size) -#define SA_GET_SYM_FSIZE(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_fsize) -#define SA_GET_SYM_LNNOPTR(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr) +#define SA_GET_SYM_LNNO(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno) +#define SA_GET_SYM_SIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size) +#define SA_GET_SYM_FSIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize) +#define SA_GET_SYM_LNNOPTR(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr) #ifdef BFD_HEADERS -#define SA_GET_SYM_ENDNDX(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx.l) +#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx.l) #else -#define SA_GET_SYM_ENDNDX(s) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx) +#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx) #endif -#define SA_GET_SYM_DIMEN(s,i) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen[(i)]) -#define SA_GET_FILE_FNAME(s) ((s)->sy_symbol.ost_auxent[0].x_file.x_fname) -#define SA_GET_SCN_SCNLEN(s) ((s)->sy_symbol.ost_auxent[0].x_scn.x_scnlen) -#define SA_GET_SCN_NRELOC(s) ((s)->sy_symbol.ost_auxent[0].x_scn.x_nreloc) -#define SA_GET_SCN_NLINNO(s) ((s)->sy_symbol.ost_auxent[0].x_scn.x_nlinno) +#define SA_GET_SYM_DIMEN(s,i) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]) +#define SA_GET_FILE_FNAME(s) (SYM_AUXENT (s)->x_file.x_fname) +#define SA_GET_SCN_SCNLEN(s) (SYM_AUXENT (s)->x_scn.x_scnlen) +#define SA_GET_SCN_NRELOC(s) (SYM_AUXENT (s)->x_scn.x_nreloc) +#define SA_GET_SCN_NLINNO(s) (SYM_AUXENT (s)->x_scn.x_nlinno) /* Modifiers */ +#ifndef BFD_ASSEMBLER #ifdef BFD_HEADERS -#define SA_SET_SYM_TAGNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx.l=(v)) +#define SA_SET_SYM_TAGNDX(s,v) (SYM_AUXENT (s)->x_sym.x_tagndx.l=(v)) +#define SA_SET_SYM_ENDNDX(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx.l=(v)) #else -#define SA_SET_SYM_TAGNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_tagndx=(v)) +#define SA_SET_SYM_ENDNDX(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx=(v)) +#define SA_SET_SYM_TAGNDX(s,v) (SYM_AUXENT (s)->x_sym.x_tagndx=(v)) #endif -#define SA_SET_SYM_LNNO(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_lnno=(v)) -#define SA_SET_SYM_SIZE(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_lnsz.x_size=(v)) -#define SA_SET_SYM_FSIZE(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_misc.x_fsize=(v)) -#define SA_SET_SYM_LNNOPTR(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr=(v)) -#ifdef BFD_HEADERS -#define SA_SET_SYM_ENDNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx.l=(v)) -#else -#define SA_SET_SYM_ENDNDX(s,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_endndx=(v)) #endif -#define SA_SET_SYM_DIMEN(s,i,v) ((s)->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v)) -#define SA_SET_FILE_FNAME(s,v) strncpy((s)->sy_symbol.ost_auxent[0].x_file.x_fname,(v),FILNMLEN) -#define SA_SET_SCN_SCNLEN(s,v) ((s)->sy_symbol.ost_auxent[0].x_scn.x_scnlen=(v)) -#define SA_SET_SCN_NRELOC(s,v) ((s)->sy_symbol.ost_auxent[0].x_scn.x_nreloc=(v)) -#define SA_SET_SCN_NLINNO(s,v) ((s)->sy_symbol.ost_auxent[0].x_scn.x_nlinno=(v)) + +#define SA_SET_SYM_LNNO(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno=(v)) +#define SA_SET_SYM_SIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size=(v)) +#define SA_SET_SYM_FSIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize=(v)) +#define SA_SET_SYM_LNNOPTR(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr=(v)) +#define SA_SET_SYM_DIMEN(s,i,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v)) +#define SA_SET_FILE_FNAME(s,v) strncpy(SYM_AUXENT (s)->x_file.x_fname,(v),FILNMLEN) +#define SA_SET_SCN_SCNLEN(s,v) (SYM_AUXENT (s)->x_scn.x_scnlen=(v)) +#define SA_SET_SCN_NRELOC(s,v) (SYM_AUXENT (s)->x_scn.x_nreloc=(v)) +#define SA_SET_SCN_NLINNO(s,v) (SYM_AUXENT (s)->x_scn.x_nlinno=(v)) /* * Internal use only definitions. SF_ stands for symbol flags. @@ -332,50 +391,57 @@ obj_symbol_type; /* All other bits are unused. */ /* Accessors */ +#ifdef BFD_ASSEMBLER +#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) +#else #define SF_GET(s) ((s)->sy_symbol.ost_flags) -#define SF_GET_NORMAL_FIELD(s) ((s)->sy_symbol.ost_flags & SF_NORMAL_MASK) -#define SF_GET_DEBUG_FIELD(s) ((s)->sy_symbol.ost_flags & SF_DEBUG_MASK) -#define SF_GET_FILE(s) ((s)->sy_symbol.ost_flags & SF_FILE) -#define SF_GET_STATICS(s) ((s)->sy_symbol.ost_flags & SF_STATICS) -#define SF_GET_DEFINED(s) ((s)->sy_symbol.ost_flags & SF_DEFINED) -#define SF_GET_STRING(s) ((s)->sy_symbol.ost_flags & SF_STRING) -#define SF_GET_LOCAL(s) ((s)->sy_symbol.ost_flags & SF_LOCAL) -#define SF_GET_FUNCTION(s) ((s)->sy_symbol.ost_flags & SF_FUNCTION) -#define SF_GET_PROCESS(s) ((s)->sy_symbol.ost_flags & SF_PROCESS) #define SF_GET_DEBUG(s) ((s)->sy_symbol.ost_flags & SF_DEBUG) -#define SF_GET_TAGGED(s) ((s)->sy_symbol.ost_flags & SF_TAGGED) -#define SF_GET_TAG(s) ((s)->sy_symbol.ost_flags & SF_TAG) -#define SF_GET_GET_SEGMENT(s) ((s)->sy_symbol.ost_flags & SF_GET_SEGMENT) -#define SF_GET_I960(s) ((s)->sy_symbol.ost_flags & SF_I960_MASK) /* used by i960 */ -#define SF_GET_BALNAME(s) ((s)->sy_symbol.ost_flags & SF_BALNAME) /* used by i960 */ -#define SF_GET_CALLNAME(s) ((s)->sy_symbol.ost_flags & SF_CALLNAME) /* used by i960 */ -#define SF_GET_IS_SYSPROC(s) ((s)->sy_symbol.ost_flags & SF_IS_SYSPROC) /* used by i960 */ -#define SF_GET_SYSPROC(s) ((s)->sy_symbol.ost_flags & SF_SYSPROC) /* used by i960 */ +#define SF_SET_DEBUG(s) ((s)->sy_symbol.ost_flags |= SF_DEBUG) +#endif +#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) +#define SF_GET_STATICS(s) (SF_GET (s) & SF_STATICS) +#define SF_GET_DEFINED(s) (SF_GET (s) & SF_DEFINED) +#define SF_GET_STRING(s) (SF_GET (s) & SF_STRING) +#define SF_GET_LOCAL(s) (SF_GET (s) & SF_LOCAL) +#define SF_GET_FUNCTION(s) (SF_GET (s) & SF_FUNCTION) +#define SF_GET_PROCESS(s) (SF_GET (s) & SF_PROCESS) +#define SF_GET_TAGGED(s) (SF_GET (s) & SF_TAGGED) +#define SF_GET_TAG(s) (SF_GET (s) & SF_TAG) +#define SF_GET_GET_SEGMENT(s) (SF_GET (s) & SF_GET_SEGMENT) +#define SF_GET_I960(s) (SF_GET (s) & SF_I960_MASK) /* used by i960 */ +#define SF_GET_BALNAME(s) (SF_GET (s) & SF_BALNAME) /* used by i960 */ +#define SF_GET_CALLNAME(s) (SF_GET (s) & SF_CALLNAME) /* used by i960 */ +#define SF_GET_IS_SYSPROC(s) (SF_GET (s) & SF_IS_SYSPROC) /* used by i960 */ +#define SF_GET_SYSPROC(s) (SF_GET (s) & SF_SYSPROC) /* used by i960 */ /* Modifiers */ -#define SF_SET(s,v) ((s)->sy_symbol.ost_flags = (v)) -#define SF_SET_NORMAL_FIELD(s,v)((s)->sy_symbol.ost_flags |= ((v) & SF_NORMAL_MASK)) -#define SF_SET_DEBUG_FIELD(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_DEBUG_MASK)) -#define SF_SET_FILE(s) ((s)->sy_symbol.ost_flags |= SF_FILE) -#define SF_SET_STATICS(s) ((s)->sy_symbol.ost_flags |= SF_STATICS) -#define SF_SET_DEFINED(s) ((s)->sy_symbol.ost_flags |= SF_DEFINED) -#define SF_SET_STRING(s) ((s)->sy_symbol.ost_flags |= SF_STRING) -#define SF_SET_LOCAL(s) ((s)->sy_symbol.ost_flags |= SF_LOCAL) -#define SF_CLEAR_LOCAL(s) ((s)->sy_symbol.ost_flags &= ~SF_LOCAL) -#define SF_SET_FUNCTION(s) ((s)->sy_symbol.ost_flags |= SF_FUNCTION) -#define SF_SET_PROCESS(s) ((s)->sy_symbol.ost_flags |= SF_PROCESS) -#define SF_SET_DEBUG(s) ((s)->sy_symbol.ost_flags |= SF_DEBUG) -#define SF_SET_TAGGED(s) ((s)->sy_symbol.ost_flags |= SF_TAGGED) -#define SF_SET_TAG(s) ((s)->sy_symbol.ost_flags |= SF_TAG) -#define SF_SET_GET_SEGMENT(s) ((s)->sy_symbol.ost_flags |= SF_GET_SEGMENT) -#define SF_SET_I960(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_I960_MASK)) /* used by i960 */ -#define SF_SET_BALNAME(s) ((s)->sy_symbol.ost_flags |= SF_BALNAME) /* used by i960 */ -#define SF_SET_CALLNAME(s) ((s)->sy_symbol.ost_flags |= SF_CALLNAME) /* used by i960 */ -#define SF_SET_IS_SYSPROC(s) ((s)->sy_symbol.ost_flags |= SF_IS_SYSPROC) /* used by i960 */ -#define SF_SET_SYSPROC(s,v) ((s)->sy_symbol.ost_flags |= ((v) & SF_SYSPROC)) /* used by i960 */ +#define SF_SET(s,v) (SF_GET (s) = (v)) +#define SF_SET_NORMAL_FIELD(s,v)(SF_GET (s) |= ((v) & SF_NORMAL_MASK)) +#define SF_SET_DEBUG_FIELD(s,v) (SF_GET (s) |= ((v) & SF_DEBUG_MASK)) +#define SF_SET_FILE(s) (SF_GET (s) |= SF_FILE) +#define SF_SET_STATICS(s) (SF_GET (s) |= SF_STATICS) +#define SF_SET_DEFINED(s) (SF_GET (s) |= SF_DEFINED) +#define SF_SET_STRING(s) (SF_GET (s) |= SF_STRING) +#define SF_SET_LOCAL(s) (SF_GET (s) |= SF_LOCAL) +#define SF_CLEAR_LOCAL(s) (SF_GET (s) &= ~SF_LOCAL) +#define SF_SET_FUNCTION(s) (SF_GET (s) |= SF_FUNCTION) +#define SF_SET_PROCESS(s) (SF_GET (s) |= SF_PROCESS) +#define SF_SET_TAGGED(s) (SF_GET (s) |= SF_TAGGED) +#define SF_SET_TAG(s) (SF_GET (s) |= SF_TAG) +#define SF_SET_GET_SEGMENT(s) (SF_GET (s) |= SF_GET_SEGMENT) +#define SF_SET_I960(s,v) (SF_GET (s) |= ((v) & SF_I960_MASK)) /* used by i960 */ +#define SF_SET_BALNAME(s) (SF_GET (s) |= SF_BALNAME) /* used by i960 */ +#define SF_SET_CALLNAME(s) (SF_GET (s) |= SF_CALLNAME) /* used by i960 */ +#define SF_SET_IS_SYSPROC(s) (SF_GET (s) |= SF_IS_SYSPROC) /* used by i960 */ +#define SF_SET_SYSPROC(s,v) (SF_GET (s) |= ((v) & SF_SYSPROC)) /* used by i960 */ /* File header macro and type definition */ +#ifndef BFD_ASSEMBLER /* * File position calculators. Beware to use them when all the * appropriate fields are set in the header. @@ -477,7 +543,6 @@ obj_symbol_type; #define H_SET_LINENO_SIZE(h,v) ((h)->lineno_size = (v)) /* Segment flipping */ -#define segment_name(v) (seg_name[(int) (v)]) typedef struct { @@ -497,10 +562,12 @@ typedef struct } object_headers; +#endif /* ! BFD_ASSEMBLER */ /* -------------- Line number handling ------- */ extern int text_lineno_number; +#ifndef BFD_ASSEMBLER /* line numbering stuff. */ typedef struct internal_lineno @@ -518,11 +585,9 @@ extern lineno *lineno_lastP; extern lineno *lineno_rootP; #define OBJ_EMIT_LINENO(a, b, c) obj_emit_lineno((a),(b),(c)) -#if __STDC__ == 1 -void obj_emit_lineno (char **where, lineno * line, char *file_start); -#else /* not __STDC__ */ -void obj_emit_lineno (); -#endif /* not __STDC__ */ +#endif /* not BFD_ASSEMBLER */ + +void obj_emit_lineno PARAMS ((char **where, lineno * line, char *file_start)); /* stack stuff */ typedef struct @@ -536,58 +601,37 @@ typedef struct stack; -#if __STDC__ == 1 - -char *stack_pop (stack * st); -char *stack_push (stack * st, char *element); -char *stack_top (stack * st); -stack *stack_init (unsigned long chunk_size, unsigned long element_size); -void c_dot_file_symbol (char *filename); -void obj_extra_stuff (object_headers * headers); -void stack_delete (stack * st); +char *stack_pop PARAMS ((stack * st)); +char *stack_push PARAMS ((stack * st, char *element)); +char *stack_top PARAMS ((stack * st)); +stack *stack_init PARAMS ((unsigned long chunk_size, + unsigned long element_size)); +void c_dot_file_symbol PARAMS ((char *filename)); +void obj_extra_stuff PARAMS ((object_headers * headers)); +void stack_delete PARAMS ((stack * st)); #ifndef tc_headers_hook -void tc_headers_hook (object_headers * headers); -#endif /* tc_headers_hook */ +void tc_headers_hook PARAMS ((object_headers * headers)); +#endif #ifndef tc_coff_symbol_emit_hook -void tc_coff_symbol_emit_hook (); /* really tc_coff_symbol_emit_hook(symbolS *symbolP) */ -#endif /* tc_coff_symbol_emit_hook */ +void tc_coff_symbol_emit_hook PARAMS ((/* symbolS * */)); +#endif + +#define obj_check_file_symbols coff_check_file_symbols -void c_section_header ( +#ifndef BFD_ASEMBLER +void c_section_header PARAMS (( #ifdef BFD_HEADERS - struct internal_scnhdr *header, + struct internal_scnhdr *header, #else - SCNHDR * header, + SCNHDR * header, #endif - - char *name, - long core_address, - long size, - long data_ptr, - long reloc_ptr, - long lineno_ptr, - long reloc_number, - long lineno_number, - long alignment); - -#else /* not __STDC__ */ - -char *stack_pop (); -char *stack_push (); -char *stack_top (); -stack *stack_init (); -void c_dot_file_symbol (); -void c_section_header (); -void obj_extra_stuff (); -void stack_delete (); -#ifndef tc_headers_hook -void tc_headers_hook (); + char *name, long core_address, long size, + long data_ptr, long reloc_ptr, long lineno_ptr, + long reloc_number, long lineno_number, + long alignment)); #endif -void tc_coff_symbol_emit_hook (); - -#endif /* not __STDC__ */ - /* sanity check */ @@ -596,6 +640,7 @@ void tc_coff_symbol_emit_hook (); hey ! Where is the C_LEAFSTAT definition ? i960 - coff support is depending on it. #endif /* no C_LEAFSTAT */ #endif /* TC_I960 */ +#ifndef BFD_ASSEMBLER #ifdef BFD_HEADERS extern struct internal_scnhdr data_section_header; extern struct internal_scnhdr text_section_header; @@ -603,12 +648,6 @@ extern struct internal_scnhdr text_section_header; extern SCNHDR data_section_header; extern SCNHDR text_section_header; #endif - -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ +#endif /* end of obj-coff.h */ diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index 195b9dfb4d6..d2884d37690 100644 --- a/gas/config/obj-coffbfd.c +++ b/gas/config/obj-coffbfd.c @@ -641,6 +641,7 @@ DEFUN (symbol_to_chars, (abfd, where, symbolP), { unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; unsigned int i; + valueT val; /* Turn any symbols with register attributes into abs symbols */ if (S_GET_SEGMENT (symbolP) == SEG_REGISTER) @@ -649,9 +650,12 @@ DEFUN (symbol_to_chars, (abfd, where, symbolP), } /* At the same time, relocate all symbols to their output value */ - S_SET_VALUE (symbolP, - segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr - + S_GET_VALUE (symbolP)); + val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr + + S_GET_VALUE (symbolP)); + + S_SET_VALUE (symbolP, val); + + symbolP->sy_symbol.ost_entry.n_value = val; where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry, where); diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h index 7cde04d27ca..98233400519 100644 --- a/gas/config/obj-coffbfd.h +++ b/gas/config/obj-coffbfd.h @@ -152,7 +152,7 @@ obj_symbol_type; section == 0 and value > 0 (external bss symbol) */ #define S_IS_DEFINED(s) ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \ - (s)->sy_symbol.ost_entry.n_value > 0)) + S_GET_VALUE (s) > 0)) /* True if a debug special symbol entry */ #define S_IS_DEBUG(s) ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION) /* True if a symbol is local symbol name */ @@ -161,12 +161,14 @@ obj_symbol_type; (s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION || \ (S_LOCAL_NAME(s) && !flagseen['L'])) /* True if a symbol is not defined in this file */ -#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value == 0) +#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ + && S_GET_VALUE (s) == 0) /* * True if a symbol can be multiply defined (bss symbols have this def * though it is bad practice) */ -#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value != 0) +#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ + && S_GET_VALUE (s) != 0) /* 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) @@ -177,8 +179,6 @@ obj_symbol_type; #define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset) /* The zeroes if symbol name is longer than 8 chars */ #define S_GET_ZEROES(s) ((s)->sy_symbol.ost_entry.n_zeroes) -/* The value of the symbol */ -#define S_GET_VALUE(s) ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) /* The numeric value of the segment */ #define S_GET_SEGMENT(s) s_get_segment(s) /* The data type */ @@ -195,8 +195,6 @@ obj_symbol_type; #define S_SET_OFFSET(s,v) ((s)->sy_symbol.ost_entry.n_offset = (v)) /* The zeroes if symbol name is longer than 8 chars */ #define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v)) -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.ost_entry.n_value = (v)) /* The numeric value of the segment */ #define S_SET_SEGMENT(s,v) ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v)) /* The data type */ diff --git a/gas/config/obj-generic.h b/gas/config/obj-generic.h index 6c89aef4567..ff46957f884 100644 --- a/gas/config/obj-generic.h +++ b/gas/config/obj-generic.h @@ -58,9 +58,6 @@ typedef void *object_headers; /* symbols have segments */ #define S_GET_SEGMENT(s) (SEG_UNKNOWN) #define S_SET_SEGMENT(s,v) ; -/* symbols have a value */ -#define S_GET_VALUE(s) (0) -#define S_SET_VALUE(s,v) ; /* symbols may be external */ #define S_IS_EXTERNAL(s) (0) #define S_SET_EXTERNAL(s) ; diff --git a/gas/config/obj-ieee.c b/gas/config/obj-ieee.c index e4a39a62d7f..61fff02adf4 100644 --- a/gas/config/obj-ieee.c +++ b/gas/config/obj-ieee.c @@ -217,7 +217,13 @@ DEFUN (do_relocs_for, (idx), if ((s->flags & BSF_UNDEFINED) == 0) { to->section = s->section; + + /* We can refer directly to the value field here, + rather than using S_GET_VALUE, because this is + only called after do_symbols, which sets up the + value field. */ to->addend += s->value; + to->sym_ptr_ptr = 0; if (to->howto->pcrel_offset) { @@ -276,7 +282,7 @@ DEFUN (do_symbols, (abfd), { ptr->sy_symbol.sy.section = (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff); - ptr->sy_symbol.sy.value += ptr->sy_frag->fr_address; + S_SET_VALUE (ptr, S_GET_VALUE (ptr) + ptr->sy_frag->fr_address); if (ptr->sy_symbol.sy.flags == 0) { ptr->sy_symbol.sy.flags = BSF_LOCAL; @@ -298,6 +304,7 @@ DEFUN (do_symbols, (abfd), abort (); } } + ptr->sy_symbol.sy.value = S_GET_VALUE (ptr); count++; } symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *)); @@ -339,14 +346,6 @@ DEFUN_VOID (bfd_as_write_hook) } - - -S_GET_VALUE (x) - symbolS *x; -{ - return x->sy_symbol.sy.value; -} - S_SET_SEGMENT (x, y) symbolS *x; int y; @@ -399,13 +398,6 @@ S_SET_NAME (x, y) x->sy_symbol.sy.name = y; } -S_SET_VALUE (s, v) - symbolS *s; - long v; -{ - s->sy_symbol.sy.value = v; -} - S_GET_OTHER (x) { abort (); diff --git a/gas/config/obj-vms.c b/gas/config/obj-vms.c index 94ef4299108..4e4ab8048a4 100644 --- a/gas/config/obj-vms.c +++ b/gas/config/obj-vms.c @@ -565,7 +565,8 @@ obj_crawl_symbol_chain (headers) symbolPP = &symbol_rootP; /* -> last symbol chain link. */ while ((symbolP = *symbolPP) != NULL) { - S_GET_VALUE (symbolP) += symbolP->sy_frag->fr_address; + S_SET_VALUE (symbolP, + S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address); /* OK, here is how we decide which symbols go out into the brave new symtab. Symbols that do are: @@ -4528,7 +4529,8 @@ VMS_Check_For_Main () * inserted. */ if (S_GET_VALUE (symbolP) >= 2) - S_GET_VALUE (symbolP) += 6; + S_SET_VALUE (symbolP, + S_GET_VALUE (symbolP) + 6); } } /* @@ -4542,7 +4544,7 @@ VMS_Check_For_Main () S_SET_TYPE (symbolP, N_UNDF); S_GET_OTHER (symbolP) = 0; S_GET_DESC (symbolP) = 0; - S_GET_VALUE (symbolP) = 0; + S_SET_VALUE (symbolP, 0); symbolP->sy_name_offset = 0; symbolP->sy_number = 0; symbolP->sy_frag = New_Frag; diff --git a/gas/config/obj-vms.h b/gas/config/obj-vms.h index 46662f9ff61..c30a3a42a17 100644 --- a/gas/config/obj-vms.h +++ b/gas/config/obj-vms.h @@ -165,8 +165,6 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_IS_STABD(s) (S_GET_NAME(s) == (char *)0) /* Accessors */ -/* The value of the symbol */ -#define S_GET_VALUE(s) (((s)->sy_symbol.n_value)) /* The name of the symbol */ #define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name) /* The pointer to the string table */ @@ -183,8 +181,6 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_GET_DESC(s) ((s)->sy_symbol.n_desc) /* Modifiers */ -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ /* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) diff --git a/gas/expr.h b/gas/expr.h index 899ac0ae838..d98b486d19e 100644 --- a/gas/expr.h +++ b/gas/expr.h @@ -44,14 +44,12 @@ typedef struct { - symbolS *X_add_symbol; /* "foo", above */ - symbolS *X_subtract_symbol; /* "bar", above */ - offsetT X_add_number; /* 42, above -- must be signed */ + struct symbol *X_add_symbol; /* "foo", above */ + struct symbol *X_subtract_symbol; /* "bar", above */ + offsetT X_add_number; /* 42, above -- must be signed */ /* What segment (expr type)? */ segT X_seg; -} - -expressionS; +} expressionS; /* "result" should be type (expressionS *). */ #define expression(result) expr(0,result) diff --git a/gas/struc-symbol.h b/gas/struc-symbol.h index d840f830b5d..2994f7f851e 100644 --- a/gas/struc-symbol.h +++ b/gas/struc-symbol.h @@ -46,6 +46,9 @@ struct symbol asymbol *bsym; #endif + /* The value of the symbol. */ + expressionS sy_value; + struct symbol *sy_next; /* forward chain, or NULL */ #ifdef SYMBOLS_NEED_BACKPOINTERS struct symbol *sy_previous; /* backward chain, or NULL */ diff --git a/gas/symbols.c b/gas/symbols.c index e39e50c92f9..24fe3d84697 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -946,6 +946,28 @@ decode_local_label_name (s) return (symbol_decode); } /* decode_local_label_name() */ +/* Get the value of a symbol. */ + +valueT +S_GET_VALUE (s) + symbolS *s; +{ + if (s->sy_value.X_seg != absolute_section) + as_bad ("Attempt to get value of unresolved symbol"); + return (valueT) s->sy_value.X_add_number; +} + +/* Set the value of a symbol. */ + +void +S_SET_VALUE (s, val) + symbolS *s; + valueT val; +{ + s->sy_value.X_seg = absolute_section; + s->sy_value.X_add_number = (offsetT) val; +} + #ifdef BFD_ASSEMBLER int @@ -1016,13 +1038,6 @@ S_IS_STABD (s) return S_GET_NAME (s) == 0; } -valueT -S_GET_VALUE (s) - symbolS *s; -{ - return s->bsym->value; -} - CONST char * S_GET_NAME (s) symbolS *s; @@ -1037,14 +1052,6 @@ S_GET_SEGMENT (s) return s->bsym->section; } -void -S_SET_VALUE (s, val) - symbolS *s; - valueT val; -{ - s->bsym->value = val; -} - void S_SET_SEGMENT (s, seg) symbolS *s; diff --git a/gas/symbols.h b/gas/symbols.h index cbdafff6b08..3912c08c3d7 100644 --- a/gas/symbols.h +++ b/gas/symbols.h @@ -57,6 +57,10 @@ void fb_label_instance_inc PARAMS ((long label)); char *fb_label_name PARAMS ((long n, long augend)); #endif /* LOCAL_LABELS_FB */ +/* Get and set the values of symbols. These used to be macros. */ +extern valueT S_GET_VALUE PARAMS ((symbolS *)); +extern void S_SET_VALUE PARAMS ((symbolS *, valueT)); + #ifdef BFD_ASSEMBLER extern int S_IS_EXTERNAL PARAMS ((symbolS *)); extern int S_IS_COMMON PARAMS ((symbolS *)); @@ -65,10 +69,8 @@ extern int S_IS_DEBUG PARAMS ((symbolS *)); extern int S_IS_LOCAL PARAMS ((symbolS *)); extern int S_IS_EXTERN PARAMS ((symbolS *)); extern int S_IS_STABD PARAMS ((symbolS *)); -extern valueT S_GET_VALUE PARAMS ((symbolS *)); extern CONST char *S_GET_NAME PARAMS ((symbolS *)); extern segT S_GET_SEGMENT PARAMS ((symbolS *)); -extern void S_SET_VALUE PARAMS ((symbolS *, valueT)); extern void S_SET_SEGMENT PARAMS ((symbolS *, segT)); extern void S_SET_EXTERNAL PARAMS ((symbolS *)); extern void S_SET_NAME PARAMS ((symbolS *, char *)); diff --git a/gas/write.c b/gas/write.c index 245cd836719..63353e395a7 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1231,6 +1231,11 @@ write_object_file () #endif continue; } + + /* Set the value into the BFD symbol. Up til now the value + has only been kept in the gas symbolS struct. */ + symp->bsym->value = S_GET_VALUE (symp); + i++; } n = i; @@ -1255,6 +1260,10 @@ write_object_file () #ifdef obj_frob_file + /* If obj_frob_file changes the symbol value at this point, it is + responsible for moving the changed value into symp->bsym->value + as well. Hopefully all symbol value changing can be done in + {obj,tc}_frob_symbol. */ obj_frob_file (); #endif