X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fsymbols.c;h=d16e804c2b9ae17bb870e21223172ef05937ef33;hb=b6f8c7c45229a8a5405079e586bfbaad396d2cbe;hp=66865e0ef42b66572be0490de03bb0ae2998c4dc;hpb=6d6ad65b43efa17a825702297331fcb290445a18;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/symbols.c b/gas/symbols.c index 66865e0ef4..d16e804c2b 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1,5 +1,5 @@ /* symbols.c -symbol table- - Copyright (C) 1987-2016 Free Software Foundation, Inc. + Copyright (C) 1987-2018 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -25,6 +25,7 @@ #include "obstack.h" /* For "symbols.h" */ #include "subsegs.h" #include "struc-symbol.h" +#include "write.h" /* This is non-zero if symbols are case sensitive, which is the default. */ @@ -1561,9 +1562,23 @@ snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP) } *symbolPP = symbolP; - *valueP = exp.X_add_number; - *segP = symbolP->bsym->section; - *fragPP = symbolP->sy_frag; + + /* A bogus input file can result in resolve_expression() + generating a local symbol, so we have to check again. */ + if (LOCAL_SYMBOL_CHECK (symbolP)) + { + struct local_symbol *locsym = (struct local_symbol *) symbolP; + + *valueP = locsym->lsy_value; + *segP = locsym->lsy_section; + *fragPP = local_symbol_get_frag (locsym); + } + else + { + *valueP = exp.X_add_number; + *segP = symbolP->bsym->section; + *fragPP = symbolP->sy_frag; + } if (*segP == expr_section) switch (exp.X_op) @@ -2091,16 +2106,20 @@ S_IS_DEFINED (symbolS *s) int S_FORCE_RELOC (symbolS *s, int strict) { + segT sec; if (LOCAL_SYMBOL_CHECK (s)) - return ((struct local_symbol *) s)->lsy_section == undefined_section; - - return ((strict + sec = ((struct local_symbol *) s)->lsy_section; + else + { + if ((strict && ((s->bsym->flags & BSF_WEAK) != 0 || (EXTERN_FORCE_RELOC && (s->bsym->flags & BSF_GLOBAL) != 0))) - || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0 - || s->bsym->section == undefined_section - || bfd_is_com_section (s->bsym->section)); + || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0) + return TRUE; + sec = s->bsym->section; + } + return bfd_is_und_section (sec) || bfd_is_com_section (sec); } int @@ -2143,6 +2162,9 @@ S_IS_LOCAL (symbolS *s) && ! S_IS_DEBUG (s) && (strchr (name, DOLLAR_LABEL_CHAR) || strchr (name, LOCAL_LABEL_CHAR) +#if FAKE_LABEL_CHAR != DOLLAR_LABEL_CHAR + || strchr (name, FAKE_LABEL_CHAR) +#endif || TC_LABEL_IS_LOCAL (name) || (! flag_keep_locals && (bfd_is_local_label (stdoutput, s->bsym) @@ -3069,7 +3091,7 @@ symbol_relc_make_sym (symbolS * sym) || S_GET_SEGMENT (sym) == absolute_section) return symbol_relc_make_expr (& sym->sy_value); - /* This may be a "fake symbol" L0\001, referring to ".". + /* This may be a "fake symbol", referring to ".". Write out a special null symbol to refer to this position. */ if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME)) return xstrdup (".");