* symbols.c (S_GET_VALUE): Don't treat O_constant and local
[deliverable/binutils-gdb.git] / gas / write.c
index 151f1cfbe68f9970fddc67a07530e1e8a5532ace..41edcb3545ff8433d3736db84f43aebb760cb352 100644 (file)
 #define TC_FIX_ADJUSTABLE(fix) 1
 #endif
 
+#ifndef TC_FINALIZE_SYMS_BEFORE_SIZE_SEG
+#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 1
+#endif
+
 #ifndef        MD_PCREL_FROM_SECTION
 #define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from(FIXP)
 #endif
@@ -61,10 +65,8 @@ extern CONST int md_short_jump_size;
 extern CONST int md_long_jump_size;
 #endif
 
-/* Used to control final evaluation of expressions that are more
-   complex than symbol + constant.  1 means set final value for simple
-   expressions, 2 means set final value for more complex expressions.  */
-int finalize_syms = 1;
+/* Used to control final evaluation of expressions.  */
+int finalize_syms = 0;
 
 int symbol_table_frozen;
 void print_fixup PARAMS ((fixS *));
@@ -760,10 +762,10 @@ adjust_reloc_syms (abfd, sec, xxx)
           symbols, though, since they are not in the regular symbol
           table.  */
        if (sym != NULL)
-         resolve_symbol_value (sym, finalize_syms);
+         resolve_symbol_value (sym);
 
        if (fixp->fx_subsy != NULL)
-         resolve_symbol_value (fixp->fx_subsy, finalize_syms);
+         resolve_symbol_value (fixp->fx_subsy);
 
        /* If this symbol is equated to an undefined symbol, convert
            the fixup to being against that symbol.  */
@@ -1576,13 +1578,23 @@ write_object_file ()
       if (!changed)
        break;
     }
+
+  /* Note - Most ports will use the default value of
+     TC_FINALIZE_SYMS_BEFORE_SIZE_SEG, which 1.  This will force
+     local symbols to be resolved, removing their frag information.
+     Some ports however, will not have finished relaxing all of
+     their frags and will still need the local symbol frag
+     information.  These ports can set
+     TC_FINALIZE_SYMS_BEFORE_SIZE_SEG to 0.  */
+  finalize_syms = TC_FINALIZE_SYMS_BEFORE_SIZE_SEG;
+
   bfd_map_over_sections (stdoutput, size_seg, (char *) 0);
 #else
   relax_and_size_all_segments ();
 #endif /* BFD_ASSEMBLER  */
 
   /* Relaxation has completed.  Freeze all syms.  */
-  finalize_syms = 2;
+  finalize_syms = 1;
 
 #if defined (BFD_ASSEMBLER) && defined (OBJ_COFF) && defined (TE_GO32)
   /* Now that the segments have their final sizes, run through the
@@ -1738,9 +1750,6 @@ write_object_file ()
            /* Patch the jump table.  */
            /* This is the offset from ??? to table_ptr+0.  */
            to_addr = table_addr - S_GET_VALUE (lie->sub);
-#ifdef BFD_ASSEMBLER
-           to_addr -= symbol_get_frag (lie->sub)->fr_address;
-#endif
 #ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD
            TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_addr, lie);
 #endif
@@ -1757,9 +1766,6 @@ write_object_file ()
            /* This is a long jump from table_ptr+0 to the final target.  */
            from_addr = table_addr;
            to_addr = S_GET_VALUE (lie->add) + lie->addnum;
-#ifdef BFD_ASSEMBLER
-           to_addr += symbol_get_frag (lie->add)->fr_address;
-#endif
            md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag,
                                 lie->add);
            table_ptr += md_long_jump_size;
@@ -1902,7 +1908,7 @@ write_object_file ()
       symbolS *symp;
 
       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
-       resolve_symbol_value (symp, finalize_syms);
+       resolve_symbol_value (symp);
     }
   resolve_local_symbol_values ();
 
