+static bfd_boolean
+in_bss (void)
+{
+ flagword flags = bfd_get_section_flags (stdoutput, now_seg);
+
+ return (flags & SEC_ALLOC) && !(flags & (SEC_LOAD | SEC_HAS_CONTENTS));
+}
+
+/* Guts of .align directive:
+ N is the power of two to which to align. A value of zero is accepted but
+ ignored: the default alignment of the section will be at least this.
+ FILL may be NULL, or it may point to the bytes of the fill pattern.
+ LEN is the length of whatever FILL points to, if anything. If LEN is zero
+ but FILL is not NULL then LEN is treated as if it were one.
+ MAX is the maximum number of characters to skip when doing the alignment,
+ or 0 if there is no maximum. */
+
+void
+do_align (unsigned int n, char *fill, unsigned int len, unsigned int max)
+{
+ if (now_seg == absolute_section || in_bss ())
+ {
+ if (fill != NULL)
+ while (len-- > 0)
+ if (*fill++ != '\0')
+ {
+ if (now_seg == absolute_section)
+ as_warn (_("ignoring fill value in absolute section"));
+ else
+ as_warn (_("ignoring fill value in section `%s'"),
+ segment_name (now_seg));
+ break;
+ }
+ fill = NULL;
+ len = 0;
+ }
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+#ifdef md_do_align
+ md_do_align (n, fill, len, max, just_record_alignment);
+#endif
+
+ /* Only make a frag if we HAVE to... */
+ if ((n > OCTETS_PER_BYTE_POWER) && !need_pass_2)
+ {
+ if (fill == NULL)
+ {
+ if (subseg_text_p (now_seg))
+ frag_align_code (n, max);
+ else
+ frag_align (n, 0, max);
+ }
+ else if (len <= 1)
+ frag_align (n, *fill, max);
+ else
+ frag_align_pattern (n, fill, len, max);
+ }
+
+#ifdef md_do_align
+ just_record_alignment: ATTRIBUTE_UNUSED_LABEL
+#endif
+
+ if (n > OCTETS_PER_BYTE_POWER)
+ record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
+}
+