gas/ChangeLog
[deliverable/binutils-gdb.git] / gas / write.c
index 817633589bfa9eea9daf4b218bb4dec37073792a..658765c5ca20ac8a213cb42db27c23965eac18d9 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
+   1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -61,8 +61,8 @@
 #endif
 
 #ifndef WORKING_DOT_WORD
-extern CONST int md_short_jump_size;
-extern CONST int md_long_jump_size;
+extern const int md_short_jump_size;
+extern const int md_long_jump_size;
 #endif
 
 /* Used to control final evaluation of expressions.  */
@@ -527,6 +527,7 @@ cvt_frag_to_fill (headersP, sec, fragP)
          as_bad_where (fragP->fr_file, fragP->fr_line,
                        _("attempt to .org/.space backwards? (%ld)"),
                        (long) fragP->fr_offset);
+         fragP->fr_offset = 0;
        }
       fragP->fr_type = rs_fill;
       break;
@@ -677,7 +678,14 @@ size_seg (abfd, sec, xxx)
       while (fragp->fr_next != last)
        fragp = fragp->fr_next;
       last->fr_address = size;
-      fragp->fr_offset += newsize - size;
+      if ((newsize - size) % fragp->fr_var == 0)
+       fragp->fr_offset += (newsize - size) / fragp->fr_var;
+      else
+       /* If we hit this abort, it's likely due to subsegs_finish not
+          providing sufficient alignment on the last frag, and the
+          machine dependent code using alignment frags with fr_var
+          greater than 1.  */
+       abort ();
     }
 
 #ifdef tc_frob_section
@@ -874,8 +882,16 @@ 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;
+         }
+
+       /* Never adjust a reloc against TLS local symbol.  */
+       if (symsec->flags & SEC_THREAD_LOCAL)
          {
            symbol_mark_used_in_reloc (fixp->fx_addsy);
            goto done;
@@ -1416,10 +1432,19 @@ set_segment_vma (abfd, sec, xxx)
    makes calculating their intended length trivial.  */
 
 #ifndef SUB_SEGMENT_ALIGN
+#ifdef HANDLE_ALIGN
+/* The last subsegment gets an aligment corresponding to the alignment
+   of the section.  This allows proper nop-filling at the end of
+   code-bearing sections.  */
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN)                                        \
+  (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG)    \
+   ? get_recorded_alignment (SEG) : 0)
+#else
 #ifdef BFD_ASSEMBLER
-#define SUB_SEGMENT_ALIGN(SEG) (0)
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
 #else
-#define SUB_SEGMENT_ALIGN(SEG) (2)
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
+#endif
 #endif
 #endif
 
@@ -1430,20 +1455,15 @@ subsegs_finish ()
 
   for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
     {
-      int alignment;
+      int alignment = 0;
 
       subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
 
       /* This now gets called even if we had errors.  In that case,
          any alignment is meaningless, and, moreover, will look weird
          if we are generating a listing.  */
-      alignment = had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg);
-
-      /* The last subsegment gets an aligment corresponding to the
-        alignment of the section.  This allows proper nop-filling
-        at the end of code-bearing sections.  */
-      if (!frchainP->frch_next || frchainP->frch_next->frch_seg != now_seg)
-       alignment = get_recorded_alignment (now_seg);
+      if (!had_errors ())
+       alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
 
       if (subseg_text_p (now_seg))
        frag_align_code (alignment, 0);
@@ -1506,22 +1526,18 @@ write_object_file ()
 #ifdef BFD_ASSEMBLER
   /* Remove the sections created by gas for its own purposes.  */
   {
-    asection **seclist, *sec;
+    asection **seclist;
     int i;
 
     seclist = &stdoutput->sections;
-    while (seclist && *seclist)
+    while (*seclist)
       {
-       sec = *seclist;
-       while (sec == reg_section || sec == expr_section)
+       if (*seclist == reg_section || *seclist == expr_section)
          {
-           sec = sec->next;
-           *seclist = sec;
+           bfd_section_list_remove (stdoutput, seclist);
            stdoutput->section_count--;
-           if (!sec)
-             break;
          }
-       if (*seclist)
+       else
          seclist = &(*seclist)->next;
       }
     i = 0;
@@ -2815,9 +2831,6 @@ fixup_segment (fixP, this_segment_type)
              else if (add_symbol_segment == undefined_section
 #ifdef BFD_ASSEMBLER
                       || bfd_is_com_section (add_symbol_segment)
-                      || (bfd_get_section_flags (stdoutput,
-                                                 add_symbol_segment)
-                          & SEC_MERGE) != 0
 #endif
                       )
                {
@@ -2929,7 +2942,7 @@ number_to_chars_bigendian (buf, val, n)
      valueT val;
      int n;
 {
-  if ((size_t) n > sizeof (val) || n <= 0)
+  if (n <= 0)
     abort ();
   while (n--)
     {
@@ -2944,7 +2957,7 @@ number_to_chars_littleendian (buf, val, n)
      valueT val;
      int n;
 {
-  if ((size_t) n > sizeof (val) || n <= 0)
+  if (n <= 0)
     abort ();
   while (n--)
     {
This page took 0.025913 seconds and 4 git commands to generate.