@@ -1950,7 +1956,7 @@ write_object_file ()
          /* Do it again, because adjust_reloc_syms might introduce
             more symbols.  They'll probably only be section symbols,
             but they'll still need to have the values computed.  */
-         resolve_symbol_value (symp, finalize_syms);
+         resolve_symbol_value (symp);
 
          /* Skip symbols which were equated to undefined or common
              symbols.  */
@@ -2103,7 +2109,7 @@ relax_frag (segment, fragP, stretch)
 #endif
       know (!(S_GET_SEGMENT (symbolP) == absolute_section)
            || sym_frag == &zero_address_frag);
-      target += S_GET_VALUE (symbolP) + sym_frag->fr_address;
+      target += S_GET_VALUE (symbolP);
 
       /* If frag has yet to be reached on this pass,
         assume it will move by STRETCH just as we did.
@@ -2242,8 +2248,9 @@ relax_segment (segment_frag_root, segment)
 
            if (offset % fragP->fr_var != 0)
              {
-               as_bad (_("alignment padding (%lu bytes) not a multiple of %ld"),
-                       (unsigned long) offset, (long) fragP->fr_var);
+               as_bad_where (fragP->fr_file, fragP->fr_line,
+                             _("alignment padding (%lu bytes) not a multiple of %ld"),
+                             (unsigned long) offset, (long) fragP->fr_var);
                offset -= (offset % fragP->fr_var);
              }
 
@@ -2343,21 +2350,20 @@ relax_segment (segment_frag_root, segment)
                      if (lie->added)
                        continue;
 
-                     offset = (symbol_get_frag (lie->add)->fr_address
-                               + S_GET_VALUE (lie->add)
+                     offset = (S_GET_VALUE (lie->add)
                                + lie->addnum
-                               - (symbol_get_frag (lie->sub)->fr_address
-                                  + S_GET_VALUE (lie->sub)));
+                               - S_GET_VALUE (lie->sub));
                      if (offset <= -32768 || offset >= 32767)
                        {
                          if (flag_warn_displacement)
                            {
                              char buf[50];
                              sprint_value (buf, (addressT) lie->addnum);
-                             as_warn (_(".word %s-%s+%s didn't fit"),
-                                      S_GET_NAME (lie->add),
-                                      S_GET_NAME (lie->sub),
-                                      buf);
+                             as_warn_where (fragP->fr_file, fragP->fr_line,
+                                            _(".word %s-%s+%s didn't fit"),
+                                            S_GET_NAME (lie->add),
+                                            S_GET_NAME (lie->sub),
+                                            buf);
                            }
                          lie->added = 1;
                          if (fragP->fr_subtype == 0)
@@ -2422,9 +2428,8 @@ relax_segment (segment_frag_root, segment)
                      know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
                            || (symbolP->sy_frag == &zero_address_frag));
 #endif
-                     target += (S_GET_VALUE (symbolP)
-                                + symbol_get_frag (symbolP)->fr_address);
-                   }           /* if we have a symbol  */
+                     target += S_GET_VALUE (symbolP);
+                   }
 
                  know (fragP->fr_next);
                  after = fragP->fr_next->fr_address;
@@ -2452,23 +2457,31 @@ relax_segment (segment_frag_root, segment)
                }
 
              case rs_space:
