2003-02-20 David Carlton <carlton@math.stanford.edu>
[deliverable/binutils-gdb.git] / gas / write.c
index b4cc7e090b05a43dadde81548461cfbcc9ae1da1..f5db82e298d5a1750c0789811a3f1007dc428798 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
 #endif
 
 #ifndef TC_FORCE_RELOCATION_SUB_ABS
-#define TC_FORCE_RELOCATION_SUB_ABS(FIX)       \
-  (S_FORCE_RELOC ((FIX)->fx_subsy))
+#define TC_FORCE_RELOCATION_SUB_ABS(FIX)       0
 #endif
 
 #ifndef TC_FORCE_RELOCATION_SUB_LOCAL
 #ifdef DIFF_EXPR_OK
-#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX)     \
-  (S_FORCE_RELOC ((FIX)->fx_subsy))
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX)     0
 #else
-#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 1
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX)     1
 #endif
 #endif
 
@@ -376,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)
@@ -693,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.  */
@@ -825,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
@@ -870,7 +881,8 @@ adjust_reloc_syms (abfd, sec, xxx)
 
        /* Never adjust a reloc against local symbol in a merge section
           with non-zero addend.  */
-       if ((symsec->flags & SEC_MERGE) != 0 && fixp->fx_offset != 0)
+       if ((symsec->flags & SEC_MERGE) != 0
+           && (fixp->fx_offset != 0 || fixp->fx_subsy != NULL))
          continue;
 
        /* Never adjust a reloc against TLS local symbol.  */
@@ -1149,7 +1161,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);
@@ -1173,7 +1185,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"),
@@ -1207,7 +1219,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;
                }
@@ -1341,7 +1353,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
@@ -1367,7 +1379,7 @@ set_symtab ()
   else
     asympp = 0;
   result = bfd_set_symtab (stdoutput, asympp, nsyms);
-  assert (result == true);
+  assert (result);
   symbol_table_frozen = 1;
 }
 #endif
@@ -1410,7 +1422,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);
@@ -1607,7 +1637,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.025178 seconds and 4 git commands to generate.