+ if (seg->phase == exp_seg_align_seen)
+ seg->phase = exp_seg_relro_seen;
+ }
+ else
+ expld.result.valid_p = FALSE;
+}
+
+static void
+fold_binary (etree_type *tree)
+{
+ etree_value_type lhs;
+ exp_fold_tree_1 (tree->binary.lhs);
+
+ /* The SEGMENT_START operator is special because its first
+ operand is a string, not the name of a symbol. Note that the
+ operands have been swapped, so binary.lhs is second (default)
+ operand, binary.rhs is first operand. */
+ if (expld.result.valid_p && tree->type.node_code == SEGMENT_START)
+ {
+ bfd_vma value = expld.result.value;
+ const char *segment_name;
+ segment_type *seg;
+
+ /* Check to see if the user has overridden the default
+ value. */
+ segment_name = tree->binary.rhs->name.name;
+ for (seg = segments; seg; seg = seg->next)
+ if (strcmp (seg->name, segment_name) == 0)
+ {
+ if (!seg->used
+ && config.magic_demand_paged
+ && config.maxpagesize != 0
+ && (seg->value % config.maxpagesize) != 0)
+ einfo (_("%P: warning: address of `%s' "
+ "isn't multiple of maximum page size\n"),
+ segment_name);
+ seg->used = TRUE;
+ value = seg->value;
+ break;
+ }
+ new_rel_from_abs (value);
+ return;
+ }
+
+ lhs = expld.result;
+ exp_fold_tree_1 (tree->binary.rhs);
+ expld.result.valid_p &= lhs.valid_p;
+
+ if (expld.result.valid_p)
+ {
+ if (lhs.section != expld.result.section)
+ {
+ /* If the values are from different sections, and neither is
+ just a number, make both the source arguments absolute. */
+ if (expld.result.section != NULL
+ && lhs.section != NULL)
+ {
+ make_abs ();
+ lhs.value += lhs.section->vma;
+ lhs.section = bfd_abs_section_ptr;
+ }
+
+ /* If the rhs is just a number, keep the lhs section. */
+ else if (expld.result.section == NULL)
+ {
+ expld.result.section = lhs.section;
+ /* Make this NULL so that we know one of the operands
+ was just a number, for later tests. */
+ lhs.section = NULL;