+ fold_segment_end (&expld.dataseg);
+ break;
+
+ default:
+ FAIL ();
+ break;
+ }
+ }
+}
+
+/* Arithmetic operators, bitwise AND, bitwise OR and XOR keep the
+ section of one of their operands only when the other operand is a
+ plain number. Losing the section when operating on two symbols,
+ ie. a result of a plain number, is required for subtraction and
+ XOR. It's justifiable for the other operations on the grounds that
+ adding, multiplying etc. two section relative values does not
+ really make sense unless they are just treated as numbers.
+ The same argument could be made for many expressions involving one
+ symbol and a number. For example, "1 << x" and "100 / x" probably
+ should not be given the section of x. The trouble is that if we
+ fuss about such things the rules become complex and it is onerous
+ to document ld expression evaluation. */
+static void
+arith_result_section (const etree_value_type *lhs)
+{
+ if (expld.result.section == lhs->section)
+ {
+ if (expld.section == bfd_abs_section_ptr
+ && !config.sane_expr)
+ /* Duplicate the insanity in exp_fold_tree_1 case etree_value. */
+ expld.result.section = bfd_abs_section_ptr;
+ else
+ expld.result.section = NULL;
+ }
+}
+
+static void
+fold_segment_align (seg_align_type *seg, etree_value_type *lhs)
+{
+ seg->relro = exp_seg_relro_start;
+ if (expld.phase == lang_first_phase_enum
+ || expld.section != bfd_abs_section_ptr)
+ expld.result.valid_p = FALSE;
+ else
+ {
+ bfd_vma maxpage = lhs->value;
+ bfd_vma commonpage = expld.result.value;
+
+ expld.result.value = align_n (expld.dot, maxpage);
+ if (seg->phase == exp_seg_relro_adjust)
+ expld.result.value = seg->base;
+ else if (seg->phase == exp_seg_adjust)
+ {
+ if (commonpage < maxpage)
+ expld.result.value += ((expld.dot + commonpage - 1)
+ & (maxpage - commonpage));
+ }
+ else
+ {
+ expld.result.value += expld.dot & (maxpage - 1);
+ if (seg->phase == exp_seg_done)