X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fsymbols.c;h=acf394330dfce03e213f3dc06e33d567e989bd5d;hb=9a17a136439c200b13a69d453f38824b7edc522c;hp=d8a9c9244c00776796e67d7837cbf528dedb8abf;hpb=d18d199917337537713f9fc4b7ae4d6568f740cf;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/symbols.c b/gas/symbols.c index d8a9c9244c..acf394330d 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1,5 +1,5 @@ /* symbols.c -symbol table- - Copyright (C) 1987-2019 Free Software Foundation, Inc. + Copyright (C) 1987-2020 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -73,10 +73,6 @@ struct symbol_flags before. It is cleared as soon as any direct reference to the symbol is present. */ unsigned int sy_weakrefd : 1; - - /* This if set if the unit of the symbol value is "octets" instead - of "bytes". */ - unsigned int sy_octets : 1; }; /* The information we keep for a symbol. Note that the symbol table @@ -118,7 +114,7 @@ struct symbol /* A pointer in the symbol may point to either a complete symbol (struct symbol above) or to a local symbol (struct local_symbol defined here). The symbol code can detect the case by examining - the first field. It is always NULL for a local symbol. + the first field which is present in both structs. We do this because we ordinarily only need a small amount of information for a local symbol. The symbol table takes up a lot of @@ -331,14 +327,14 @@ local_symbol_make (const char *name, segT section, valueT val, fragS *frag) { const char *name_copy; struct local_symbol *ret; + struct symbol_flags flags = { .sy_local_symbol = 1, .sy_resolved = 0 }; ++local_symbol_count; name_copy = save_symbol_name (name); ret = (struct local_symbol *) obstack_alloc (¬es, sizeof *ret); - ret->lsy_flags.sy_local_symbol = 1; - ret->lsy_flags.sy_resolved = 0; + ret->lsy_flags = flags; ret->lsy_name = name_copy; ret->lsy_section = section; local_symbol_set_frag (ret, frag); @@ -850,9 +846,7 @@ symbol_temp_new_now (void) symbolS * symbol_temp_new_now_octets (void) { - symbolS * symb = symbol_temp_new (now_seg, frag_now_fix_octets (), frag_now); - symb->sy_flags.sy_octets = 1; - return symb; + return symbol_temp_new (now_seg, frag_now_fix_octets (), frag_now); } symbolS * @@ -929,14 +923,12 @@ symbol_find_noref (const char *name, int noref) *copy++ = TOUPPER (c); *copy = '\0'; - if (copy2 != NULL) - free (copy2); + free (copy2); copy = (char *) name; } result = symbol_find_exact_noref (name, noref); - if (copy != NULL) - free (copy); + free (copy); return result; } @@ -1097,19 +1089,6 @@ use_complex_relocs_for (symbolS * symp) case O_constant: return 0; - case O_symbol: - case O_symbol_rva: - case O_uminus: - case O_bit_not: - case O_logical_not: - if ( (S_IS_COMMON (symp->sy_value.X_add_symbol) - || S_IS_LOCAL (symp->sy_value.X_add_symbol)) - && - (S_IS_DEFINED (symp->sy_value.X_add_symbol) - && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section)) - return 0; - break; - case O_multiply: case O_divide: case O_modulus: @@ -1129,18 +1108,22 @@ use_complex_relocs_for (symbolS * symp) case O_gt: case O_logical_and: case O_logical_or: - - if ( (S_IS_COMMON (symp->sy_value.X_add_symbol) - || S_IS_LOCAL (symp->sy_value.X_add_symbol)) - && - (S_IS_COMMON (symp->sy_value.X_op_symbol) + if ((S_IS_COMMON (symp->sy_value.X_op_symbol) || S_IS_LOCAL (symp->sy_value.X_op_symbol)) - - && S_IS_DEFINED (symp->sy_value.X_add_symbol) && S_IS_DEFINED (symp->sy_value.X_op_symbol) - && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section && S_GET_SEGMENT (symp->sy_value.X_op_symbol) != expr_section) - return 0; + { + case O_symbol: + case O_symbol_rva: + case O_uminus: + case O_bit_not: + case O_logical_not: + if ((S_IS_COMMON (symp->sy_value.X_add_symbol) + || S_IS_LOCAL (symp->sy_value.X_add_symbol)) + && S_IS_DEFINED (symp->sy_value.X_add_symbol) + && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section) + return 0; + } break; default: @@ -1221,7 +1204,7 @@ valueT resolve_symbol_value (symbolS *symp) { int resolved; - valueT final_val = 0; + valueT final_val; segT final_seg; if (LOCAL_SYMBOL_CHECK (symp)) @@ -1232,7 +1215,13 @@ resolve_symbol_value (symbolS *symp) if (local_symbol_resolved_p (locsym)) return final_val; - final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE; + /* Symbols whose section has SEC_ELF_OCTETS set, + resolve to octets instead of target bytes. */ + if (locsym->lsy_section->flags & SEC_OCTETS) + final_val += local_symbol_get_frag (locsym)->fr_address; + else + final_val += (local_symbol_get_frag (locsym)->fr_address + / OCTETS_PER_BYTE); if (finalize_syms) { @@ -1245,10 +1234,25 @@ resolve_symbol_value (symbolS *symp) if (symp->sy_flags.sy_resolved) { + final_val = 0; + while (symp->sy_value.X_op == O_symbol) + { + final_val += symp->sy_value.X_add_number; + symp = symp->sy_value.X_add_symbol; + if (LOCAL_SYMBOL_CHECK (symp)) + { + struct local_symbol *locsym = (struct local_symbol *) symp; + final_val += locsym->lsy_value; + return final_val; + } + if (!symp->sy_flags.sy_resolved) + return 0; + } if (symp->sy_value.X_op == O_constant) - return (valueT) symp->sy_value.X_add_number; + final_val += symp->sy_value.X_add_number; else - return 0; + final_val = 0; + return final_val; } resolved = 0; @@ -1305,6 +1309,7 @@ resolve_symbol_value (symbolS *symp) resolved = 1; } + final_val = 0; final_seg = undefined_section; goto exit_dont_set_value; } @@ -1336,7 +1341,9 @@ resolve_symbol_value (symbolS *symp) /* Fall through. */ case O_constant: - if (symp->sy_flags.sy_octets) + /* Symbols whose section has SEC_ELF_OCTETS set, + resolve to octets instead of target bytes. */ + if (symp->bsym->section->flags & SEC_OCTETS) final_val += symp->sy_frag->fr_address; else final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE; @@ -1378,6 +1385,12 @@ resolve_symbol_value (symbolS *symp) break; } + /* Don't leave symbol loops. */ + if (finalize_syms + && !LOCAL_SYMBOL_CHECK (add_symbol) + && add_symbol->sy_flags.sy_resolving) + break; + if (finalize_syms && final_val == 0) { if (LOCAL_SYMBOL_CHECK (add_symbol)) @@ -1392,11 +1405,16 @@ resolve_symbol_value (symbolS *symp) relocation to detect this case, and convert the relocation to be against the symbol to which this symbol is equated. */ - if (! S_IS_DEFINED (add_symbol) + if (seg_left == undefined_section + || bfd_is_com_section (seg_left) #if defined (OBJ_COFF) && defined (TE_PE) || S_IS_WEAK (add_symbol) #endif - || S_IS_COMMON (add_symbol)) + || (finalize_syms + && ((final_seg == expr_section + && seg_left != expr_section + && seg_left != absolute_section) + || symbol_shadow_p (symp)))) { if (finalize_syms) { @@ -1407,25 +1425,6 @@ resolve_symbol_value (symbolS *symp) symp->sy_value.X_op_symbol = add_symbol; } final_seg = seg_left; - final_val = 0; - resolved = symbol_resolved_p (add_symbol); - symp->sy_flags.sy_resolving = 0; - goto exit_dont_set_value; - } - else if (finalize_syms - && ((final_seg == expr_section && seg_left != expr_section) - || symbol_shadow_p (symp))) - { - /* If the symbol is an expression symbol, do similarly - as for undefined and common syms above. Handles - "sym +/- expr" where "expr" cannot be evaluated - immediately, and we want relocations to be against - "sym", eg. because it is weak. */ - symp->sy_value.X_op = O_symbol; - symp->sy_value.X_add_symbol = add_symbol; - symp->sy_value.X_add_number = final_val; - symp->sy_value.X_op_symbol = add_symbol; - final_seg = seg_left; final_val += symp->sy_frag->fr_address + left; resolved = symbol_resolved_p (add_symbol); symp->sy_flags.sy_resolving = 0; @@ -1650,7 +1649,7 @@ resolve_symbol_value (symbolS *symp) if (finalize_syms) S_SET_VALUE (symp, final_val); -exit_dont_set_value: + exit_dont_set_value: /* Always set the segment, even if not finalizing the value. The segment is used to determine whether a symbol is defined. */ S_SET_SEGMENT (symp, final_seg); @@ -2324,14 +2323,14 @@ S_IS_LOCAL (symbolS *s) if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL)) abort (); - if (bfd_get_section (s->bsym) == reg_section) + if (bfd_asymbol_section (s->bsym) == reg_section) return 1; if (flag_strip_local_absolute /* Keep BSF_FILE symbols in order to allow debuggers to identify the source file even when the object file is stripped. */ && (flags & (BSF_GLOBAL | BSF_FILE)) == 0 - && bfd_get_section (s->bsym) == absolute_section) + && bfd_asymbol_section (s->bsym) == absolute_section) return 1; name = S_GET_NAME (s); @@ -2665,18 +2664,6 @@ symbol_set_value_now (symbolS *sym) symbol_set_frag (sym, frag_now); } -/* Set the value of SYM to the current position in the current segment, - in octets. */ - -void -symbol_set_value_now_octets (symbolS *sym) -{ - S_SET_SEGMENT (sym, now_seg); - S_SET_VALUE (sym, frag_now_fix_octets ()); - symbol_set_frag (sym, frag_now); - sym->sy_flags.sy_octets = 1; -} - /* Set the frag of a symbol. */ void @@ -2948,13 +2935,6 @@ symbol_set_bfdsym (symbolS *s, asymbol *bsym) /* else XXX - What do we do now ? */ } -/* Return whether symbol unit is "octets" (instead of "bytes"). */ - -int symbol_octets_p (symbolS *s) -{ - return s->sy_flags.sy_octets; -} - #ifdef OBJ_SYMFIELD_TYPE /* Get a pointer to the object format information for a symbol. */ @@ -3293,7 +3273,7 @@ symbol_relc_make_sym (symbolS * sym) is defined as an expression or a plain value. */ if ( S_GET_SEGMENT (sym) == expr_section || S_GET_SEGMENT (sym) == absolute_section) - return symbol_relc_make_expr (& sym->sy_value); + return symbol_relc_make_expr (symbol_get_value_expression (sym)); /* This may be a "fake symbol", referring to ".". Write out a special null symbol to refer to this position. */