/* This module handles expression trees.
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
This file is part of the GNU Binutils.
static const struct
{
token_code_type code;
- const char * name;
+ const char *name;
}
table[] =
{
if (!seg->used
&& config.magic_demand_paged
&& (seg->value % config.maxpagesize) != 0)
- einfo (_("%P: warning: address of `%s' isn't multiple of maximum page size\n"),
+ einfo (_("%P: warning: address of `%s' "
+ "isn't multiple of maximum page size\n"),
segment_name);
seg->used = TRUE;
new_rel_from_abs (seg->value);
case LENGTH:
{
if (expld.phase != lang_first_phase_enum)
- {
- lang_memory_region_type *mem;
-
- mem = lang_memory_region_lookup (tree->name.name, FALSE);
- if (mem != NULL)
- new_number (mem->length);
- else
- einfo (_("%F%S: undefined MEMORY region `%s'"
- " referenced in expression\n"),
- tree, tree->name.name);
- }
+ {
+ lang_memory_region_type *mem;
+
+ mem = lang_memory_region_lookup (tree->name.name, FALSE);
+ if (mem != NULL)
+ new_number (mem->length);
+ else
+ einfo (_("%F%S: undefined MEMORY region `%s'"
+ " referenced in expression\n"),
+ tree, tree->name.name);
+ }
}
break;
/* Subroutine of exp_fold_tree_1 for copying a symbol type. */
static void
-try_copy_symbol_type (struct bfd_link_hash_entry * h, etree_type *src)
+try_copy_symbol_type (struct bfd_link_hash_entry *h, etree_type *src)
{
if (src->type.node_class == etree_name)
{
if (h == NULL
|| !(h->type == bfd_link_hash_new
|| h->type == bfd_link_hash_undefined
+ || h->type == bfd_link_hash_undefweak
|| h->linker_def))
{
/* Do nothing. The symbol was never referenced, or
- was defined in some object file. Undefined weak
- symbols stay undefined. */
+ was defined in some object file. Note that
+ undefweak symbols are defined by PROVIDE. This
+ is to support glibc use of __rela_iplt_start and
+ similar weak references. */
break;
}
}
h->type = bfd_link_hash_defined;
h->u.def.value = expld.result.value;
h->u.def.section = expld.result.section;
- h->linker_def = 0;
+ h->linker_def = ! tree->assign.type.lineno;
+ h->ldscript_def = 1;
if (tree->type.node_class == etree_provide)
tree->type.node_class = etree_provided;
/* Copy the symbol type if this is a simple assignment of
- one symbol to another. Also, handle the case of a foldable
+ one symbol to another. Also, handle the case of a foldable
ternary conditional with names on either side. */
if (tree->assign.src->type.node_class == etree_name)
try_copy_symbol_type (h, tree->assign.src);
exp_fold_tree_1 (tree);
}
-etree_type *
-exp_binop (int code, etree_type *lhs, etree_type *rhs)
+static void
+exp_value_fold (etree_type *tree)
{
- etree_type value, *new_e;
-
- value.type.node_code = code;
- value.type.filename = lhs->type.filename;
- value.type.lineno = lhs->type.lineno;
- value.binary.lhs = lhs;
- value.binary.rhs = rhs;
- value.type.node_class = etree_binary;
- exp_fold_tree_no_dot (&value);
+ exp_fold_tree_no_dot (tree);
if (expld.result.valid_p)
- return exp_intop (expld.result.value);
+ {
+ tree->type.node_code = INT;
+ tree->value.value = expld.result.value;
+ tree->value.str = NULL;
+ tree->type.node_class = etree_value;
+ }
+}
- new_e = (etree_type *) stat_alloc (sizeof (new_e->binary));
- memcpy (new_e, &value, sizeof (new_e->binary));
+etree_type *
+exp_binop (int code, etree_type *lhs, etree_type *rhs)
+{
+ etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->binary));
+
+ new_e->type.node_code = code;
+ new_e->type.filename = lhs->type.filename;
+ new_e->type.lineno = lhs->type.lineno;
+ new_e->binary.lhs = lhs;
+ new_e->binary.rhs = rhs;
+ new_e->type.node_class = etree_binary;
+ if (lhs->type.node_class == etree_value
+ && rhs->type.node_class == etree_value
+ && code != ALIGN_K
+ && code != DATA_SEGMENT_ALIGN
+ && code != DATA_SEGMENT_RELRO_END)
+ exp_value_fold (new_e);
return new_e;
}
etree_type *
exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
{
- etree_type value, *new_e;
-
- value.type.node_code = code;
- value.type.filename = cond->type.filename;
- value.type.lineno = cond->type.lineno;
- value.trinary.lhs = lhs;
- value.trinary.cond = cond;
- value.trinary.rhs = rhs;
- value.type.node_class = etree_trinary;
- exp_fold_tree_no_dot (&value);
- if (expld.result.valid_p)
- return exp_intop (expld.result.value);
-
- new_e = (etree_type *) stat_alloc (sizeof (new_e->trinary));
- memcpy (new_e, &value, sizeof (new_e->trinary));
+ etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->trinary));
+
+ new_e->type.node_code = code;
+ new_e->type.filename = cond->type.filename;
+ new_e->type.lineno = cond->type.lineno;
+ new_e->trinary.lhs = lhs;
+ new_e->trinary.cond = cond;
+ new_e->trinary.rhs = rhs;
+ new_e->type.node_class = etree_trinary;
+ if (cond->type.node_class == etree_value
+ && lhs->type.node_class == etree_value
+ && rhs->type.node_class == etree_value)
+ exp_value_fold (new_e);
return new_e;
}
etree_type *
exp_unop (int code, etree_type *child)
{
- etree_type value, *new_e;
-
- value.unary.type.node_code = code;
- value.unary.type.filename = child->type.filename;
- value.unary.type.lineno = child->type.lineno;
- value.unary.child = child;
- value.unary.type.node_class = etree_unary;
- exp_fold_tree_no_dot (&value);
- if (expld.result.valid_p)
- return exp_intop (expld.result.value);
-
- new_e = (etree_type *) stat_alloc (sizeof (new_e->unary));
- memcpy (new_e, &value, sizeof (new_e->unary));
+ etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->unary));
+
+ new_e->unary.type.node_code = code;
+ new_e->unary.type.filename = child->type.filename;
+ new_e->unary.type.lineno = child->type.lineno;
+ new_e->unary.child = child;
+ new_e->unary.type.node_class = etree_unary;
+ if (child->type.node_class == etree_value
+ && code != ALIGN_K
+ && code != ABSOLUTE
+ && code != NEXT
+ && code != DATA_SEGMENT_END)
+ exp_value_fold (new_e);
return new_e;
}
etree_type *
exp_nameop (int code, const char *name)
{
- etree_type value, *new_e;
-
- value.name.type.node_code = code;
- value.name.type.filename = ldlex_filename ();
- value.name.type.lineno = lineno;
- value.name.name = name;
- value.name.type.node_class = etree_name;
-
- exp_fold_tree_no_dot (&value);
- if (expld.result.valid_p)
- return exp_intop (expld.result.value);
+ etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->name));
- new_e = (etree_type *) stat_alloc (sizeof (new_e->name));
- memcpy (new_e, &value, sizeof (new_e->name));
+ new_e->name.type.node_code = code;
+ new_e->name.type.filename = ldlex_filename ();
+ new_e->name.type.lineno = lineno;
+ new_e->name.name = name;
+ new_e->name.type.node_class = etree_name;
return new_e;
}