* elf64-alpha.c (ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED): Defined.
[deliverable/binutils-gdb.git] / gas / write.c
index 2beb1d7731c3513c20a0c08cbd791b29049e4d9f..55db85a7ec91e30f1f861021f3f65c86512d965a 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
@@ -765,8 +769,7 @@ adjust_reloc_syms (abfd, sec, xxx)
 
        /* If this symbol is equated to an undefined symbol, convert
            the fixup to being against that symbol.  */
-       if (sym != NULL && symbol_equated_p (sym)
-           && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+       if (sym != NULL && symbol_equated_reloc_p (sym))
          {
            fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
            sym = symbol_get_value_expression (sym)->X_add_symbol;
@@ -871,8 +874,9 @@ adjust_reloc_syms (abfd, sec, xxx)
            goto done;
          }
 
-       /* Never adjust a reloc against local symbol in a merge section.  */
-       if (symsec->flags & SEC_MERGE)
+       /* Never adjust a reloc against local symbol in a merge section
+          with non-zero addend.  */
+       if ((symsec->flags & SEC_MERGE) && fixp->fx_offset)
          {
            symbol_mark_used_in_reloc (fixp->fx_addsy);
            goto done;
@@ -979,11 +983,10 @@ write_relocs (abfd, sec, xxx)
        }
 
       /* If this is an undefined symbol which was equated to another
-         symbol, then use generate the reloc against the latter symbol
+         symbol, then generate the reloc against the latter symbol
          rather than the former.  */
       sym = fixp->fx_addsy;
-      while (symbol_equated_p (sym)
-            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+      while (symbol_equated_reloc_p (sym))
        {
          symbolS *n;
 
@@ -1055,8 +1058,7 @@ write_relocs (abfd, sec, xxx)
          symbol, then generate the reloc against the latter symbol
          rather than the former.  */
       sym = fixp->fx_addsy;
-      while (symbol_equated_p (sym)
-            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+      while (symbol_equated_reloc_p (sym))
        sym = symbol_get_value_expression (sym)->X_add_symbol;
       fixp->fx_addsy = sym;
 
@@ -1230,7 +1232,7 @@ write_contents (abfd, sec, xxx)
                    (stdoutput, sec, buf, (file_ptr) offset,
                     (bfd_size_type) n_per_buf * fill_size);
                  if (x != true)
-                   as_fatal (_("Cannot write to output file."));
+                   as_fatal (_("cannot write to output file"));
                  offset += n_per_buf * fill_size;
                }
            }
@@ -1364,7 +1366,7 @@ set_symtab ()
   asymbol **asympp;
   symbolS *symp;
   boolean result;
-  extern PTR bfd_alloc PARAMS ((bfd *, size_t));
+  extern PTR bfd_alloc PARAMS ((bfd *, bfd_size_type));
 
   /* Count symbols.  We can't rely on a count made by the loop in
      write_object_file, because *_frob_file may add a new symbol or
@@ -1376,9 +1378,9 @@ set_symtab ()
   if (nsyms)
     {
       int i;
+      bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *);
 
-      asympp = (asymbol **) bfd_alloc (stdoutput,
-                                      nsyms * sizeof (asymbol *));
+      asympp = (asymbol **) bfd_alloc (stdoutput, amt);
       symp = symbol_rootP;
       for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
        {
@@ -1479,14 +1481,14 @@ write_object_file ()
     if (flag_always_generate_output)
       {
        if (n_warns || n_errs)
-         as_warn (_("%d error%s, %d warning%s, generating bad object file.\n"),
+         as_warn (_("%d error%s, %d warning%s, generating bad object file"),
                   n_errs, n_errs == 1 ? "" : "s",
                   n_warns, n_warns == 1 ? "" : "s");
       }
     else
       {
        if (n_errs)
-         as_fatal (_("%d error%s, %d warning%s, no object file generated.\n"),
+         as_fatal (_("%d error%s, %d warning%s, no object file generated"),
                    n_errs, n_errs == 1 ? "" : "s",
                    n_warns, n_warns == 1 ? "" : "s");
       }
@@ -1574,15 +1576,24 @@ write_object_file ()
       if (!changed)
        break;
     }
-  /* Relaxation has completed.  Freeze all syms.  */
-  finalize_syms = 1;
+
+  /* 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 ();
-  finalize_syms = 1;
 #endif /* BFD_ASSEMBLER  */
 
+  /* Relaxation has completed.  Freeze all syms.  */
+  finalize_syms = 1;
+
 #if defined (BFD_ASSEMBLER) && defined (OBJ_COFF) && defined (TE_GO32)
   /* Now that the segments have their final sizes, run through the
      sections and set their vma and lma. !BFD gas sets them, and BFD gas
@@ -1737,9 +1748,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
@@ -1756,9 +1764,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;
@@ -1876,8 +1881,8 @@ write_object_file ()
       obj_emit_strings (&next_object_file_charP);
 
 #ifdef BFD_HEADERS
-    bfd_seek (stdoutput, 0, 0);
-    bfd_write (the_object_file, 1, object_file_size, stdoutput);
+    bfd_seek (stdoutput, (file_ptr) 0, 0);
+    bfd_bwrite (the_object_file, (bfd_size_type) object_file_size, stdoutput);
 #else
 
     /* Write the data to the file.  */
@@ -1943,7 +1948,7 @@ write_object_file ()
              /* They only differ if `name' is a fb or dollar local
                 label name.  */
              if (name2 != name && ! S_IS_DEFINED (symp))
-               as_bad (_("local label %s is not defined"), name2);
+               as_bad (_("local label `%s' is not defined"), name2);
            }
 
          /* Do it again, because adjust_reloc_syms might introduce
@@ -1953,8 +1958,7 @@ write_object_file ()
 
          /* Skip symbols which were equated to undefined or common
              symbols.  */
-         if (symbol_equated_p (symp)
-             && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
+         if (symbol_equated_reloc_p (symp))
            {
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              continue;
@@ -2006,7 +2010,7 @@ write_object_file ()
          /* Make sure we really got a value for the symbol.  */
          if (! symbol_resolved_p (symp))
            {
-             as_bad (_("can't resolve value for symbol \"%s\""),
+             as_bad (_("can't resolve value for symbol `%s'"),
                      S_GET_NAME (symp));
              symbol_mark_resolved (symp);
            }
@@ -2102,7 +2106,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.
@@ -2257,6 +2261,12 @@ relax_segment (segment_frag_root, segment)
          break;
 
        case rs_machine_dependent:
+         /* If fr_symbol is an expression, this call to
+            resolve_symbol_value sets up the correct segment, which will
+            likely be needed in md_estimate_size_before_relax.  */
+         if (fragP->fr_symbol)
+           resolve_symbol_value (fragP->fr_symbol);
+
          address += md_estimate_size_before_relax (fragP, segment);
          break;
 
@@ -2343,11 +2353,9 @@ 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)
@@ -2423,9 +2431,13 @@ 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  */
+                      /* Convert from an actual address to an octet offset
+                         into the section.  Here it is assumed that the
+                         section's VMA is zero, and can omit subtracting it
+                         from the symbol's value to get the address offset.  */
+                      know (S_GET_SECTION (symbolP)->vma == 0);
+                     target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE;
+                   }
 
                  know (fragP->fr_next);
                  after = fragP->fr_next->fr_address;
@@ -2436,7 +2448,7 @@ relax_segment (segment_frag_root, segment)
                         cannot have fewer than 0 chars.  That is, we can't
                         .org backwards.  */
                      as_bad_where (fragP->fr_file, fragP->fr_line,
-                                   _("attempt to .org backwards ignored"));
+                                   _("attempt to .org backwards"));
 
                      /* We've issued an error message.  Change the
                          frag to avoid cascading errors.  */
@@ -2475,7 +2487,7 @@ relax_segment (segment_frag_root, segment)
                        fragP->fr_symbol = 0;
                      }
                    else
