2003-05-01 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gas / write.c
index b1c27d78b52e508fbffdc1752553346bd5d9d1da..ce40572749cc967079f327ee23b413425d559b06 100644 (file)
@@ -1,6 +1,6 @@
 /* write.c - emit .o file
    Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002
+   1998, 1999, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -34,7 +34,7 @@
 
 #ifndef TC_FORCE_RELOCATION
 #define TC_FORCE_RELOCATION(FIX)               \
-  (S_FORCE_RELOC ((FIX)->fx_addsy))
+  (generic_force_reloc (FIX))
 #endif
 
 #ifndef TC_FORCE_RELOCATION_ABS
@@ -374,6 +374,19 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type)
   return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type);
 }
 
+/* Generic function to determine whether a fixup requires a relocation.  */
+int
+generic_force_reloc (fix)
+     fixS *fix;
+{
+#ifdef BFD_ASSEMBLER
+  if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+      || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+    return 1;
+#endif
+  return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
+}
+
 /* Append a string onto another string, bumping the pointer along.  */
 void
 append (charPP, fromP, length)
@@ -691,11 +704,11 @@ size_seg (abfd, sec, xxx)
   else
     flags &= ~SEC_RELOC;
   x = bfd_set_section_flags (abfd, sec, flags);
-  assert (x == true);
+  assert (x);
 
   newsize = md_section_align (sec, size);
   x = bfd_set_section_size (abfd, sec, newsize);
-  assert (x == true);
+  assert (x);
 
   /* If the size had to be rounded up, add some padding in the last
      non-empty frag.  */
@@ -823,7 +836,7 @@ adjust_reloc_syms (abfd, sec, xxx)
 
        /* If the symbol is undefined, common, weak, or global (ELF
           shared libs), we can't replace it with the section symbol.  */
-       if (S_FORCE_RELOC (fixp->fx_addsy))
+       if (S_FORCE_RELOC (fixp->fx_addsy, 1))
          continue;
 
        /* Is there some other (target cpu dependent) reason we can't adjust
@@ -1004,7 +1017,6 @@ write_relocs (abfd, sec, xxx)
   for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
     {
       arelent **reloc;
-      char *data;
       bfd_reloc_status_type s;
       symbolS *sym;
       int j;
@@ -1040,7 +1052,6 @@ write_relocs (abfd, sec, xxx)
          relocs[i++] = reloc[j];
          assert (i <= n);
        }
-      data = fixp->fx_frag->fr_literal + fixp->fx_where;
       if (fixp->fx_where + fixp->fx_size
          > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
        as_bad_where (fixp->fx_file, fixp->fx_line,
@@ -1148,7 +1159,7 @@ write_contents (abfd, sec, xxx)
          x = bfd_set_section_contents (stdoutput, sec,
                                        f->fr_literal, (file_ptr) offset,
                                        (bfd_size_type) f->fr_fix);
-         if (x == false)
+         if (!x)
            {
              bfd_perror (stdoutput->filename);
              as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
@@ -1172,7 +1183,7 @@ write_contents (abfd, sec, xxx)
                                                fill_literal,
                                                (file_ptr) offset,
                                                (bfd_size_type) fill_size);
-                 if (x == false)
+                 if (!x)
                    {
                      bfd_perror (stdoutput->filename);
                      as_perror (_("FATAL: Can't write %s"),
@@ -1206,7 +1217,7 @@ write_contents (abfd, sec, xxx)
                  x = bfd_set_section_contents
                    (stdoutput, sec, buf, (file_ptr) offset,
                     (bfd_size_type) n_per_buf * fill_size);
-                 if (x != true)
+                 if (!x)
                    as_fatal (_("cannot write to output file"));
                  offset += n_per_buf * fill_size;
                }
@@ -1340,7 +1351,7 @@ set_symtab ()
   int nsyms;
   asymbol **asympp;
   symbolS *symp;
-  boolean result;
+  bfd_boolean result;
   extern PTR bfd_alloc PARAMS ((bfd *, bfd_size_type));
 
   /* Count symbols.  We can't rely on a count made by the loop in
@@ -1366,7 +1377,7 @@ set_symtab ()
   else
     asympp = 0;
   result = bfd_set_symtab (stdoutput, asympp, nsyms);
-  assert (result == true);
+  assert (result);
   symbol_table_frozen = 1;
 }
 #endif
@@ -1409,7 +1420,25 @@ subsegs_finish ()
          any alignment is meaningless, and, moreover, will look weird
          if we are generating a listing.  */
       if (!had_errors ())
-       alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
+       {
+         alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
+#ifdef BFD_ASSEMBLER
+         if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
+             && now_seg->entsize)
+           {
+             unsigned int entsize = now_seg->entsize;
+             int entalign = 0;
+
+             while ((entsize & 1) == 0)
+               {
+                 ++entalign;
+                 entsize >>= 1;
+               }
+             if (entalign > alignment)
+               alignment = entalign;
+           }
+#endif
+       }
 
       if (subseg_text_p (now_seg))
        frag_align_code (alignment, 0);
@@ -1555,6 +1584,10 @@ write_object_file ()
   /* Relaxation has completed.  Freeze all syms.  */
   finalize_syms = 1;
 
+#ifdef md_post_relax_hook
+  md_post_relax_hook;
+#endif
+
 #ifndef BFD_ASSEMBLER
   /* Crawl the symbol chain.
 
@@ -1606,7 +1639,7 @@ write_object_file ()
 #ifdef OBJ_BOUT
            || fragP->fr_next == data_frag_root
 #endif
-           || ((fragP->fr_next->fr_address - fragP->fr_address)
+           || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
                == (fragP->fr_fix + fragP->fr_offset * fragP->fr_var))))
        abort ();
 #endif
This page took 0.02614 seconds and 4 git commands to generate.