+               growth = 0;
                if (symbolP)
                  {
-                   growth = S_GET_VALUE (symbolP);
-                   if (symbol_get_frag (symbolP) != &zero_address_frag
+                   offsetT amount;
+
+                   amount = S_GET_VALUE (symbolP);
+                   if (S_GET_SEGMENT (symbolP) != absolute_section
                        || S_IS_COMMON (symbolP)
                        || ! S_IS_DEFINED (symbolP))
-                     as_bad_where (fragP->fr_file, fragP->fr_line,
-                                   _(".space specifies non-absolute value"));
-                   fragP->fr_symbol = 0;
-                   if (growth < 0)
                      {
-                       as_warn (_(".space or .fill with negative value, ignored"));
-                       growth = 0;
+                       as_bad_where (fragP->fr_file, fragP->fr_line,
+                                     _(".space specifies non-absolute value"));
+                       /* Prevent repeat of this error message.  */
+                       fragP->fr_symbol = 0;
                      }
+                   else if (amount < 0)
+                     {
+                       as_warn_where (fragP->fr_file, fragP->fr_line,
+                                      _(".space or .fill with negative value, ignored"));
+                       fragP->fr_symbol = 0;
+                     }
+                   else
+                     growth = (was_address + amount
+                               - fragP->fr_next->fr_address);
                  }
-               else
-                 growth = 0;
                break;
 
              case rs_machine_dependent:
@@ -2488,7 +2501,7 @@ relax_segment (segment_frag_root, segment)
                  valueT value;
                  int size;
 
-                 value = resolve_symbol_value (fragP->fr_symbol, 0);
+                 value = resolve_symbol_value (fragP->fr_symbol);
                  size = sizeof_leb128 (value, fragP->fr_subtype);
                  growth = size - fragP->fr_offset;
                  fragP->fr_offset = size;
@@ -2611,7 +2624,7 @@ fixup_segment (fixP, this_segment_type)
 
       if (sub_symbolP)
        {
-         resolve_symbol_value (sub_symbolP, finalize_syms);
+         resolve_symbol_value (sub_symbolP);
          if (add_symbolP == NULL || add_symbol_segment == absolute_section)
            {
              if (add_symbolP != NULL)
@@ -2652,8 +2665,15 @@ fixup_segment (fixP, this_segment_type)
                as_bad_where (fixP->fx_file, fixP->fx_line,
                              _("callj to difference of 2 symbols"));
 #endif /* TC_I960  */
-             add_number += S_GET_VALUE (add_symbolP) -
-               S_GET_VALUE (sub_symbolP);
+             add_number += (S_GET_VALUE (add_symbolP)
+                            - S_GET_VALUE (sub_symbolP));
+             if (1
+#ifdef TC_M68K
+                 /* See the comment below about 68k weirdness.  */
+                 && 0
+#endif
+                 && pcrel)
+               add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
 
              add_symbolP = NULL;
              pcrel = 0;        /* No further pcrel processing.  */
@@ -2678,21 +2698,26 @@ fixup_segment (fixP, this_segment_type)
                add_number -= S_GET_VALUE (sub_symbolP);
 
 #ifdef DIFF_EXPR_OK
-             else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
-#if 0
-                      /* Do this even if it's already described as
-                         pc-relative.  For example, on the m68k, an
-                         operand of "pc@(foo-.-2)" should address
-                         "foo" in a pc-relative mode.  */
-                      && pcrel
-#endif
-                      )
+             else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type)
                {
                  /* Make it pc-relative.  */
-                 add_number += (MD_PCREL_FROM_SECTION (fixP, this_segment_type)
-                                - S_GET_VALUE (sub_symbolP));
-                 pcrel = 1;
-                 fixP->fx_pcrel = 1;
+                 if (0
+#ifdef TC_M68K
+                     /* Do this for m68k even if it's already described
+                        as pc-relative.  On the m68k, an operand of
+                        "pc@(foo-.-2)" should address "foo" in a
+                        pc-relative mode.  */
+                     || 1
+#endif
+                     || !pcrel)
+                   {
+                     add_number += MD_PCREL_FROM_SECTION (fixP,
+                                                          this_segment_type);
+                     pcrel = 1;
+                     fixP->fx_pcrel = 1;
+                   }
+
+                 add_number -= S_GET_VALUE (sub_symbolP);
                  sub_symbolP = 0;
                  fixP->fx_subsy = 0;
                }
This page took 0.027309 seconds and 4 git commands to generate.