Alan Modra <amodra@bigpond.net.au>
[deliverable/binutils-gdb.git] / gas / write.c
index 17c323209fe52ac8d61439ab84701540384b96a1..14e23fbc2f3fcab523c7737be60f7c9c157fc22a 100644 (file)
 #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
 
@@ -111,6 +109,9 @@ int symbol_table_frozen;
 
 symbolS *abs_section_sym;
 
+/* Remember the value of dot when parsing expressions.  */
+addressT dot_value;
+
 void print_fixup PARAMS ((fixS *));
 
 #ifdef BFD_ASSEMBLER
@@ -184,9 +185,6 @@ static void cvt_frag_to_fill PARAMS ((object_headers *, segT, fragS *));
 static void remove_subsegs PARAMS ((frchainS *, int, fragS **, fragS **));
 static void relax_and_size_all_segments PARAMS ((void));
 #endif
-#if defined (BFD_ASSEMBLER) && defined (OBJ_COFF) && defined (TE_GO32)
-static void set_segment_vma PARAMS ((bfd *, asection *, PTR));
-#endif
 
 /* Create a fixS in obstack 'notes'.  */
 
@@ -220,6 +218,7 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
   fixP->fx_addsy = add_symbol;
   fixP->fx_subsy = sub_symbol;
   fixP->fx_offset = offset;
+  fixP->fx_dot_value = dot_value;
   fixP->fx_pcrel = pcrel;
   fixP->fx_plt = 0;
 #if defined(NEED_FX_R_TYPE) || defined (BFD_ASSEMBLER)
@@ -692,11 +691,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.  */
@@ -869,7 +868,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.  */
@@ -1148,7 +1148,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 +1172,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 +1206,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 +1340,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,25 +1366,11 @@ set_symtab ()
   else
     asympp = 0;
   result = bfd_set_symtab (stdoutput, asympp, nsyms);
-  assert (result == true);
+  assert (result);
   symbol_table_frozen = 1;
 }
 #endif
 
-#if defined (BFD_ASSEMBLER) && defined (OBJ_COFF) && defined (TE_GO32)
-static void
-set_segment_vma (abfd, sec, xxx)
-     bfd *abfd;
-     asection *sec;
-     PTR xxx ATTRIBUTE_UNUSED;
-{
-  static bfd_vma addr = 0;
-
-  bfd_set_section_vma (abfd, sec, addr);
-  addr += bfd_section_size (abfd, sec);
-}
-#endif /* BFD_ASSEMBLER && OBJ_COFF && !TE_PE  */
-
 /* Finish the subsegments.  After every sub-segment, we fake an
    ".align ...".  This conforms to BSD4.2 brane-damage.  We then fake
    ".fill 0" because that is the kind of frag that requires least
@@ -1423,7 +1409,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);
@@ -1569,14 +1573,6 @@ write_object_file ()
   /* 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
-     should too. Currently, only DJGPP uses this code, but other
-     COFF targets may need to execute this too.  */
-  bfd_map_over_sections (stdoutput, set_segment_vma, (char *) 0);
-#endif
-
 #ifndef BFD_ASSEMBLER
   /* Crawl the symbol chain.
 
@@ -2656,7 +2652,8 @@ fixup_segment (fixP, this_segment)
                   && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP))
            {
              add_number -= S_GET_VALUE (fixP->fx_subsy);
-             fixP->fx_offset = add_number;
+             fixP->fx_offset = (add_number + fixP->fx_dot_value
+                                + fixP->fx_frag->fr_address);
 
              /* Make it pc-relative.  If the back-end code has not
                 selected a pc-relative reloc, cancel the adjustment
This page took 0.025732 seconds and 4 git commands to generate.