-                     growth = (was_address + amount
+                     growth = (was_address + fragP->fr_fix + amount
                                - fragP->fr_next->fr_address);
                  }
                break;
@@ -2547,7 +2559,7 @@ relax_segment (segment_frag_root, segment)
    Go through all the fixS's in a segment and see which ones can be
    handled now.  (These consist of fixS where we have since discovered
    the value of a symbol, or the address of the frag involved.)
-   For each one, call md_apply_fix to put the fix into the frag data.
+   For each one, call md_apply_fix3 to put the fix into the frag data.
 
    Result is a count of how many relocation structs will be needed to
    handle the remaining fixS's that we couldn't completely handle here.
@@ -2645,7 +2657,7 @@ fixup_segment (fixP, this_segment_type)
              else
              bad_sub_reloc:
                as_bad_where (fixP->fx_file, fixP->fx_line,
-                             _("Negative of non-absolute symbol %s"),
+                             _("negative of non-absolute symbol `%s'"),
                              S_GET_NAME (sub_symbolP));
            }
          else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
@@ -2659,7 +2671,7 @@ fixup_segment (fixP, this_segment_type)
                 as the target of a call instruction.  */
              if (fixP->fx_tcbit)
                as_bad_where (fixP->fx_file, fixP->fx_line,
-                             _("callj to difference of 2 symbols"));
+                             _("callj to difference of two symbols"));
 #endif /* TC_I960  */
              add_number += (S_GET_VALUE (add_symbolP)
                             - S_GET_VALUE (sub_symbolP));
@@ -2739,7 +2751,7 @@ fixup_segment (fixP, this_segment_type)
                  char buf[50];
                  sprint_value (buf, fragP->fr_address + where);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               _("Subtraction of two symbols in different sections \"%s\" {%s section} - \"%s\" {%s section} at file address %s."),
+                               _("subtraction of two symbols in different sections `%s' {%s section} - `%s' {%s section} at file address %s"),
                                S_GET_NAME (add_symbolP),
                                segment_name (S_GET_SEGMENT (add_symbolP)),
                                S_GET_NAME (sub_symbolP),
@@ -2855,25 +2867,7 @@ fixup_segment (fixP, this_segment_type)
        }
 
       if (!fixP->fx_done)
-       {
-#ifdef MD_APPLY_FIX3
-         md_apply_fix3 (fixP, &add_number, this_segment_type);
-#else
-#ifdef BFD_ASSEMBLER
-         md_apply_fix (fixP, &add_number);
-#else
-         md_apply_fix (fixP, add_number);
-#endif
-#endif
-
-#ifndef TC_HANDLES_FX_DONE
-         /* If the tc-* files haven't been converted, assume it's handling
-            it the old way, where a null fx_addsy means that the fix has
-            been applied completely, and no further work is needed.  */
-         if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
-           fixP->fx_done = 1;
-#endif
-       }
+       md_apply_fix3 (fixP, & add_number, this_segment_type);
 
       if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && size > 0)
        {
@@ -2893,7 +2887,7 @@ fixup_segment (fixP, this_segment_type)
                  else
                    sprintf (buf2, "%ld", (long) add_number);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               _("Value of %s too large for field of %d bytes at %s"),
+                               _("value of %s too large for field of %d bytes at %s"),
                                buf2, size, buf);
                } /* Generic error checking.  */
            }
@@ -2905,7 +2899,7 @@ fixup_segment (fixP, this_segment_type)
              && size == 2
              && add_number > 0x7fff)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
+                         _("signed .word overflow; switch may be too large; %ld at 0x%lx"),
                          (long) add_number,
                          (unsigned long) (fragP->fr_address + where));
 #endif
This page took 0.03266 seconds and 4 git commands to generate.